#clojure logs

2015-02-15

00:23yogthosrobindunbarr: Luminus is meant to be a light weight batteries included micro-framework like Flask
00:29robindunbarryogthos: I see, thanks.
00:41devllHi,Is there a way to get string value of the stacktrace of a Exception?
00:41devllObviously,I can write one .
00:42devllI guess I just should do it.
01:08justin_smith,(apply str (.getStackTrace (Exception. "oops")))
01:08clojurebot"sandbox$eval25.invoke(NO_SOURCE_FILE:0)clojure.lang.Compiler.eval(Compiler.java:6768)clojure.lang.Compiler.eval(Compiler.java:6731)clojure.core$eval.invoke(core.clj:3076)clojure.core$eval3$fn__4$fn__14.invoke(NO_SOURCE_FILE:0)clojure.core$eval3$fn__4.invoke(NO_SOURCE_FILE:0)clojure.core$eval3.invoke(NO_SOURCE_FILE:0)clojure.lang.Compiler.eval(Compiler.java:6768)clojure.lang.Compiler.eval(Compiler...
01:09devlljustin_smith: thanks
01:37vasanybody do passwordless logins for their app?
01:49vasping
01:52justin_smithvas: no, how would that work?
01:59vasjustin_smith: been contemplating various approaches, but i think the one i want to use is essentially asking the user just for their email, then sending them a link that they click
01:59vasso the only password they need is their email password, not truly "passwordless" but no passwords kept on my end
02:00vas( and the link is their authentication for the session )
02:00justin_smithahh, right - instead you have a mapping of an account (and account data) to a token validated via email?
02:01vasprecisely so
02:01vasor text message, i might use phone numbers eventually
04:34kaplanHi, can anyone tell me what's wrong with this code? https://www.refheap.com/97252
04:36AimHere,(reverse "acca")
04:36clojurebot(\a \c \c \a)
04:36wminorkaplan: I think you're using the wrong reverse, you need clojure.string/reverse
04:36kaplanah
04:37AimHereThe 'if' is redundant too
04:37AimHere(if X true false) can be easily reduced to (X)
04:38kaplanah, thanks
04:38kaplanwminor, that worked
04:38AimHere(if (if X true false) true false)
04:41kaplanwminor, is there any way to shorten the clojure.string part?
04:41TEttinger,(require [clojure.string :as s])
04:42clojurebot#<CompilerException java.lang.ClassNotFoundException: clojure.string, compiling:(NO_SOURCE_PATH:0:0)>
04:42AimHereYou can give it an alias in the require'
04:42TEttinger,(require '[clojure.string :as s])
04:42clojurebotnil
04:42TEttinger,(s/reverse "blah")
04:42clojurebot"halb"
04:43TEttingerkaplan: typically require goes in the ns form, where it looks like (ns mynamespace (:require [clojure.string :as s]))
04:43TEttingernote the colon and the no need for a quote
04:44TEttingerin the repl, or in the middle of a clojure source file, you can use (require '[whatever]) and need the quote but can't have the colon before require
04:45wminorI'm writing an HTTP client for something, and I have a bunch of functions that work in the success case, returning maps representing the json data in the body of the responses. However, I'm having a tough time deciding how to handle errors. What's the idiomatic way to handle failure of the HTTP request in the way that a caller can be informed of the reason for failure?
04:46TEttingerthere's also (use) but it is frowned upon, especially for clojure.string. use overwrites any functions or vars that are currently defined with the ones in the ns it uses, so you don't need the s/reverse and can just do reverse. BUT you just overwrote clojure.core/reverse
04:46kaplanTEttinger, ah, thanks
04:47TEttingerwminor, that's a really good question, and I am not qualified at all to answer
04:48wminorSadly, searches for error handling in clojure bring up a really mixed bag, and I've not seen an approach that sticks out as being either particularly nice, or "the clojure way"
04:51ggherdovHello. I'm trying to understand commute vs alter. My book (progr. cloj., oreilly) says about commute that "the commute-d function will be applied again at commit time with the latest value for the commute-d ref".
04:51ggherdovI don't understand. Wouldn't this second application of the function need to be in a transaction as well? I mean: the second application of the function may take some time; at the point you have the result, the original ref value might have changed -again-...
04:53ddellacostawminor: if you are just talking about HTTP error responses, seems like that could/should be handled simply by passing the error response back to the client, and handling it as is appropriate there, no? If you are talking about general error handling in the Clojure ecosystem, I'd have to agree with you there
04:54wminorddellacosta: sure, I could just bubble up errors to the caller, but it feels like there should be a better way
04:54ddellacostawminor: you may also want to take a look at liberator, may or may not answer some of your questions: http://clojure-liberator.github.io/liberator/
04:55wminorwill take a peek, thanks
04:56ddellacostawminor: again, I'm a bit confused about what you are talking about--if you are talking about HTTP responses then I think that should be app-specific. If you are talking about errors/exceptions on the app level that have to be handled in some app-specific way, then that is definitely not something I've seen codified in any way in the Clojure world
04:57ddellacostawminor: for example, are you talking about, say, the user passing invalid data to an HTTP route, or the database blowing up because it's out of connections (for example)?
05:06faveteli_what am i missing in this simple infix macro? http://lpaste.net/120533
05:08kaplanTEttinger, https://www.refheap.com/97253 LightTable instarepl gives me EOF on line 7
05:08faveteli_i found the problem need to unquote :)
05:08TEttingerneed another paren just before line 7, kaplan
05:09TEttingerneed to end palindrome? fn
05:09kaplanTEttinger, ah, damn parens
05:10TEttingerheh
05:10TEttingerit will get easier!
05:10TEttingeralso lighttable supports rainbow parens
05:10TEttingerwhich are so nice, in my view, not everyone likes em
05:11kaplanTEttinger, I thought I should make my brain used to parens without any aid first
05:11TEttingeryeah, I think you will get used to them though, it doesn't take that long
05:13wminor ddellacosta: the former I suppose. I think for now I'm happy for the client to explode in exceptional circumstances
05:14ddellacostawminor: in that case, another thing you could take a look at is Prismatic's fnhouse (https://github.com/Prismatic/fnhouse)--we use something different ourselves, but it's worth seeing how much this solves your problem or misses the mark
05:15ddellacostawminor: but in general I like the direction the Prismatic folks are going in with most of their libraries
05:16wminorddellacosta: thanks. At this point I'm still very new to clojure, so just happy to find find decent code to read so that I can soak up ideas. I don't yet know enough to evaluate third party code easily
05:17ddellacostawminor: gotcha. Yeah, in general I'd recommend checking out their stuff, I think their libraries represent some of the higher quality and more thoughtfully practical stuff available now in Clojure
05:50IntegralistHello, I'm having an issue with a namespace when the app is compiled and/or at runtime: http://goo.gl/At2Jbp -> I've just to use ns-resolve to work around the issue but am still having no luck.
05:54nicferrierso I've got two webservers in a single process... they use a lot of core.async... how should I wait on the core.async operations? with a while loop with a thread/sleep?
05:59muhuknicferrier: you mean wait and block everything else?
05:59nicferriermuhuk: I mean the go blocks are all async... so if I set them up and do nothing else the program will just quit, no? so I have to wait for them somehow.
05:59nicferrieror do I? maybe the main will just hang?
06:00muhuknicferrier: I see what you mean.
06:00nicferrierI want to get this right. this is a piece of infrastructure.
06:00muhukI usually set up something like a promise and wait on that
06:00muhukthen you can deliver that promise anywhere else and you should be able to exit that way.
06:00nicferrierah. not a bad idea.
06:00nicferrierI could have a signal to the go block to fulfil the promise.
06:18ggherdovCan anybody clarify this statement: "The function you give to `commute` will be run at least twice: once to compute the in-transaction value, and again to compute the commit value". It's from "the joy of clojure".
06:18ggherdovMy question is: why do you bother computing the in-transaction value, if then you're going to do it all over again at commit time?
06:43muhukggherdov: have you seen the example here https://clojuredocs.org/clojure.core/commute
06:48ggherdov@muhuk no I haven't, thanks. Reading.
07:54nicferrierdoesn't waiting on a promise block the thread? it does right? I'm getting some wierd error about many2many-channels and futures being confused.
07:55nicferrieraha. it's not that. I'm confusing a thread and a promise.
07:55nicferrierhow do I exchange a promise between two threads?
07:56nicferrierI want the promise to be delivered in another thread.
07:56nicferriercan I return the promise from a thread?
08:34nicferriergah. now I am stuck trying to end my threads.
08:34nicferrier:-(
08:34nicferrierclojure is great but concurrency is hard.
08:34muhukconcurrency is hard, period.
08:34muhukwhy do you need to exchange the promise between threads
08:35nicferrierI solved that.
08:35nicferrier:-)
08:35muhukok, cool
08:37nicferrierI've got a few threads which are sockets and clients... and now they don't end.
08:37nicferriersort of trying to make this usable.
08:38AeroNotixnicferrier: stop trying to use 12 different concurrency primitives in the same program.
08:38nicferrierbut I need them.
08:38AeroNotixYou think you need them :)
08:38nicferrieryou think I don't know but you don't know what I'm doing.
08:39AeroNotixI know you think you know what you're doing. You always seem to try to mention your many-years experience whenever you're learning something on IRC.
08:39nicferrierbecause I'm not seeking a mentor.
08:39AeroNotixBut really, there is probably an easier way than using threads, promises and core.async all at the same time.
08:40AeroNotixI say "probably" because there might be a genuine need.
08:40nicferrieryeah.
08:40AeroNotixhaha!
08:40AeroNotixgo for it dude, knock yourself out.
08:40nicferrieryou want to know what I'm doing?
08:40AeroNotixNope.
08:40nicferrieryou're friendly.
08:41AeroNotixI am, really.
08:41nicferriernot really.
08:41AeroNotixbut it's clear you don't want help.
08:41nicferrierthat's right. I'm just chatting.
08:41nicferrierchatting helps.
08:41vas_hehehe a gem of a back-n-forth
08:41nicferrierI use irc for rubber ducking.
08:46nicferrierjust so you know - that's not friendly and it pisses me off.
08:46nicferriermakes me feel unwelcome.
08:46nicferrierhope you don't do it a lot.
08:46AeroNotixnicferrier: thing is, you are exactly like that yourself.
08:46AeroNotix#emacs is tyranny when you're active.
08:47nicferrierthat's not true.
08:47AeroNotixAh! So I'm mistaken.
08:47AeroNotixoh wait.
08:50muhukJust because someone is rude (or whatever) in another channel doesn't mean we should make belittling comments about them in #clojure.
08:51AeroNotixIt wasn't belittling. nicferrier made it clear they're just here to complain, not ask for help. Even when nudged in the direction that they might be doing something wrong, the first assertion is that they *need* to do it like that.
08:51AeroNotixWhich is funny, because the previous conversation makes it clear that nicferrier is confused about several primitives.
08:51nicferrierAeroNotix: no, but you can't throw bricks at someone without hearing what they're trying to do.
08:51nicferrierand I don't think I'm confused.
08:52AeroNotixGotcha.
08:52muhukImplying that he doesn't know what he's doing is belittling.
08:52nicferrierand so is passive aggresive behaviour.
08:52AeroNotixI implied there might be a better way to do it.
08:52Bronsaplease, take this somewhere else and don't pollute #clojure with personal issues.
08:52AeroNotixBronsa: agreed. It's gone too far now.
08:57vas_hi :) i want to timestamp stuff
08:57AeroNotixvas_: what do you mean?
08:57AeroNotixlike generate timestamps?
08:57vas_just like unix standard count for tokens i put in a db
08:57vas_to check that they're <33min fresh
08:58AeroNotixvas_: you can get the unix timestamp by doing (quot (System/currentTimeMillis) 1000)
08:58AeroNotixand then it's simple maths to do the comparison
08:58vas_Wow that's awesome. Thanks for the swift answer AeroNotix
08:58AeroNotixnp
09:00AeroNotixwhat's the best guide to getting started with ClojureScript? I know there were a lot of tooling changes recently and I haven't kept up.
09:14vas_AeroNotix: works like a charm, thank you kindly ^_^
09:14AeroNotixno worries
09:37cityspiritin the enqueue macro here http://www.braveclojure.com/concurrency/#4_5__Simple_Queueing, why doesn't (deref ~q) block the main thread, prohibiting further calls to enqueue itself?
09:38cityspiritactually, i guess I would rather think the call to ~serialized would be blocking the main thread
09:42vas_because "Dereferencing a future will block if the future hasn't finished running" ?
09:47cityspirithow does the call to enqueue return a promise to the next call to enqueue without first being block by ~serialized, which is dereferencing a promise
10:05nonrecursivecityspirit: this might help https://gist.github.com/flyingmachine/ba9ae6e500896b1d2c78
10:06nonrecursivethat’s not 100% exactly what happens but it should show that all the futures get created before any of the futures get dereferences
10:06nonrecursivedereferenced*
10:10mavbozononrecursive: so, if the future is not yet finished, (deref ~q) will block the main thread
10:11nonrecursivecityspirit: sometimes it does get blocked but that’s actually ok
10:15nonrecursivemavbozo: cityspirit: yeah, but that’s ok. Maybe a dumb metaphor will help? Let’s say some unpleasant person has lined up three balls on a table. he wants each ball to get thrown into the air, caught, and then handed to him in the order that they’re lined up. You could go down, one by one, tossing each ball and handing it to this person. Or you could get two of your friends to toss the balls at the same time as you, and you
10:15nonrecursivehand in each ball, in order, as soon as it’s done being tossed
10:16nonrecursivein the first case, let’s say the balls take 1 second, 3 seconds, and 2 seconds. It’ll take you a total of 6 seconds
10:16nonrecursivein the second case, you can hand in ball one after 1 second, then you have to wait 2 more seconds to hand in ball 2. but you can hand in ball 3 immediately
10:17justin_smith$mail nicferrier what you want is shutdown-agents when your app is ready to shut down, clojure's main thread will not end until the agent-pools are nicely put to bed
10:17lazybotMessage saved.
10:17nonrecursiveenqueue is acting like the second case - the thread does sometimes have to wait, but the task as a whole will only take as long as the longest sub-task
10:18nonrecursivemavbozy: cityspirit: does that help at all?
10:19cityspiritnonrecursive: thanks, for the example and description. the description makes sense, I'm still looking at example. I guess my problem comes with understanding how the macro behaves differently than , e.g. https://www.refheap.com/97267 By the way, I really enjoy your writing style
10:19mavbozononrecursive: that helps. thx.
10:23nonrecursivecityspirit: in that example you deref the first promise before creating the second promise and future. with enqueue, you create all promises and futures before any of the promises actually get dereferenced
10:25favetelinguisis the clojure cheat sheet a complete discription of the Clojure language?
10:25justin_smithnot at all
10:26gfredericks~the clojure cheat sheet is not a complete description of the Clojure language
10:26clojurebotAck. Ack.
10:26nonrecursivecityspirit: line 3 and 5 of the gist I linked show a let expression getting deref’d, but those don’t actually have to block until the promise at line 8 is encountered. in the mean time, the futures at lines 2, 4, and 6 have already been created, so that work is done concurrently
10:27favetelinguisis there something with the same layout that shows the omplete set of functionallity?
10:27nonrecursivecityspirit: also, thanks! :D
10:29justin_smithfavetelinguis: you could look at the ns-publics of clojure.core and the other core libs, and read doc strings or look them up
10:29justin_smith,(ns-publics 'clojure.core)
10:29clojurebot{primitives-classnames #'clojure.core/primitives-classnames, +' #'clojure.core/+', decimal? #'clojure.core/decimal?, restart-agent #'clojure.core/restart-agent, sort-by #'clojure.core/sort-by, ...}
10:30gfredericks,primitives-classnames
10:30clojurebot{float "Float/TYPE", int "Integer/TYPE", long "Long/TYPE", boolean "Boolean/TYPE", char "Character/TYPE", ...}
10:30justin_smithhow handy
10:30gfredericksthat's my thing-in-clojure-core-I-never-knew-existed-of-the-day
10:31justin_smith,(rand-nth (keys (ns-publics 'clojure.core))) ; random clojure def of the day
10:31clojurebotproxy
10:32gfredericksclj-http defines a custom map type for headers and it doesn't take metadata o_o
10:32cityspiritnonrecursive: ahh ok it makes sense - thanks a lot for the responses!
10:32nonrecursivecityspirit: no problem :)
10:34tcrayford____gfredericks: I'm sure it saves a bunch of pointers in practice
10:34tcrayford____(seems like an awful idea too me)
10:35adgtlI am tyring to paste following json string in clojure repl
10:35adgtl(json/read-str "{"recenttracks":{"track":[{"name":"Loading...","artist":{"#text":""}}]}}")
10:35adgtlbut it fails
10:36adgtlthis also fails (json/read-str '{"recenttracks":{"track":[{"name":"Loading...","artist":{"#text":""}}]}}')
10:36justin_smithadgtl: neither of those is string syntax
10:36adgtlAnyone know how to parse json string
10:36gfrederickstcrayford____: which idea is awful?
10:36tcrayford____gfredericks: though some of yeller's benchmarks rn spend a significant amount of time in clojure.core/meta (and the calling path from that just leads to `conj`)
10:36justin_smithadgtl: you mean how to provide a literal? "{\"recenttracks\":{\"track\"...
10:36tcrayford____defining a custom map without meta
10:37adgtljustin_smith: I have that string.. I don't want to add \
10:37adgtlbasically is there any string sanitizer?
10:37justin_smithadgtl: sorry, that's the only way to make the valid clojure string literal
10:37gfrederickstcrayford____: I think the point of the custom map was to make it case-insensitive; probably the lacking-of-metadata was just an oversight
10:37justin_smithadgtl: unless you use emacs, or another editor that can quote it for your
10:37adgtlisn't there any helper to do that?
10:37justin_smith*you
10:37justin_smithno
10:37tcrayford____oh case insensitive maps gosh darnit
10:37adgtljustin_smith: I use emacs.. how to make it quote?
10:37justin_smiththe helper would need to get the string to work on it
10:37tcrayford____next thing clojure will get HashWithIndifferentAccess
10:37justin_smithwhat you have is not a string
10:38adgtljustin_smith: it's string containing json
10:38clojurebotNo entiendo
10:38gfrederickstcrayford____: hey at least it's not in the language
10:38tcrayford____haha
10:38tcrayford____HashWithIndifferentAccess is in rails
10:38tcrayford____so it's in the language ;)
10:38justin_smithadgtl: there is a tool called string-edit that has a function string-edit-at-point
10:39justin_smithyou can insert a string into the string-edit buffer and it gets escaped properly
10:39adgtljustin_smith: in emacs?
10:39justin_smithyes
10:39justin_smithyou need to require the string-edit package first
10:39gfrederickstcrayford____: ruby is the microkernal of the general purpose programming language "rails"
10:39AeroNotixparedit quotes literal strings with quotes as well.
10:39justin_smithadgtl: the other option is to put the json in a file, and slurp it
10:39adgtljustin_smith: can't do that
10:40justin_smithadgtl: optionally, you could also call (pr-str (slurp "file.json"))
10:40justin_smithand that also gives you the escaped string
10:41justin_smithadgtl: you can'
10:41justin_smitht install string-edit?
10:42zapho53Is there a way of doing something like this (which doesn't work): (apply Integer/parseInt [day month year hour min]) ?
10:42justin_smithzapho53: methods are not first class
10:42justin_smith#(Integer/parseInt %) will work
10:42adgtlhmm
10:42adgtluser=> (def c (json/read-str (pr-str (slurp "seed.json"))))
10:42adgtl#'user/c
10:43adgtluser=> c
10:43adgtl"{\"recenttracks\":{\"track\":[{\"name\":\"Loading...\",\"artist\":{\"#text\":\"\"}}]}}\n"
10:43adgtlthat's totally wrong
10:43justin_smithno, that's correct
10:43justin_smiththat's exactly what it should look like as a valid clojure string
10:43adgtlI want to convert it to clojure map
10:43justin_smithit's properly escaped
10:43justin_smithOK, then parse it!
10:43justin_smithbut now you have the string you can parse
10:43adgtlSeee what I am doing json/read-str
10:43adgtlit should parse it too
10:43justin_smithno you aren't
10:43justin_smithoh...
10:43justin_smiththat's weird
10:44justin_smithclojure.data.json?
10:44rufoayou don't need pr-str
10:44rufoajust slurp right into read-str
10:44zapho53justin_smith: OK, thanks.
10:44rufoacos its a string
10:44justin_smithrufoa: I was suggesting pr-str if he wanted to print the valid escaping
10:44rufoayeah. but now he wants to parse it
10:44rufoaso get rid
10:44AeroNotixhe?
10:44rufoa*she?
10:44justin_smithadgtl: rufoa is right, just take out the pr-str if you want to parse straight away, and that will work
10:45justin_smithadgtl: I only suggested pr-str if you wanted to get the escaped version (it would print it)
10:46adgtljustin_smith: this did the trick (def n (json/read-str (json/read-str (pr-str (slurp "seed.json")))))
10:47rufoathat relies on a dodgy assumption about the similarity of clojure map and json map representations
10:47rufoadon't do it
10:47rufoa (def n (json/read-str (slurp "seed.json")))
10:47justin_smithadgtl: well, that would do it too, it's also a bit silly
10:48AeroNotixA link to clojure.data.json would've solved this ten minutes ago
10:48rufoa^
10:48AeroNotixadgtl: https://github.com/clojure/data.json
10:48justin_smithAeroNotix: he is using data.json
10:48AeroNotixread that, come back if you have problems.
10:48justin_smithAeroNotix: the issue is the json literal properly quoted
10:48justin_smithAeroNotix: which was solved with putting it in a file, and slurp
10:49AeroNotixreading the docs always helps
10:49adgtlrufoa: thanks
10:49adgtlcorrrected
10:51adgtldoing this now
10:51adgtl(get (get (json/read-str (slurp "seed.json")) "recenttracks") "track")
10:51adgtltwo get to just get array back
10:51rufoacheck out get-in
10:51rufoain core
10:51justin_smithadgtl: (get-in (json/read-str (slurp "seed.json")) ["recenttracks" "track"])
10:52adgtljustin_smith: smooth
10:52AeroNotixI'm really surprised more APIs don't expose a `get-in`-like function by default
10:52AeroNotixbecause it's so useful
10:53tcrayford____AeroNotix: got some other examples you want a thing like get-in for?
10:53tcrayford____apart from update-in/assoc-in
10:53AeroNotixtcrayford____: other languages
10:53justin_smithAeroNotix: inorite - when I first came to clojure, I had been working on a guile lib to work with json, and I was like "wait, get-in is what I wanted all along"
10:53AeroNotixjustin_smith: exactly :)
10:53tcrayford____oh haha
10:54AeroNotixbut for clojure-specific stuff, I think I'm missing dissoc-in
10:54AeroNotixor dissoc-if
11:19gfredericksdissoc-if-not-contains?-meta
11:19gfredericksdissoc-if-not-contains?-meta-in
11:19rufoahaha
11:19rufoais there a macro version of that
11:22AeroNotixDo people use meta a lot? I don't seem to use it all that much
11:22gfredericksprobably not; it's a weird feature but sometimes useful
11:23gfredericksconfession: I used it this morning: https://github.com/gfredericks/test.chuck/issues/5
11:25michaelr`hi
11:30michaelr`I'm writing an application with ClojureScript and Om. I'd like to allow users to deep link into the application screens and then share urls. Such as the following app.com/#/factory/workers/1. The thing here is that when a users gets to this specific page, the application must load not only the data for this specific page, but also all of it's other state - such as to load the "factory" and then to load the "worker".
11:31michaelr`Now I'm asking how to architecture for such feature, so as not to make a sphaghetti off of it. :)
11:31justin_smithmichaelr`: perhaps make a tree that describes the feature dependencies, and a function that can load the code needed for the features?
11:31justin_smithmichaelr`: almost sounds like component when I put it that way...
11:32michaelr`justin_smith: it's less about code, more about state.
11:33michaelr`justin_smith: that is the application needs to be brought to a certain state such as if the user has been using it and navigating to this specific screen from the main screen.
11:34michaelr`justin_smith: here, he navigates directly to the sub screen...
11:34justin_smithmichaelr`: component is about state
11:35justin_smithI did say "feature" rather than "state" - because big picture what matters is the functionality, and state or not is an implementation detail of that
11:37justin_smithregardless, what you need is a way to describe the set of features you need, and then something that can take that discription and build up the state / bindings needed to make those features
11:38piranhawhat could be wrong if compojure doesn't return Content-Type when I serve resources (with `(route/resources "/")`)?
11:39justin_smithpiranha: so the response to the client has no Content-Type in the headers?
11:39piranhajustin_smith: yep
11:39justin_smithwhat kind of file is it?
11:39mavbozopiranha: have you put content-type middleware?
11:39michaelr`justin_smith: ok thanks
11:39piranhamavbozo: hm, no, should I?
11:40piranhaI've been looking at compojure sources and it looks like it should still work: https://github.com/weavejester/compojure/blob/master/src/compojure/route.clj#L38
11:40piranhajustin_smith: css file, for example
11:40justin_smithmichaelr`: something that often happens is that the logic for creating the proper state and bindings is interleaved with the UI workflow
11:40justin_smithmichaelr`: which can totally work until you want parts of the UI to be directly accessible
11:41justin_smithmichaelr`: at which point the building of state and bindings needs to be decoupled from UI - so your UI code will likely need to be changed to call the generic "build state and bindings if needed" code
11:42justin_smithpiranha: there is a wrap-content-type handler that could help you
11:42justin_smithpiranha: but I thought that was in by default
11:42piranhayeah, found it, thanks
11:42piranhabut looking at compojure's code it should've been done already for me :\
11:43piranhaanyway, this one should work
11:43piranhayep, it helped
11:44piranhadamn
11:44piranha%)
11:44piranhajustin_smith: except curl -I http://localhost:3000/ now returns application/octet-stream :-)
11:45justin_smithpiranha: well, you will need to manually add a content-type header if the file-type can't be inferred I think
11:45piranha(GET "/" [] (resp/resource-response "index.html")) - how do I add content type here?
11:46justin_smithpiranha: {:headers {:content-type "text/html"} :body (resp/resource-response "index.html") :status 200}
11:46piranhathanks!
11:46justin_smiththat's if resource-response returns the text of the page
11:46justin_smithand not a map
11:47michaelr`justin_smith: can you maybe point at a source code anywhere which works like you described?
11:50justin_smithmichaelr`: a very common, simple example would be the typical "login required" workflow. Instead of having a landing page that you always hit after login, you have a login that intercepts unauthorized access, and after login it sends you back to the resource you initially asked for
11:52justin_smithother usages of that pattern will add a more complex map of required features, but have a similar logic - you have a "desired destination" and you have the code that figures out what needs to be built up (load profile from the db? authenticate? load some resource representing your saved session?)
11:54michaelr`justin_smith: ok, thanks :)
12:03michaelr`justin_smith: i need to make some more thinking.. actually, I might be overthinking it as the current requirements only define one resource that needs to be deep linked within the application, and even then no constraints are set on how the URL should look like. So I'd have to weight seriously on whether there would be a real plus to architecting the whole application for deep linking. Of course that would be really neat, but I'm not
12:03michaelr`sure it's a real feature the client needs and wants to pay for :)
12:03justin_smithmichaelr`: maybe a part of the URL could encode the source of the resource you need?
12:03justin_smithwell anything beyond what would be specific to a user profile of course
12:04cddrI'm trying to add some debugging operations to cider-nrepl but am having a hard time making the tools.jar available to the middlware I'm adding
12:04justin_smithcddr: the jvm tools.jar?
12:04cddryes
12:04justin_smithwith some vms it needs to be explicitly added to your classpath
12:05justin_smithit's a 1.7 change iirc?
12:05cddroh
12:05justin_smithcddr: and you need the jdk for tools.jar - jre works for most clojure stuff, but you need jdk for that one jar
12:06cddrok, yeah I do have the jdk
12:07cddrCan a leiningen plugin be dependent on another plugin?
12:08justin_smithyeah, but it should specify it as a normal dep
12:08justin_smithsince the other plugin should be available at its runtime
12:08cddrah, right maybe that's what I was missing
12:08cddrI was using lein-jdk-tools but it wasn't working
12:08kaplancan anyone explain macros in a simple way to me?
12:08cddrBut didn't have it in the deps
12:08justin_smithkaplan: they return the list representing the code that will eventually run
12:09justin_smith,(defmacro two [] (list '+ 1 2))
12:09clojurebot#'sandbox/two
12:09justin_smith,(two)
12:09clojurebot3
12:09justin_smithhaha
12:09justin_smithI made a mistake, but I hope it's still clear what that did
12:09justin_smithkaplan: the place where it gets interesting, is you can use the full power of the clojure language to construct that list
12:10kaplanhmmn, not clear
12:10justin_smithand we have tools like ` (aka syntax-quote) and ~ / ~@ (unquote / unquote splicing) that make writing macros much easier
12:10justin_smith,(list '+ 1 1)
12:10clojurebot(+ 1 1)
12:10justin_smiththat returns a list
12:10justin_smithwhich also happens to be valid clojuer code
12:10justin_smith*clojure
12:11justin_smith,(defn two-f [] (list '+ 1 1))
12:11clojurebot#'sandbox/two-f
12:11justin_smiththat's a function
12:11justin_smith,(defmacro two-m [] (list '+ 1 1))
12:11clojurebot#'sandbox/two-m
12:11justin_smiththat's a macro
12:11justin_smith,(two-f)
12:11clojurebot(+ 1 1)
12:11justin_smith,(two-m)
12:11clojurebot2
12:11justin_smithnote that they contain the same thing
12:11justin_smithbut because one is a macro, its result gets evaluated, as if I had typed that in
12:12kaplanahh
12:12smt-justin_smith: that was very good
12:12justin_smithsmt-: thanks :)
12:12kaplanWhat do ` ~ and ~@ do
12:12justin_smithkaplan: so you can write code that constructs the code that needs to be run. This is often for developer convenience, making prettier syntaxes.
12:12justin_smith,`(+ 1 1)
12:12clojurebot(clojure.core/+ 1 1)
12:13justin_smithso first off, ` resolves things to their bindings
12:13justin_smith+ becomes clojure.core/+
12:13justin_smith(def num 42)
12:13justin_smith,(def num 42)
12:13clojurebot#<CompilerException java.lang.SecurityException: denied, compiling:(NO_SOURCE_PATH:0:0)>
12:13justin_smithhrmph
12:13justin_smith,(defn num [] 42)
12:13clojurebot#<CompilerException java.lang.SecurityException: denied, compiling:(NO_SOURCE_PATH:0:0)>
12:13justin_smithoh, it's the name
12:13justin_smith,(def num- 42)
12:13clojurebot#'sandbox/num-
12:14justin_smith,`(+ num- 1)
12:14clojurebot(clojure.core/+ sandbox/num- 1)
12:14justin_smithso that resolved the var
12:14justin_smith,`(+ ~num- 1)
12:14clojurebot(clojure.core/+ 42 1)
12:14justin_smiththat "unquoted" the var
12:15justin_smith,`(+ ~@[num- 100 10001] 1)
12:15clojurebot(clojure.core/+ 42 100 10001 1)
12:15justin_smithand that unquoted, splicing
12:15justin_smithso these are all tools for deciding when things should be "unquoted" (evaluated sooner rather than later) and splicing rather than inserting
12:16justin_smith,`(+ ~[num- 100 10001] 1) ; without splicing
12:16clojurebot(clojure.core/+ [42 100 10001] 1)
12:17justin_smithkaplan: basic idea is that ` / ~ / ~@ can make macro definition much easier
12:19mavbozopiranha: i just tried using compojure-app leiningen template and (compojure.route/resource "/") just works and sending the Content-Type
12:19piranha:(
12:19mavbozopiranha: do you also use `lein new compojure-app ...`?
12:19piranhamavbozo: I was doing exactly the same... anyway, wrote a bit of custom code, and it works
12:19piranhanope, not even close :)
12:19piranhaI had to put compojure inside of an existing system
12:20mavbozopiranha: so, you use (with `(route/resources "/")`) . that's new to me
12:21piranhathe "(with" part was just my words, not clojure's code :)
12:28gfredericksnone of these routing libs seem to think it might be useful to know what route is going to match while you're running your middleware
12:28justin_smithgfredericks: it's tricky - my middleware might want to act differently based on the route that gets matched, but I also might want to use a middleware to change which route gets hit (see friend for example)
12:32gfredericksjustin_smith: yeah -- I think it should just be easier to do things where you want to do them
12:32gfredericksI switched from compojure to polaris to make that easier, but it was still clunky
12:32justin_smithgfredericks: let me know if you have ideas for improving polaris btw.
12:33justin_smithI still vividly remember the heated discussion as we designed polaris at an indian buffet
12:38AeroNotixpolaris' image makes me feel nauseous
12:38AeroNotixespecially when scrolling
12:38justin_smithhaha
12:49gfredericksjustin_smith: iirc I ended up using polaris to make a middleware that's ordered pretty early, does route matching, adds a key to the req saying what route matched, and a function for doing that route's thing
12:49gfredericksthen there's a dummy handler at the bottom that just calls the function
12:49justin_smithgfredericks: interesting. If that's generally useful we could maybe include that middleware
12:50gfredericksit felt pretty weird :/
12:50justin_smithgfredericks: why not write the middleware to do things on the request coming out the other side rather than coming in?
12:50gfredericksthewhatnow?
12:51justin_smithie. instead of (fn [handler] (fn [request] (handler (foo request)))) you can do (fn [handler] (fn [request] (foo (handler request))))
12:51justin_smiththe latter lets the handler run first before doing its thing
12:51gfredericksthe driving use case was wanting all logging associated w/ the request to be able to include which route it was applying to
12:51justin_smithahh
12:52justin_smithso the logging could use the latter pattern, right?
12:52gfrederickswell there's two middlewares involved
12:52gfredericksone that does the route matching and one that does logging
12:53justin_smithyeah, I'm just saying if you added an assoc of the route at the handler dispatch, the first one isn't even a middleware any more
12:53justin_smithand if the logging uses type b (acting after the handler instead of before) it gets all the info it needs
12:54gfredericksthe logging goes on both sides
12:54gfredericksso the route has to be matched beforehand
12:55justin_smithwhat if the first part of the logger attached a lambda to the request
12:55justin_smithand the second part ran it
12:55justin_smith(with matching route as an arg, if course)
12:55gfredericksright, something like that is an option; it feels a little risky/loose to defer logging to after the request
12:56justin_smithit's still during the request - just on the tail end after the handler got hit
12:56gfredericksand that also presupposes that there aren't any other pre-middlewares interested in logging
12:56gfredericksor else you'd have to rewrite all of those too
12:56justin_smithright
12:57justin_smithgfredericks: it feels like something where there would be an elegant solution
12:57justin_smithperhaps it would require route matching vs. route execution to be broken up (which is what you did, in an ad-hoc way)
12:57gfredericksyeah
12:57gfredericksroute matching could return a keyword w/ a params map or something
12:58justin_smithpolaris should have a function that looks up the handler but not yet calling it
12:58justin_smithhmm, yeah
12:58adgtlAnyone know easiest way to parse json in clojurescript?
12:58gfredericksmake the pattern: (def my-routes [...]) (def base-handler (compile-base-handler my-routes)) (def wrap-route-matching (compile-route-matching my-routes)) or so
12:59adgtlseems this one is not available clojure.data.json?
13:00justin_smithadgtl: I think the easiest way in cljs is to let js do the parsing, and then convert it to clojure data afterward if needed with -js->clj
13:00adgtljs->clj?
13:00justin_smithyeah
13:00justin_smith-js->clj is the underlying protocol method
13:00justin_smithbut better to use the function, yeah
13:01justin_smithhttps://github.com/clojure/clojurescript/blob/master/src/cljs/cljs/core.cljs#L8676
13:01adgtlwhy can't I do (require '[clojure.data.json :as json])
13:01justin_smithclojure.data.json uses java
13:01justin_smithwhich isn't there in the clojurescript runtime
13:01justin_smithwell, it uses the jvm
13:02justin_smithand a javascript runtime's native json reading is very likely better than clojure.data.json could do anyway
13:03adgtljustin_smith: but now I have problem.. how can I know that some libraries are there in clojurescript and some are not
13:03adgtlI was assuming all the clojure libs are available for clojurescript too
13:03justin_smithadgtl: hopefully the libs will mention if they are cljs compatible
13:03justin_smithno, not all work
13:03adgtlAny documentation for -js->clj ?
13:04justin_smithadgtl: I just linked to it's source, including doc-string
13:04justin_smithyou would create the js object from the json in the normal way it is done in js
13:04justin_smithand then call js->clj on it
13:04tomjackcfleming: downgrading to 0.1.44 appears to have fixed my resolution issue
13:05adgtl(-js->clj "{}") fails on repl
13:05justin_smiththat's not a js object
13:05justin_smiththat's a json string
13:05adgtlhow to pass js object then?
13:05justin_smithsomething like (js->clj (JSON/parse "{}")) I think
13:05tomjackcfleming: oh, no, it didn't, nevermind :(
13:06adgtlthrows error too (-js->clj {a: "b"})
13:06justin_smithadgtl: yes, because you can't just put js literals in cljs
13:06justin_smiththat's why I suggested using JSON/parse
13:07adgtl(js->clj (JSON/parse "{'a': 'awesome'}")) fails too
13:07justin_smithit shouldn't
13:07justin_smithdon't use '
13:07justin_smith' isn't json
13:08justin_smith(js->clj (JSON/parse "{}")) will work
13:08adgtlokay
13:09justin_smith(js->clj (JSON/parse "{\"a\": \"awesome\"}")) also works
13:13gfredericksclojurebot: ' |isn't| json
13:13clojurebot'Sea, mhuise.
13:14adgtlcljs throwing
13:14adgtlNo such namespace: JSON at line 13
13:15adgtlI could do that from repl
13:15adgtlbut not from my cljs code
13:15l3dxI have a map where each value again is a map. I want to dissoc one of the keys from the inner maps. how would you do that?
13:15michaniskinjs/JSON
13:15gfredericksl3dx: update
13:16justin_smithmichaniskin: so then would it be (.parse js/JSON "{}") ?
13:16michaniskinjustin_smith: should be yes
13:16l3dxgfredericks: thanks!
13:23adgtlJust realized that I can't read files from clojurescript
13:23adgtlso slurp won't work
13:23justin_smithbut you can serve json files to cljs
13:23l3dxhah, nice 404 at clojuredocs :)
13:24justin_smithand there is also a #js literal for inline js in clojurescript
13:25justin_smith#js {"foo" "bar"} will create a js object directly
13:25justin_smithwithout even needing the json parsing step
13:27michaniskin(js-obj "foo" "bar")
13:29justin_smithmichaniskin: #js reader is just a shorcut for js-obj
13:29Lewixhttps://gist.github.com/6ewis/eb653a3985c5f7feeb30 - what does bottom and size refer to in this example
13:30justin_smithLewix: the arguments to the function
13:30michaniskinjustin_smith: indeed
13:30Lewixjustin_smith: no. I mean what do those specific argument represent
13:31justin_smithfrom reading the code, the y of the bottom edge, the x of the left edge, and the width/height
13:31justin_smithit generates x/y pairs for a square that is aligned with the cartesian grid
13:32Lewixjustin_smith: width/height?
13:32whodidthishow do i get lein midje to use project.clj's :test profile
13:32justin_smithLewix: yes, the size, in x/y units
13:33Lewixjustin_smith: it's not intuitive to me
13:34Lewixjustin_smith: thanks. I'll think about it
13:34justin_smithwell, since it is a square, the width and height are the same, right?
13:35justin_smithso they are provided as one argument
13:36Lewixjustin_smith: thanks. i got it now
13:42LewixHow do you think about the parenthesis in clojure?
13:43Lewixlike curly braces?
13:52sveriHi, having a list of arbitrary depth and length, how can I check if it contains a certain element?
13:52smt-Lewix: in C: foobar(1, 2, "foo"); in Clojure: (foobar 1 2 "foo"). that's how I think about them. they are not the same as curly braces
13:53rufoasveri: do you mean nested vectors? if so flatten them first
13:53sverirufoa: actually I mean seqs :-)
13:53sveribut flattening sounds good :-)
13:54Lewixsmt-: you think about them in terms of functions
13:54sverirufoa: thank you, I guess flatten will do the trick
13:54rufoa,(some #{4} (flatten '(1 2 (3 4) 5)))
13:54clojurebot4
13:54smt-Lewix: the trick is that everything in clojure is an expression, which means everything returns a value. even an 'if' returns a value. 'if' in C does not, it just branches the execution. once you grok the implications of that, parenthesis suddenly make sense
13:56Lewixsmt-: I see. so you think about them in terms of expressions
13:56adgtlWhat's the simplest way to do ajax from clojurescript?
13:58smt-Lewix: yes. in C you have nested blocks of code, and you control the execution flow. in clojure you have nested expressions but no blocks, hence no need for curly braces
13:58rufoaLewix you might find this illuminating https://en.wikipedia.org/wiki/S-expression#Use_in_Lisp
13:59Lewixsmt-: thanks
13:59Lewixrufoa: thanks I'll give it a read later
14:02smt-adgtl: https://github.com/JulianBirch/cljs-ajax
14:02adgtlsveri: thanks :)
14:03adgtlsmt-: how about cljs-http?
14:05smt-adgtl: I've never used cljs-http so I don't know about that
14:12adgtlsmt-: ok
14:19Lewix(require '[clojure.string :as str])
14:20Lewixwhy do we need `
14:20Lewix;`[1 2]
14:20jjmojojjmojoLewix: because clojure.string isn't in the namespace
14:20Lewix;;`[1 2]
14:20Lewix>>`[1 2]
14:21jjmojojjmojoLewix: https://clojuredocs.org/clojure.core/quote
14:21jjmojojjmojothat's what ' is expaned to in the compiler
14:22LewixHow do you guys run clojure code
14:22Lewixhere
14:22mearnsh,`[1 2]
14:22clojurebot[1 2]
14:22Lewixthanks
14:23Lewix,(type `[1 2])
14:23clojurebotclojure.lang.PersistentVector
14:23Lewix,(type [1 2])
14:23mearnsh,`(+)
14:23clojurebotclojure.lang.PersistentVector
14:23clojurebot(clojure.core/+)
14:23mearnsh,'(+)
14:23clojurebot(+)
14:23Lewixso jjmojojjmojo it's pretty much the same thing it seems (whenever we use vector)
14:23mearnshsyntax quote ` gives you fully qualified symbols
14:23clojurebotCool story bro.
14:24sundbryClojurebot, stop being a dick!
14:24Lewixmearnsh: can you be more explicit please
14:24mearnsh`str
14:24mearnsh,`str
14:24clojurebotclojure.core/str
14:24mearnsh,'str
14:24clojurebotstr
14:25Lewixmearnsh: i understand why it's needed for lists but not so sure about vectors
14:25jjmojojjmojoLewix: it's not though - when you use it in a case like require, you're passing an un-evaluated vector that contains references to things you want to be loaded - if you try (require [clojure.string :as str]) it will break (unless you somehow have clojure.string already loaded)
14:25mearnshis there a context to this question?
14:25justin_smithLewix: in general it namespace qualifies things, and allows selective unquoting
14:25justin_smith` is most useful in macros
14:25jjmojojjmojomearnsh: the initial query was about require
14:26jjmojojjmojodisclaimer: I am not an expert :)
14:26Lewixjjmojojjmojo: ah i see, we are using a function in the vector we're passing
14:26srrubyHow do clojure servers compare with node.js for serving restful apis ? I'm reviewing current web stacks. Some are recommending node,express,mongo,and angular. I'd probably go for clojure and react...
14:27jjmojojjmojosrruby: what sort of comparison do you want?
14:27justin_smithLewix: wait, you showed an example using ' and then asked why we need ` right?
14:27jjmojojjmojoexpress != node :)
14:28Lewixsrruby: my guess is not callback hell and promises craziness anymore
14:28Lewixjustin_smith: i meant `
14:28jjmojojjmojosrruby: I'm not like the other kids, but I prefer to build my restful stuff without help from frameworks and other distractions - so all I need is something like ring
14:28justin_smithok, because you should not use ` with require
14:29Lewixjustin_smith: oh apparently it's ' ( i confuse both all the time)
14:29jjmojojjmojoLewix: me too :)
14:29justin_smithOK - because it made it look like you were asking a much more complex question than you actually were
14:29Lewixjjmojojjmojo: so what's ` for and what's ' for
14:30Lewixjustin_smith: most of my questions are probably basic at this point. I don't know clojure
14:30justin_smith' prevents evaluation, ` prevents evaluation, fully resolves symbols in the current context, and allows selective unquoting and splicing
14:30jjmojojjmojoLewix: ^^^ what justin_smith said
14:30srrubyThanks everyone. I'll think about how to formulate a better question.
14:30justin_smiththe features of ` are mostly useful when writing macros
14:31Lewixjustin_smith: it' sso confusing
14:31smt-Lewix: does this help:
14:31smt-,(let [x 10 y 20] [x y])
14:32clojurebot[10 20]
14:32smt-,(let [x 10 y 20] '[x y])
14:32clojurebot[x y]
14:32justin_smithsrruby: the big difference between clojure and node imho is that clojure takes longer to start up, but it can scale more in a single process. Both can do async within one thread, but clojure has the option of also having mutiple threads
14:32smt-,(let [x 10 y 20] `[x y])
14:32clojurebot[sandbox/x sandbox/y]
14:32Lewixholycow
14:33Lewixjustin_smith: , smt- : I'm not sure i understand `
14:33Lewixit does the same thing as ' + extra stuff
14:34justin_smithLewix: it's useful when writing macros, don't worry about it (and don't use it) until you need it for macro writing
14:34Lewixyet we cannot use it as a replacement for '
14:34justin_smithno, because it does extra stuff :)
14:34Lewixok I'll leave it at that for now
14:34justin_smithA tank does what a truck does, + extra stuff
14:34justin_smithbut you probably don't want to use it instead of a truck usually
14:35Lewixok fair enough
14:35Lewixam I gonna survive with clojure?
14:35srrubyjustin_smith: Thanks. I think I'll use Clojure when I can in order to preserve my sanity.
14:35LewixI'm losing my motivation to learn it everyday
14:35justin_smithLewix: I think so. Don't be afraid to try things in the repl. Try things that you think should work, and also try things that you think should fail.
14:35Lewixsrruby: aha tell me about it
14:36drojasanyone knows some graph data structure library?
14:36Lewixjustin_smith: what p languages do you work with?
14:36justin_smithLewix: remember that it doesn't go as deep as other langauges do. You learn some rules and special cases, and relatively quickly you are done. After that it's figuring out the nuances, and how to design things for the most part.
14:37justin_smithLewix: in the past I have used C, C++, OCaml, Scheme
14:37justin_smithplayed around a little bit with java / javascript and a bunch of other stuff
14:37justin_smithlot's of shell scripting with vanilla bourne shell/ bash if you count that
14:37Lewixjustin_smith: I see. thanks for the encouragement
14:38justin_smithLewix: I'd say it's pretty similar to C in terms of the number of special cases you need to learn. Much simpler than eg. C++, Java. A bit more complex than OCaml and Scheme are but not massively so.
14:39smt-Lewix: have you written any simple programs in .clj files, or played only in repl?
14:40Lewixjustin_smith: yea I learned C++ Java back in college (Haven't touch those for an eternity so I barely remember). I also played with C but these days I'm mostly into ruby and javascript in my day to day work
14:40smt-justin_smith: btw, does OCaml have persistent data structures?
14:40justin_smithsmt-: indeed it does
14:41justin_smithsmt-: it doesn't have a concurrent garbage collector though, so it can't do multi process things as easily as clojure
14:41Lewixsmt-: I'm playing while learning. It;s just that pesky feeling that you're starting something from scratch and you're not even sure it's worth your time
14:41justin_smithusually it is similar to eg. ruby / python / node where you start multiple processes and have them communicate, not as nice as multi threading in clojure
14:41smt-justin_smith: how do you like OCaml? I almost began learning it some years ago, but didn't. should I? :)
14:42justin_smithsmt-: I think it is great. Many of the advantages of Haskell while being much easier to pick up and learn.
14:42justin_smithand if you like clojure, most of the ideas cross over (higher order functions, immutable data, etc.)
14:43smt-justin_smith: thanks, sounds promising
14:43justin_smithbut you also get pattern matching, and static typing (for better and every so often worse)
14:44Lewixjustin_smith: which one do you prefer
14:44justin_smithLewix: I like clojure - because I am doing stuff that works better with real threads
14:44justin_smithalso, it's easier to deploy in a corporate environment if you are using the jvm
14:45Lewixjustin_smith: I heard we can use clojure on top of node?
14:45justin_smithLewix: clojurescript, yeah. Though I think node support might still be in progress?
14:45smt-Lewix: what kind of applications would you like to do? that way you can figure out if learning clojure is worth it
14:45smt-Lewix: games? web apps?
14:46Lewixsmt-: mostly backend for mobile apps
14:46justin_smithLewix: server backend, with multiple clients, is a place where Clojure does very well.
14:46smt-Lewix: for that kind of work I find clojure excellent
14:47Lewixgreat. lets see how it goes
15:21Lewixjustin_smith: what book do you advise
15:23whodidthishow do i insert a vector of longs to a bigint[] column in yesql, i tried "...VALUES (:user_id, :my_vector)" and "VALUES (:user_id, (:my_vector))" but the first one says "insert has more expressions than target columns" and the other "expression is of type record"
15:23justin_smithLewix: Clojure Programming is good
15:25devll(inc justin_smith )
15:25lazybot⇒ 4
15:25justin_smithdevll: it's space-sensitive
15:25justin_smith(identity karma karma karma karma chameleon)
15:25lazybotkarma karma karma karma chameleon has karma 1.
15:26AeroNotix(identity AeroNotix)
15:26lazybotAeroNotix has karma 5.
15:26AeroNotixyay
15:26AeroNotixTIL
15:26justin_smith(identity justin_smith)
15:26lazybotjustin_smith has karma 186.
15:26justin_smith(identity justin_smith )
15:26lazybotjustin_smith has karma 4.
15:26AeroNotix(inc justin_smith)
15:26lazybot⇒ 187
15:26AeroNotix187 skills
15:26AeroNotixCkihy
15:27devllwow
15:28AeroNotixProtected by clojurists with big ideas, Parens, and 187 skills
15:28AeroNotixjustin_smith: ^
15:28justin_smithhaha
15:29ncthom91hi all. Any overtone users in here?
15:32amalloy~anyone
15:32clojurebotJust a heads up, you're more likely to get some help if you ask the question you really want the answer to, instead of "does anyone ..."
15:32AeroNotixor my favourite variation:
15:32AeroNotixdon't ask to ask, ask.
15:32amalloy~ask
15:32clojurebotThe Ask To Ask protocol wastes more bandwidth than any version of the Ask protocol, so just ask your question.
15:33AeroNotix:|
15:33AeroNotix(inc clojurebot)
15:33lazybot⇒ 47
15:33amalloythat factoid is technomancy's i think
15:33AeroNotix(inc technomancy)
15:33lazybot⇒ 162
15:33AeroNotix,scoreboard
15:33clojurebot#<CompilerException java.lang.RuntimeException: Unable to resolve symbol: scoreboard in this context, compiling:(NO_SOURCE_PATH:0:0)>
15:35gfredericksI think there's another element to it, which is that some people might be able to answer your question but aren't willing to admit to arbitrary familiarity with X since who knows what the followup question might be
15:35amalloyright, that's my perspective
15:35AeroNotixalso, the X/Y problem
15:36amalloy(not on overtone specifically, since i know i won't be able to answer)
15:45justin_smithamalloy: the question asker may think it's an overtone problem, but it turns out to be like their profiles.clj is messed up
15:45justin_smithamalloy: things like that happen all the time :)
15:52justin_smithncthom91: anyway, what's your overtone question?
15:54ncthom91justin_smith it's about how to route audio buses in overtone. i.e. if I define an instrument with definst, I'm not sure how I would then route the output of that instrument through various fx (i.e. if I want to write a custom waveshaper), and then how I would do things like split the audio bus and route the same channel simultaneously through two parallel effects
15:55justin_smithncthom91: with overtone's model, splitting a bus is just a question of using the same bus in two places
15:55ncthom91cool. that parts easy enough then, eh? :)
15:55justin_smithncthom91: regarding routing, it's been a while since I have used this, but it all happens in the supercollider vm - there are commands in the vm to route different "synth groups" to one another
15:56justin_smithevery instrument is in a synth group, and you can tell the sc vm that the output of one synth group is the input of another etc.
15:56ncthom91justin_smith do you know how to do that?
15:56ncthom91is it part of hte overtone clojure api? Or do I have to get down in the SC trenches?
15:57justin_smithncthom91: almost everything in overtone is just network commands sent to the sc vm
15:57justin_smithall those routing commands are exposed to the network interface, even if overtone doesn't map them they can likely still be accessed in some way
15:59ncthom91justin_smith this actually looks close to what I need I think: https://github.com/overtone/overtone/blob/e200075da27375727db1f5ce342e2e1c22ea1dbd/src/overtone/examples/synthesis/fx.clj#L25-L36
16:00justin_smiththat looks exactly right, yeah
16:00justin_smiththough I thought it would be a bit more flexible. I guess you could define everything to take a bus in
16:01justin_smithand a bus out...
16:01justin_smithbut yeah, it will at least do what you want
16:01justin_smith(right now I am working on a little pixie lang dsl to create a csound score for a musical project)
16:01ncthom91justin_smith woah awesome! Is it open source?
16:02justin_smithnot uploaded yet, I might at the very least upload some of the util libs
16:02ncthom91I'm working on a synthesis exploration blog post using overtone
16:02justin_smithmay or may not upload the composition (it uses a huge audio file...)
16:02justin_smithcool
16:03justin_smithI tend to like csound as a target lang because it is super trivial to generate code for (it is basically a modified assember syntax)
16:03justin_smithor a lisp with no parens, no first class functions, and only one expression per line
16:05ncthom91justin_smith hm, I'm rather unfamiliar with csound but I know I've heard of it
16:05justin_smith(the syntax supports more than that, but it can be used in that stripped down assmbler style)
16:05justin_smithit's a direct descendent of the language max matthews used to program a computer to sing "bicycle built for two"
16:06justin_smithnot as fancy as supercollider, but it's familiar to me so I use it
16:06justin_smithand it's very low overhead for the most part
16:08ncthom91to be fair, I never got into SC either. I've always worked in higher level languages like Max/MSP, but in the past few years I've really gotten interested in the math behind hte sound, hence my diving into overtone
16:08ncthom91hm that's probably where I've heard of CSound... does Max/MSP have a relation to csound?
16:09justin_smithncthom91: MSP is Miller S Puckett, a student of Max Matthews
16:10justin_smithMSP is the author of PD, which you may have heard of
16:10justin_smiththey all (including supercollider which is the engine for overtone) use the same basic internal model
16:10justin_smithbut they have various syntax and UI differences
16:11justin_smitheg. Max and PD are both point and click visual programming
16:11justin_smithbut the semantics are identical to the textual ones still
16:12cflemingtomjack: Ok, thank - I haven't had a chance to look at your repro case yet, I'll take a look today
16:12cflemingtomjack: *thanks
16:21ncthom91justin_smith cool, yea i've used PD a bit
16:23justin_smithI've found core.async maps nicely to the part of my brain that knows pd
16:24ncthom91justin_smith how do you suppose I could take an audio bus in, duplicate the sound and pitch offset one of the duplicates in the output bus?
16:24justin_smithmy bigger pd patches were all sends and receives
16:26justin_smithso mix audio on an input bus with a pitch shifted verdion of itself?
16:27ncthom91justin_smith yea
16:27justin_smiththe audio sig itself won't be destroyed by pitch shifting, so you can just use the same input twice
16:30justin_smithand then sum the regular signal with the shifted one. usually this turns out better if you also adjust the level of the clean and shifted sigs
16:32ncthom91justin_smith sweet yea that makes sense. How would you shift the signal? Supposing I'm going to have to calc the FFT here yea?
16:32justin_smithit is just like taking two connections from the same in in pd, processing one, and adding that to the other
16:32ncthom91right
16:32sveriHi, I have trouble understanding first and rest in a loop recur. In this paste: http://pastebin.com/2d53etiJ I have a vec, doing first on it gives me back a list. Doing rest on it gives me back a list in a list whereas I expect just a simple list too. Why is that?
16:33justin_smithncthom91: there should br a good pitch shift built in
16:33ncthom91justin_smith ah, that'd be sweet :)
16:34ncthom91hm looks like there's a UGen for it. Suppose I gotta learn how to use UGens then lol
16:36justin_smithsveri: do you want second instead of rest?
16:37sverijustin_smith: second would work, but I might have more than two seqs in the vec and wanted to use loop / recur with first / rest
16:40ncthom91justin_smith any chance you've worked with ugens in overtone? can't seem to find good docs on it
16:41sverijeez, I am so stupid, of course rest returns the rest in a list -.-
16:45justin_smithncthom91: doesn't using a name in a synthdef translate to using that ugen?
16:50justin_smiththe overtone cheatsheet indicates you can call shift in a synthdef
16:55ncthom91justin_smith what do you mean using a name in synthdef translates to using a ugen?
16:57justin_smithsynthdefs are not normal code
16:57justin_smithhey are dsl
16:58justin_smith(shift sig) in a synthdef translates to inserting the shift ugen in the def
17:00emaczendoes anybody here use the luminus web framework/libraries?
17:01emaczenI want to know about the HTML templates that are loading by default
17:01emaczenI would prefer to solely use clojure/clojurescript
17:03justin_smithemaczen: you should just be able to add a dep to your preferred templating lib and csll that in your handlers
17:06emaczenjustin_smith: Do you use the luminus stackk?
17:06emaczenOr the libraries since it is mostly a set of libraries rather than a framework
17:10emaczenjustin_smith: I ask because I don't see where to do this -- I see a selmer dependency in handler.clj but it is only called in one place that doesn't seem all that related to what you mention.
17:10avshalomemaczen: yes, and i also use "web development with clojure" as a reference
17:11justin_smithI don't use it, but chsnging page rendering will just be a question of changing what the handler function returns
17:11emaczenjustin_smith: Ok, I know where that is then.
17:11emaczenavshalom: Do you use Selmer? Or do you use clojurescript for templating?
17:12emaczenI think the cljs templating is the hiccup library? Is that correct?
17:12avshalomnot yet, now i am using hiccup
17:12avshalomonce i start working with web developers i will probably switch over
17:12emaczenavshalom: Do you plan on using Selmer? If so why?
17:13avshalomemaczen: i think it would be better for implementing existing stylesheets that were created by webdevs using other technology
17:14emaczenavshalom: Yeah, I'm trying to work by myself so it wil be a matter of personal preference for me then :)
17:14avshalomemaczen: now, i am just writing boring webpages by synthesizing with hiccup
17:14emaczensynthesizing?
17:14avshalomprogrammatically generating
17:14emaczenavshalom: I'm new to web-development with a little experience with some JS technologies but I do mostly backend work.
17:15emaczenI also have some Common Lisp experience
17:15avshalomemaczen: i'm not a web maven -- i usually do the brains and back end. so, this is new territory, don't know the web lingo
17:15emaczenavshalom: Haha, I guess we are in similar boats then...
17:15emaczenBut you look like you have the head start :)
17:15avshalomemaczen: i would definitely get the "web development with clojure" book/pdf
17:16emaczenSounds like a good idea.
17:16avshalomthere is also a video series by packt? i think
17:16emaczenOne quick question for you though.
17:17avshalomit's audio is a little crummy, but if you want to get up and going FAST, then it's pretty good
17:17avshalomyes?
17:17emaczenInside the home-page function in home.clj -- how do you render the page with hiccup? By default with luminus there is a line of code: (layout/render "app.html" ...
17:18emaczenThis renders the HTML/Selmer template.
17:18avshalomdunno, i don't use selmer (yet)
17:18emaczenavshalom: I wish to use hiccup
17:19avshalomjust something like (defroutes "/" [] (home)) i think, with content in home function
17:20emaczenCan you link me to those videos by pakt?
17:20emaczenI didn't find anything on goolge
17:20emaczenahh, I think I found it
17:20emaczenI'm getting antzy I guess...
17:20avshalomhttps://www.packtpub.com/web-development/building-web-applications-clojure-video
17:20emaczenThanks!
17:20avshalomyeah, its $35 well spent.
17:21avshalom(defn home [] (layout/common [:h1 "Doo Dah"]))
17:23emaczendoes web-dev with clojure use hiccup for their layouts?
17:23emaczenI have played with hiccup inside selmer actually
17:23emaczenWait
17:23avshalomiirc, it does both
17:23emaczenI mean, I have loaded some selmer templates, and then on top of that used some hiccup
17:26avshalomi really want that book on reactive functional programming. i guess i have to wait another month....
17:27avshalomi came from a Fortran / Scientific programming background, and all this stuff is radically different, but i think that i know that i want to do it
17:27avshalomsome book on idioms for concurrent programming
17:28avshalom(but in clojure, because i'm not good at clojure or concurrent programming)
17:28emaczenavshalom: How much do you know about Lisp dialects?
17:28avshalomemaczen: i can do small stuff in elisp
17:29emaczenavshalom: Do you know how to use lisp macros?
17:29avshalomemaczen: but elisp is not practical enough for "day job" stuff. clojure is practical, though unfortunately, so much maths code is in C and Fortran
17:29emaczenavshalom: Maxima is written in Common Lisp
17:29emaczenClojure is influenced by Common Lisp
17:29avshalomemaczen: i know the rudiments of Lisp Macros, but i haven't found a case where i would say "oh, i gotta have a macro instead of a function"
17:30emaczenavshalom: I'm new to this as well but I found a pretty cool use case the other day.
17:30AeroNotixemaczen: one of the things I really like about Clojure is how un-Common Lisp it is.
17:30AeroNotixoriginally Clojure was implemented in CL but Clojure is decidedly not anything at all much like Common Lisp
17:30AeroNotixaside from being, you know, a Lisp.
17:31avshalomemaczen: in fact i came to Lisp through Mathematica (don't shoot, i know mma is not a lisp)
17:31emaczenAeroNotix: I don't really know details, but from the languages I have played with, it is most similar to common lisp.
17:31AeroNotixemaczen: in what way?
17:31avshalomcompleteness?
17:32AeroNotixOh right we're just making things up. Gotcha.
17:32emaczenAeroNotix: multimethods
17:32emaczengeneric funciton model instead of message passing mod
17:32emaczenmodel*
17:32emaczenand it is a lisp dialect, where every other language I know is not.
17:32AeroNotixemaczen: multimethods aren't at all like CLOS.\
17:32emaczenCLOS has multimethods
17:33emaczenI have not used another PL that uses the generic function model
17:33AeroNotixSure, but it's much richer and actually is a core language feature, rather than being altogether "meh" in Clojure.
17:33emaczenIf you know a little CL, I think it is a good place to start drawing connections
17:34emaczenAvshalom: Anyway, the use case for macros that I found interesting/fun was a tiny SQL like manipulation for an inefficient list of lists data-table implementation
17:34AeroNotixand you only have single dispatch in Clojure.
17:35m1dnight_guys, currently I have a printer function (def print [sender & msgs] ..) that I call like (print "me" "foo" "bar")
17:35emaczenAvshalom: So I defined 'select' and 'where' as "library" functions and then used them in a macro that would let me type something like: (select (column1 column2) from table where [expressions are true]
17:35m1dnight_but now I want to add a second function that takes multiple lists that represent a single line (multithreaded and all that)
17:36m1dnight_I'm guessing it's not possible since [sender & msgs] will match anything, right?
17:36avshalomemaczen: that's cool
17:36avshalomemaczen: that's another book i want, the one on clojure macros
17:37avshalomemaczen: maybe one day when i am a clojure stud, i will write my own dsl
17:37emaczenavshalom: if you are interested in macros, I would recommend On Lisp by Paul Graham
17:37avshalomor not, because i'm having a blast making money with functions ;-)
17:37emaczenavshalom: Yeah, I should spend more time trying to make some money than doing random lispy things :)
17:38AeroNotixOn Lisp is one of the only very detailed texts on macros. It gets another +1 from me.
17:38avshalomemaczen: i will say that i haven't had this much "fun" in years. clojure has been fun!!!!
17:39emaczenavshalom: Oh yeah! All Lisp programming is usually fun!
17:39avshalomemaczen: and remarkably Mathematica-like. i feel that i can transfer a lot of experience into clojure, and bosses will be satistfied by JVM language
17:39avshalomemaczen: i love using clojure, and watching my 40-core machine shoot to 100% usage.
17:39AeroNotixyou develop on a 40-core machine?
17:40avshalomyeah
17:40emaczenI'm jealous!
17:40avshalomit's a fucking beast
17:40avshalom250 gig of ram, 200 terabytes of storage
17:40emaczenavshalom: I guess you are doing some machine learning / statistics?
17:40avshalom(and i have three of them)
17:40emaczenWith Big Data?
17:40avshalomemaczen: yeah
17:40AeroNotixWhich processor is that?
17:40avshalomoh, i dunno. xeon or something
17:41avshalomi also use an ibm p595
17:41AeroNotixhaha
17:41AeroNotixok
17:41AeroNotixo7
17:41avshalomwe're getting a new one soon, just that it takes a bit of time to buy a $10 million dollar machine.
17:41AeroNotixRoger.
17:41AeroNotixI'm writing this all down.
17:43avshalomemaczen: i'm in the post-big data / machine learning world
17:43AeroNotixhttps://www.youtube.com/watch?v=pnD_51Vvi1I
17:43avshalomemaczen: i've gone back to smarter/better models that actually fit the problem
17:43emaczenavshalom: What is the post-big data / machine learning world?
17:43avshalommore bayesian statistics and markov chain monte carlo
17:43emaczenAhhh cool! I'm just getting into this world really.
17:44avshalomemaczen: i.e. there is no universal algorithm (machine learning) that will solve all problems
17:44emaczenI wrote a naive bayes classifier with gaussian and bernoulli implementations
17:44emaczenMostly as a Common Lisp exercise
17:44avshalomnaive bayes is actually pretty good imo. and a good framework to develop sophisticated models.
17:45avshalomyeah, recur :-)
17:45m1dnight_is there a thing like "unlist"?
17:45m1dnight_I want to pass a list of elements as multiple arguments to a function but i'm not sure how
17:45m1dnight_I know I've done it before but i can't remember
17:45avshalomemaczen: talk to you later, maybe here or on #emacs. i need to go yell at the kids
17:46avshalomtake care AeroNotix, i will make you an account once the power 8 arrives
17:46AeroNotixm1dnight_: apply
17:46AeroNotixavshalom: An elephant you say?
17:46avshalom:-)
17:46AeroNotixm1dnight_: ,(apply + [1 2 3 4])
17:46AeroNotix,(apply + [1 2 3 4])
17:46m1dnight_yea, but what if + takes more than 1 argument?
17:46clojurebot10
17:46emaczenavshalom: haha sounds good, cya later
17:46m1dnight_the signature is (def printer [sender & msgs] ..)
17:47AeroNotixm1dnight_: TIAS
17:47AeroNotix,(doc apply)
17:47clojurebot"([f args] [f x args] [f x y args] [f x y z args] [f a b c d ...]); Applies fn f to the argument list formed by prepending intervening arguments to args."
17:48m1dnight_ohhhh
17:48m1dnight_(I had to google TIAS, btw)
17:48AeroNotixm1dnight_: :)
17:50mr_rmdid (fn) always allow you to give it a name, like: (fn foo [_] 42) ?
17:51Bronsamr_rm: yes
17:52AeroNotixthe alternative is maddening
17:52mr_rmBronsa: ok thanks. it took me quite a while to realize that! i always thought it was purely anonymous and was doing stuff like (let [foo (fn [_] ...)] ...)
17:52AeroNotixmr_rm: there's let-fn
17:53AeroNotixsorry letfn
17:53mr_rmAeroNotix: yes, i knew about that. just a stupid example
17:53AeroNotixstoopid example
17:53mr_rmheh
17:56m1dnight_okay I have one more question, if you guys dont mind. (I have googled zip, merge, merge with, zip with, concat with..) but I would like to merge sequences with a value
17:57m1dnight_like (merge-with [1 2 3] [4 5 6] [-1]) --> [1 2 3 -1 4 5 6]) ?
17:58AeroNotixm1dnight_: flatten
17:58AeroNotixbut
17:58AeroNotix,flatten
17:58AeroNotixdammit
17:58clojurebot#<core$flatten clojure.core$flatten@99a9fc5>
17:58AeroNotixmr_rm: concat
17:58AeroNotix~flatten
17:58clojurebotflatten is rarely the right answer. Suppose you need to use a list as your "base type", for example. Usually you only want to flatten a single level, and in that case you're better off with concat. Or, better still, use mapcat to produce a sequence that's shaped right to begin with.
17:58AeroNotixm1dnight_: ^^
17:59AeroNotixm1dnight_: that has had some sorting applied, what's the sort there?
17:59m1dnight_well, the actual use case is the following: I want to call (debug-msg sendername ["line" " one"] ["line " "two"])
18:00AeroNotixand?
18:00m1dnight_Since this debugging function is needed for the sake of printing multiline without other threads interleaving
18:00m1dnight_I need to put it in a single print statement
18:00m1dnight_so no particular sort, the elements arent even numbers
18:00AeroNotixYou're talking about printing to the terminal?
18:00m1dnight_yes
18:00AeroNotixDo you care about logging?
18:01m1dnight_it's more debug logging :p
18:01AeroNotixah
18:01m1dnight_but I have some "state" I need to print that takes up multiple lines
18:01AeroNotixI get you
18:01AeroNotixuse concat
18:01m1dnight_and I have multiple threads spitting their state and it gets messy real quick :>
18:02AeroNotixthis is why when you care about stuff, use a proper logging joint.
18:03AeroNotixe.g. we use logstash using tools.logging
18:03AeroNotixand it exports the thread it was running on, so you can drill down into your logs with the thread ID
18:03m1dnight_ah, ill have to check that out then )
18:03m1dnight_thanks for the info, AeroNotix
18:05AeroNotixm1dnight_: e.g. http://i.imgur.com/q6lFGDN.png
18:12AeroNotixWhat're some cool Clojure open-source projects people are interested in?
19:04seangrove$seen bhauman
19:04lazybotbhauman was last seen quittingQuit: bhauman 2 hours and 54 minutes ago.
20:27gfredericks,'welp
20:27clojurebotwelp
20:50pcnIs this the right forum to ask cider questions?
20:51pcnAh, never mind, I see it now
20:53justin_smith,'narp
20:53clojurebotnarp
20:58gfredericks,'blelk
20:58clojurebotblelk
21:22brainproxyhappy day for clj devs who are fans of devdocs
21:22brainproxyhttp://devdocs.io/clojure/
21:23arrdemcool!
21:40gfrederickspop quiz: what's the difference between (def x) and (declare x)?
21:41justin_smithoh, wow, that's tricky. def adds metadata that declare doesn't?
21:42gfredericksthat's basically the exact opposite of the right answer
21:42justin_smithoh, haha
21:42justin_smith-1 point for me then
21:43gfredericksdeclare is actually just a macro that adds ^:declared
21:43gfredericksoh also it can take multiple symbols
22:03cyy Hello everybody! I have a question about the multitask on the same JVM. When I type the following three commands in different terminals: "lein ring server" "lein cljsbuild auto" "lein tramponline cljsbuild repl-listen" dose Clojure will setup three different JVMs to execute these commands? If Clojure will do this, could I have a way to force them share the same JVM to execute these task? I found that after executeing these commands my
22:04cyy--- I found that after executeing these commands my computer memory has been nearly used up, so I want to know whether there is any way to decrease the memory consumption. Thanks!
22:04justin_smithcyy: this is lein specific. Check out the "lein pdo" plugin
22:05justin_smithpdo will make it do parallel lein tasks in one instance
22:06arrdem(inc justin_smith)
22:06lazybot⇒ 188
22:06arrdemchrist you've been busy
22:07justin_smithheh
23:59ddellacostawhat are folks doing for sharing namespaces for testing utilities between different projects?
23:59ddellacostawe've got some duplicated code now, but it's also a major pain in the butt to have a separate namespace for testing utility libs