#clojure logs

2012-11-10

00:05XPheriorWho's awake?!
00:06twobitspriteyou
00:06XPheriorHaw.
00:47brainproxySgeo: https://gist.github.com/4050049
00:48brainproxyI'm working on monad transformers, and discovered by experiment that the algo.monads implementation and the protocol-monads (my fork) implementation are giving different answers
00:49brainproxyfor monadic plus in the context of the list/sequence transformer applied to the set monad
00:49brainproxybut which one is "correct"?
00:49brainproxyhaving a hard time consulting the haskell wiki as the notation is hard for me to follow
00:50SgeoIs there a difference between the "set" monad concept and the list monad?
00:50SgeoWhat happens if you try these examples, converting to the list monad?
00:50brainproxyso, sequence/list transformer over the list-monad?
00:51SgeoHold on, I'm not thinking this through
00:51brainproxyokay, thanks for your time, I actually need to step away for a little bit, but I appreciate your input
00:51brainproxyshould be back in 25 min or so
00:52SgeoAre you sure that the inputs you're giving to the function are effectively similar enough for the question to make sense?
00:52imeredithbrainproxy: i dont get clojures syntax well, but are you basically trying to do something like ... Set(1 2) + Set(3 4) ?
00:52brainproxySgeo: yes, they're the same inputs
00:52brainproxyeffectively, i mean
00:52brainproxywell... I have a high degree of confidence they are
00:52SgeoBecause the first one is giving am/m-plus a bunch of sets that themselves contain a list
00:53amalloyimeredith: no, he's doing something pretty obscure; i wouldn't worry about it
00:53SgeoAnd the second is giving... not entirely sure about that list-t stuff, but looks like just a bunch of lists?
00:53brainproxythe first one is asking to carry out monadic plus on the set-list monadic values
00:53brainproxyand the same for the second
00:53imeredithamalloy: k, i was going to see what scalaz did, but i cant grok clojure well :)
00:54brainproxyimeredith: thanks for thinking about it :)
00:54brainproxySgeo: (set-list 1 2) is effectively the same as #{(1 2}
00:55amalloyas a fun aside, brainproxy and Sgeo, have you tried to provide an instance of Monad for Set in haskell?
00:55brainproxyamalloy: i don't know a lick of haskell, yet
00:56Sgeoistr that one of the problems in attempting to do so is that Sets require a typeclass constraint (forgot if that's the term), and thus >>= for sets would have to be (Ord a, Ord b) => Set a -> (a -> Set b) -> Set b
00:57amalloySgeo: right on the nose
00:57SgeoAnd you can't write that instance, since >>= is not supposed to have that constraint
00:57brainproxyokay, well let me try with list transformer over list monad
00:57brainproxyand see how results compare in the two librarier
00:57SgeoBut that's irrelevent to Clojure
00:57amalloyalthough i didn't know Set had that constraint; i thought it was just the union function
00:57brainproxy*libraries
00:57Sgeoamalloy, hmm, hold on'
00:57amalloywell, that's why i said "as a fun aside"
00:58Sgeoamalloy, um, I think it's that >>= would need to use a function that requires Ord... I don't really remember
00:58SgeoI do recall that using constraints in the data declaration is recommended against, so that they're not needed everywhere.
00:58SgeoIt's been a while
00:59SgeoSo probably not that Set requires it, but some operation that >>= needs would require it
00:59imeredithSgeo: amalloy, at worst dont sets just require equals?
00:59amalloySgeo: yes
00:59Sgeoimeredith, in theory, but an efficient implementation needs some ordering, even if it's arbitrary
00:59imeredithof course
01:01brainproxySgeo: https://gist.github.com/4050099
01:02brainproxysimilar result
01:03Sgeo> msum [[[1, 2, 3]], [[]], [[3, 4]]]
01:03Sgeo=> [[1,2,3],[],[3,4]]
01:03SgeoStill not entirely sure of what you're inputting for the second one
01:03SgeoWhat's the list-t used for here?
01:04brainproxylist-t is the list transformer
01:04imeredithoh
01:04brainproxyapplying it to the list monad
01:04SgeoThis seems like it's likely to be a different operation from just putting a list in a list
01:06SgeoI'm not certain, because I don't understand monad transformers too well, and especially not in the context of Clojure
01:06brainproxyhttps://github.com/clojure/algo.monads/blob/master/src/main/clojure/clojure/algo/monads.clj#L610
01:06imeredithi really wish multibot was going
01:06brainproxyi think I understand the docstring more clearly now
01:09brainproxySgeo: thanks, it looks like algo.monads has it right and the protocol-monads have a subtle implementation problem
01:09SgeoYou're... welcome, but I still wish I entirely understood what is going on
01:09brainproxythat is, given that haskell's msum and algo.monads m-plus are doing the same thing
01:09SgeoAre you certain that trying something closer to the equivalent in protocol monads won't give you the same result?
01:10brainproxywell I'm not sure I do either, I'm learning what it all means by banging around with the two libraries, and grok'ing what I can from haskell-related discussions
01:11brainproxybut the idea is that the list monad has been composed with the list monad, and there are rules for how to to deal with that when you want to do monadic operations on the compound monad
01:11Sgeo@(m/m-plus [(list (list 1 2 3)) (list (list)) (list (list 3 4))])
01:11muhooi don't think i've ever seen a monad in clojure code in the wild.
01:11Sgeobrainproxy, maybe compare it with ... oh, I see, you are
01:11SgeoOh, I don't know if the Haskell code I pasted actually corresponds properly
01:13brainproxyokay
01:13imeredithbrainproxy: so basically whats going on is that the list transformer gives you access to the inner stuff, hense you are combining your inner lists into on
01:13imeredithe
01:13imerediththen it unwraps it into the outer bit which is a list
01:14brainproxyimeredith: close
01:14brainproxybut that's the basic idea
01:14imeredithbrainproxy: try using an option instead of a list, and i think it should become clearer
01:15brainproxyoption?
01:15imereditherr
01:15imeredithmaybe
01:15imeredithoh
01:15brainproxylike maybe monad?
01:15imeredithbrainproxy: sorry, i see the subtle difference
01:15imeredithbrainproxy: yeah, im just saying, i think you are being confused by it being a list-t of lists
01:16brainproxydang... I wish I knew how to express this in haskell, need to learn some more stuff
01:16imeredithsorry i cant express stuff in clojure
01:16brainproxyit's okay
01:17brainproxymy problem is I've been learning monads by studying source of algo.monads and protocol-monads and reading related tutorials
01:17imeredithin scala i would go ListT(Some(List(1,2,3))) which would have the type ListT[Option, Int]
01:17imeredithOption = Maybe in this case
01:17brainproxygotcha
01:18shachafIs someone expressing something in Haskell?
01:18imeredithbrainproxy: im biased, but i do think that static typing will help you learn this stuff heh
01:18imeredithnot that im an expert :(
01:18brainproxyimeredith: right, that's actually one of the nice things about jim duey's protocol monads
01:18brainproxyis they give you a way to reason about the types
01:19Grozhnabevshachaf, you hold no power over me here, you evil man.
01:19brainproxywhereas algo.monads is purely interface driven
01:19GrozhnabevFreedom shall carry on.
01:21imeredithbrainproxy: how do they give you a way to reason over types?
01:22brainproxybecause the bind and result are implemented as protocol methods
01:22brainproxyas well zero and plus
01:22imeredithbrainproxy: honestly the types thing is one of the main reasons i havent gotten into clojure more, i started down the monad track at the same time i was looking into clojure, and now i cant even imagine doing it without static typing
01:22shachafPlease stop changing your nick, Grozhnabev.
01:22shachafIt's just annoying. :-(
01:22brainproxyimeredith: see https://github.com/michaelsbradleyjr/protocol-monads/blob/examples/src/monads/core.clj
01:23Grozhnabevshachaf, "freedom annoys those who seek to oppress others" - Virgil, 0231 CE
01:23brainproxythat's my fork of duey's library, and I've been paying a lot of attention to type-related issues
01:23brainproxythere's even a "return type checker"
01:23brainproxywhich is purely optional
01:24brainproxymeant to help the developer reason more carefully about the steps in his monadic computations
01:24imeredithbrainproxy: so when does the type stuff kick in? when you load the code?
01:24brainproxyno, if you bind *throw-on-mismatch* to true
01:25brainproxythen if you have a mismatch between a bound monadic value and the return of a monadic function
01:25brainproxyyou get an exception
01:25imeredithat runtime?
01:25brainproxyyeah
01:25imeredithi guess you then rely on tests to pick up any problems?
01:25Sgeoimeredith, one of the notable things in Haskell that you can't do in Clojure due to the differnt type systems is polymorphism on the return type
01:26brainproxyimeredith: well, the checker is meant itself as a way to identity subtle errors during development
01:26SgeoThat is, can't really do a return :: (Monad m) => a -> m a
01:26imeredithbrainproxy: right
01:26imeredithSgeo: in clojure you cant?
01:26imeredithoh
01:26Sgeocore.algo.monads works around it by sort of supplying the information in a dynamically-scoped way
01:26imeredithi see
01:26SgeoI think protocol-monads does it by not actually supplying a return function, but not entirely sure
01:27brainproxySgeo: what do you mean?
01:27imeredithhow do you get by without return?
01:27Sgeobrainproxy, let's try a simpler example than return. Haskell has a value called maxBound
01:27SgeoIf used where an Int is expected, maxBound is the maximum Int value
01:28imeredithdo-result isnt return?
01:28SgeoIf used where a Char is expected, maxBound is the maximum Char
01:28Sgeoetc. etc.
01:28Sgeoimeredith, erm, it probably is, but ... hold on
01:28imeredithI take it MonadZero is Monoid too
01:29SgeoNote that do-result takes an argument that it ignores
01:29brainproxynote on the thing I just linked to on github, the transformer sections are still being adjusted w.r.t. to the type checker stuff I implemented
01:29brainproxyand so there are / are probably things wrong with them
01:29brainproxybut up to that section, everything is pretty solid
01:30SgeoThat argument is not needed in Haskell, because the type system effectively supplies that information
01:30imeredithbrainproxy: no reader monad? :(
01:30brainproxyimeredith: not yet
01:31imeredithKleisli/ReaderT is my favourite monad trnasformer atm - probably because its the only one i really understand
01:31imeredith:)
01:32SgeoProtocol monads keeps calling "monads" what I would term "monadic values" :(
01:32SgeoAlthough in protocol monads, you can get the information about the monad from a monadic value
01:32brainproxyright
01:32SgeoSo, I guess it sort of makes sense
01:33brainproxyso when you do (m/bind [1 2 3] (fn [x] ...))
01:33brainproxythe monad is the vector monad
01:33brainproxysince the monadic value is a vector
01:35brainproxyi've worked to flesh out the test suite a good bit
01:36brainproxywhich helped me to think about what everything actually does ... just that I've hit a wall w/ transformers since I don't have the knowledge to begin with know whether the lib is implementing them correctly
02:13brainproxySgeo: just realized I could simplify bind and plus for the ListTransformer, revealing an "inner plus" at work
02:13brainproxyhttps://github.com/michaelsbradleyjr/protocol-monads/blob/examples/src/monads/core.clj#L728
02:52muhooi suspect, as a complete gut hunch, that monads are only necessary to get around limitations created by haskell, i.e. its strict type checking. the same way that things like design patterns are necessary to get around limitations in oop.
02:56amalloymuhoo: nobody would bother porting them to clojure if that were true
03:01amalloymonads capture a common pattern that is useful in a lot of contexts. for example, clojure's for macro is a special-cased version of the list monad
03:02shachafThat's silly. "Monad" is just the name of a generic API that a lot of different types in Haskell expose.
03:02amalloyshachaf: sorry, which is silly?
03:02shachafYou can perfectly well write Haskell code without ever using this API, but it's a nice abstraction to recognize.
03:02shachaf"necessary to get around limitations created by haskell"
03:03Sgeobound-fn bothers me a little. What if I have a macro that expands into an fn form, but where I'm using the macro I'd rather it expand into bound-fn
03:03amalloywell, he's presumably thinking of IO, which is in some ways what he's claiming
03:03SgeoAm I just out of luck?
03:04shachafamalloy: The way IO is done in Haskell has nothing to do with type checking.
03:04tomojSgeo: bound-fn* ?
03:04shachafIt has everything to do with purity, and if you had a dynamically typed pure language, you could do the exact same thing.
03:04tomojnot sure what you mean
03:05Sgeotomoj, suppose I am using future
03:05SgeoBut I want the code inside my future block to see some dynamic variable
03:05SgeoHow do I make it use bound-fn or bound-fn* instead?
03:06amalloyshachaf: yes. i don't think it's unreasonable for him to think those are the same thing, right? the haskell type system prevents you from performing IO except in functions which deal in IO. type safety and purity seem pretty related to me
03:06tomojfutures already have binding conveyance
03:06shachafamalloy: That has nothing to do with the type system.
03:06shachafIt could work precisely the same way in a dynamically-typed language.
03:06shachafIO String isn't a "tagged" String which the type system keeps apart from String; it's a completely different kind of value.
03:07tomojI guess you might mean (future-call (bound-fn* f)) ? but that could only make sense if you called bound-fn* in some other dynamic scope
03:07tomojI think?
03:07shachaf00:05 <lambdabot> shachaf says: getLine :: IO String contains a String in the same way that /bin/ls contains a list of files
03:10Sgeo(println "Hello") could return a 0 argument function, which I then call to actually print "Hello"
03:11Sgeo((println "Hello")).. except I don't do that, rather, I build up a huge 0-argument function out of several pieces, and tell the compiler where it is
03:43raekSgeo: I think 'future' itself already acts as a 'bound-fn'
03:44bbloom,(source bound-fn)
03:44clojurebotSource not found
03:44SgeoSo, in my own code, if I want to output an fn based off code passed into the macro, I should likely use bound-fn?
03:44SgeoBlah
03:45bbloomworks locally
03:45bbloom,(doc bound-fn)
03:45clojurebot"([& fntail]); Returns a function defined by the given fntail, which will install the same bindings in effect as in the thread at the time bound-fn was called. This may be used to define a helper function which runs on a different thread, but needs the same bindings in place."
03:45bbloom,(doc bound-fn*)
03:45clojurebot"([f]); Returns a function, which will install the same bindings in effect as in the thread at the time bound-fn* was called and then call f with any given arguments. This may be used to define a helper function which runs on a different thread, but needs the same bindings in place."
03:45raekif you want the current value of some dynamics vars, perhaps you could just let them
03:45bbloom,(doc with-bindings)
03:45clojurebot"([binding-map & body]); Takes a map of Var/value pairs. Installs for the given Vars the associated values as thread-local bindings. The executes body. Pops the installed bindings after body was evaluated. Returns the value of body."
03:46tomojI don't think you can do that
03:46brainproxySgeo: okay, figured it out
03:46brainproxyhttps://gist.github.com/4050099
03:46tomojthe macro returns code, how are you going to get the bindings in there?
03:47brainproxywith a flag, the algo.monads version will implement the same op as protocol-monads
03:47tomojoh
03:47tomojI think I misunderstood you
03:47raek(defmacro foo [] `(let [x# (quote ~*x*), y# (quote ~*y*)] (defn ... x# ... y# ...)))
03:48raekI find dynamic vars hard to use
03:53bbloomraek: let is lexical, you want binding
03:53bbloom,(doc binding)
03:53clojurebot"([bindings & body]); binding => var-symbol init-expr Creates new bindings for the (already-existing) vars, with the supplied initial values, executes the exprs in an implicit do, then re-establishes the bindings that existed before. The new bindings are made in parallel (unlike let); all init-exprs are evaluated before the vars are bound to their new values."
05:23niclhow do I check the case of a character in a string?
05:24niclbasically, I would like to filter a string by case
05:34ajmccluskeynicl: I'm really new to clojure, so there's probably better ways, but my first thoughts would be something like (defn is-upper-case? [c] (= (clojure.string/upper-case c) c))
05:34niclajmccluskey: ah yes, don't know why I didn't think of that?!
05:35niclajmccluskey: thanks
05:35ajmccluskeynicl: no worries. Just glad I could help someone else for a change :)
05:42Rayneser
05:42Raynes&(Character/isUpperCase \x)
05:42lazybot⇒ false
05:42Raynes&(Character/isUpperCase \X)
05:42lazybot⇒ true
05:42Raynesnicl: ^
05:43ajmccluskeynicl: I think Raynes has a far better answer
05:44RaynesYour answer was clever.
05:45RaynesDon't feel bad because you haven't memorized the java standard library. :)
05:46niclRagnes: thanks!
05:46niclRaynes: ah sorry, got your name wrong.
05:46niclRaynes: thanks. Was thinking there would be something like that
05:47ajmccluskeyHaha, thanks. Using already working code is cleverer though :p.
05:50niclajmccluskey: I agree with Raynes though - you're solution was solid common sense
05:50niclwhich is to be applauded!
06:09daniel__is there an easy way of debugging what takes a long time to load when including a namespace i.e. (use 'backend.core) (REPL)
06:24ivandaniel__: reloading via tools.namespace or by using eval-defun repeatedly in Emacs with nrepl
06:24ivanthe general idea is to keep your JVM running
06:30daniel__thanks ivan
06:31daniel__im also having a problem serializing a protobuf-dump (byte array) to a string if anyone can help there?
06:31daniel__it works in some cases and not in others, i need a reliable way of going from protobuf-dump -> string
07:11ithildinHey, not sure who's around this early. I'm new to clojure (and linux, double whammy) and I'm wondering what my options are for writing something with a GUI
07:11ithildinIs there much there outside of Swing?
07:12ithildinIn case it wasn't too clear, that's GUI options for clojure in linux
07:19ChongLiithildin: you could write your GUI in opengl
07:20ChongLithat's a big undertaking though
07:20ithildinyeah, that seems like overkill to get some buttons and text on the screen
07:21ChongLiseesaw
07:21ChongLiit's a DSL built on swing
07:21ChongLihttps://github.com/daveray/seesaw
07:21ithildinI have seen seesaw when I've searched.
07:22ithildinso it would be nicer than normal Swing. but I've not had good experiences with swing
07:22ithildingranted, that was years and years ago
07:22ithildinmaybe things have gotten better?
07:22ChongLiprobably
07:22ChongLithe number of users of swing is pretty staggering
07:23ithildinYeah, that's the advantage. Coming from web development or iOS development (or Delphi or VisualWhatever) it seemed really annoying though
07:24scottjithildin: there's GUIFTW that supports SWT (eclipse)
07:24ChongLithe other advantage is the fact that clojure is a lisp
07:24ChongLiallowing library writers a lot of liberty in building nice DSLs with macros
07:24ithildinhmm I'll have to check that out as well scottj
07:25scottjithildin: https://github.com/santamon/GUIFTW it hasn't been updated in a year so unless you really don't want swing I'd go with seesaw which is very actively developed
07:25ithildinah, ok
07:26ithildinyeah, not a good sign when the readme says "It's in alpha stage" and then it hasn't been updated for a year
07:27ChongLiyeah it's always a shame when things are seemingly abandoned
07:28ithildinha, apparently I don't know the keyboard shortcuts in xchat
07:29daniel__How do i serialize a protobuf-dump when i have it as a byte array?
07:29daniel__I'm sending it as a string with ZeroMQ
07:34raekanother thing that happens a lot is that the readme says "It's in alpha stage" but the project is actively used by hundreds persons and is actively maintained
07:35raekpeople should bump up their versions from 0.x.0 to 1.0.0 more often
07:39rodnaph_raek: +1 if it's not some big commercial offering then "usable" should be 1.0
07:40rodnaph_(though i am guilty of not doing this too)
07:46daniel__i have a print inside a function that isnt printing to the repl
07:46daniel__maybe its because its in a try block, maybe because its within a while loop?
07:47raekdaniel__: is it in another thread?
07:48raektry and while shouldn't affect it
07:49rodnaph_is it part of some lazy evaluation that hasn't been realised?
07:49daniel__i dont think so https://gist.github.com/4050976
07:50daniel__line 7
07:55daniel__any ideas?
07:58daniel__just noticed my try block isnt properly formed
07:59andrewmcveighdaniel__: the "future" is spinning up another thread.
07:59andrewmcveighah, sorry... your println is not involved.
07:59daniel__yeah its outside the future
08:00daniel__the second deref should be cached as well shouldnt it?
08:01daniel__added a modification, this is how my try should be isnt it? https://gist.github.com/4050976
08:02andrewmcveighdaniel__: no, you had the try block right the first time.
08:02daniel__should it be (try expr (finally ..)
08:02clojurebotCool story bro.
08:03andrewmcveighyeah
08:03daniel__shouldnt it*
08:03raekdaniel__: println-str prints to a string and returns it. but it is not passed out from the while form
08:03raekdaniel__: try changing it to 'println'
08:03daniel__raek, i tried with print as well
08:03daniel__ok
08:04daniel__andrewmcveigh: in the first example, dont i have (try expr1 expr2 (finally .. ?
08:04raekor if it clojure data structures, use 'prn'
08:04raek,(doc while)
08:04clojurebot"([test & body]); Repeatedly executes body while test expression is true. Presumes some side-effect will cause test to become false/nil. Returns nil"
08:04daniel__im hoping its a string, but thats why i want to print it
08:04raekprintln-str does not print
08:05andrewmcveighdaniel__: yes, that's fine.
08:05raekit behaves as 'format', but adds a newline
08:05daniel__no but i mean, im not sure if its a clojure data structure or not, i want to verify what it is
08:05raekdaniel__: what happens if you use 'prn' instead of 'print-str'?
08:05daniel__let me just test it
08:06raekalso, do you call (server ..) directly in the repl?
08:06daniel__ok :) with println it works :D
08:06raekdaniel__: do you understand the difference?
08:06daniel__im sure i tried with (print before , shouldnt they be the same except for a (newline)
08:06raekyes
08:06daniel__raek, yeah i call it directly
08:07daniel__the difference between prn and print i dont know
08:07daniel__i will investigate
08:07raekbetween println and println-str
08:07daniel__oh, println-str prints to a string and then returns that string
08:07daniel__and the while wasnt returning anything
08:07raek,(pr '[foo "foo bar"])
08:07clojurebot[foo "foo bar"]
08:07raek,(print '[foo "foo bar"])
08:07clojurebot[foo foo bar]
08:08daniel__print prints to *out*
08:08raekdaniel__: exatctly
08:08daniel__im just puzzled why it didnt seem to work when i tried it with print before
08:09raekpr/prn/pr-str turns clojure data into strings so that they can be read again
08:09raekprint/println/str turns stuff into strings in random ways
08:09daniel__i see
08:11wingyhow can i check the path of the current file?
08:11daniel__*file* wingy
08:12daniel__includes the filename
08:12wingydaniel__: hmm Light Table returns nil
08:12daniel__its nil in the repl
08:12daniel__not sure how light table works
08:13wingynil in the repl as well?
08:14wingydamn i have a file opened but i dont know where its located
08:14raekwingy: a repl is not really in a file. (it is in a namespace though)
08:14raekoh, maybe this was a light table specific thing
08:14wingyraek: yes
08:21wingyused grep to find it instead
08:32darqHi. How can someone help me how to negate (membero 2 [1 2 3]) in core.logic? Instead of the goal to succed i want it to fail
08:36daniel__Does anyone have any advice for handing ctrl+c in the repl? I have a function running in a (while true .. which i sometimes want to break out of with ctrl+c .. the problem is, the next time i launch the function the repl crashes
08:36daniel__i need to make sure i execute the finally block on ctrl+c
09:03Neurus__Hi, I'm starting with Clojure.
09:04Neurus__whats the sharp (#) sign? (map #(+ 10 %) [ 1 3 5 7 ])
09:04Neurus__
09:05andrewmcveighNeurus__: #(+ 10 %) is shorthand for (fn [a] (+ 10 a))
09:06Bronsa,'#(+ 10 %)
09:06clojurebot(fn* [p1__27#] (+ 10 p1__27#))
09:06Neurus__tks andrewmcveigh , Tried googling but didn't find it :(
09:08andrewmcveighNeurus__: np. It's not easy googling for #
09:18Neurus__really enjoing 4clojure.com
09:22andrewmcveighNeurus__: yeah, it's a cool site.
09:58ambrosebsbrainproxy: you might be interested in my work in statically typing algo.monads https://github.com/frenchy64/typed-clojure/blob/master/test/typed/test/monads.clj#L278
09:58ambrosebsbrainproxy: I saw your protocol monads fork with type related debugging
11:22ebaxtIs it possible to add login hooks when using friend?
11:36hcumberdalecemerick ..?
11:37hcumberdaleI'm trying to get started with friend
11:37hcumberdaleI like to use compojure
11:38hcumberdaleBut I do not understand how the samples on https://github.com/cemerick/friend are connected to each other?
11:39cemerickhcumberdale: compojure
11:39cemerickgah
11:39hcumberdaleHi cemerick
11:39cemerickhcumberdale: compojure is mostly just some routing and helpers around ring handlers, so the ring-only examples are equally applicable to handlers produced by compojure fns and macros
11:40hcumberdaleAnd how does the "(friend/authenticate {:credential-fn " stuff work?
11:40cemerickhcumberdale: perhaps looking at the mock app used in friends tests would be helpful: https://github.com/cemerick/friend/blob/master/test/test_friend/mock_app.clj
11:40hcumberdaleDo I need friend/authenticate when I use friend/wrap-authorize ?
11:40cemerickwell, the map provided to friend/authenticate is configuration for the friend middleware
11:41cemerickYes
11:41hcumberdaleAhh, that's a bit disconnected to the compojure sample
11:41cemerickwell, it's not a compojure sample per se, just a sample focused on authorization that happens to use compojure routes
11:42hcumberdaleAhh! ;)
11:42hcumberdalecemerick I'm currently using sandbar
11:42hcumberdaleI forked it to fix the issue that it can not work with numbers as password
11:43hcumberdalecompojure/context & friend/wrap-authorize should be similar to a regex like "/user*" :user right?
11:45cemerickwrap-authorize (and everything else in friend) is entirely ignorant of whatever you're using for routing
11:45hcumberdaleDoes friend store the session in the default ring session store? So is it possible to stay with "(wrap-stateful-session {:store (session-store :sessions)})" ?
11:46cemerickYes, friend presumes the use of ring sessions.
11:49hcumberdaleSo "friend/authenticate" does not mean that there is actually authentication?
11:50hcumberdaleIt just means, it is there if authorize is used?
11:50hcumberdaleauthorize or authenticated ...?
11:51ebaxtcemerick: Is it possible to add login hooks when using friend?
11:52cemerickhcumberdale: I'm not clear on your question...
11:52cemerickebaxt: login hooks?
11:54hcumberdalefriend/authenticate does nothing if there is neither authorize or authenticated used?
11:56cemerickit establishes the scope within the app within which (a) a user may become authenticated, and (b) an authorization error will be automagically (i.e. by redirection to a login page, etc)
11:57ebaxtcemerick: a function called after login before redirecting. Or do I have to write a custom workflow?
11:57hcumberdaleSo friend/authenticate is like a "wrap-authentication-context"
11:57cemerickebaxt: or add the hook to your credential fn
11:57cemerickbbl
12:01hcumberdaleIs there a html-form example for interactive-form ?
12:20hcumberdaleclojure.lang.ArityException: Wrong number of args (2) passed to: friend$authenticate$fn
12:20hcumberdalemhhh
12:42SrPxCan you give help about clojurescript?
12:42SrPxI am getting 'cannot set property error of undefined' when trying to run the compiled js of a simple hello world.
12:54SrPx);
13:04winkhey, any clues how to get (let [x '(+ 2 3)] (+ 1 x)) work? (I know, taking off ' just works, but I happen to have a function call that I want to completely use as an argument, then call it)
13:06malcolmsparks(let [x '(+ 2 3)] (+ 1 (eval x))) ??
13:06lazybotmalcolmsparks: Uh, no. Why would you even ask?
13:07dspp,(let [x '(+ 2 3)] (+ 1 ~x))
13:07clojurebot#<IllegalStateException java.lang.IllegalStateException: Attempting to call unbound fn: #'clojure.core/unquote>
13:08dspp,(let [x '(+ 2 3)] (+ 1 (eval x)))
13:08clojurebot#<Exception java.lang.Exception: SANBOX DENIED>
13:09_tcawhat's the reason you want to use it as an argument also wink
13:10_tcadoes it need to be a list?
13:12wink_tca: well maybe it can be done more elegantly, but I basically have some wrapper function and I'm passing a block of (clojure.java.jdbc/update-or-insert-values) into it, so at the moment there's no db connection yet
13:19malcolmsparkswink, could you may be wrap your function in a delay, and then deref it once you have the db connection?
13:21malcolmsparksor just wrap it in a function?
13:22winkmalcolmsparks: thanks, I didn't know about delay, works perfectly
13:23Sgeo_Is there a delay* ?
13:23hcumberdalefriend :unauthorized-handler does not work ! ;(
13:24malcolmsparksI think that's an overblown solution, I'm regretting mentioning it because it should be possible to simply wrap in a function
13:24malcolmsparkseg.
13:25hcumberdalehttps://www.refheap.com/paste/6524
13:25malcolmsparks(let [x (fn [] (+ 2 3))] (+ 1 (x)))
13:25malcolmsparksie. so that evaluation is delayed until the db connection is in scope
13:25hcumberdalehttps://www.refheap.com/paste/6525
13:26malcolmsparksdelays have extra semantics (memoization) that you don't need
13:27malcolmsparksbut delays are useful to know about - I use them for somewhat expensive operations (eg. looking up a static value in a database that won't change)
13:27malcolmsparkswhere I don't want to pay for the database query until the value is actually needed
13:27malcolmsparksand when I know it won't change so don't want to visit the database each time the value is required
13:28winkhm, yeah
13:28winkmalcolmsparks: thanks, used fn now :)
13:29malcolmsparksis this the right channel to ask core.logic questions? or is there a dedicated irc channel for that
13:29winkI still don't really get why in one direction it's like this: (1 2 3) => cannot execute function named "1", but on the other hand I can't call something like '(1 2 3)
13:30malcolmsparks'(1 2 3) is a list (data) because you're quoting it
13:30malcolmsparks(1 2 3) is the function '1' with two arguments (2 and 3)
13:31malcolmsparkssince '1' isn't a function, you get an error
13:31winkyes
13:31malcolmsparksas soon as you present the special form (a ...) to clojure it gets excited and tries to apply it immediately
13:32malcolmsparksbtw. 'apply' means run the function named in the first item of the list with the arguments in the rest of the list
13:33winkwait, that works?
13:36winkmalcolmsparks: I'm not sure how that would work besides: (def x ["str" "a" "b"]) (apply (eval(read-string (first x))) x)
13:41malcolmsparkswink, I'm not sure what you're asking
13:41malcolmsparkscan you rephrase?
13:42winkmalcolmsparks: I'm not asking this time, I'm questioning " 'apply' means run the function named in the first item of the list with the arguments in the rest of the list"
13:44SrPxAnyone has an idea why clojurescript is not working here ? http://stackoverflow.com/questions/13324490/getting-cannot-set-property-error-of-undefined-when-trying-to-run-the-js-outp#comment18177550_13324490
13:45malcolmsparksHere's a list: (1 2 3) - but if it isn't quoted Lisp sees this as a 'special form' and evaluates it, that's all I meant. The rule for evaluation is to consider the first item of the list (a) to be the function, and it is given b and c as arguments.
13:45malcolmsparks(a b c)
13:46winkyes of course, but core/apply takes 2 arguments. not one, even if it's a list. or am I mistaken?
13:50malcolmsparksah, I see the confusion, I didn't mean core/apply when I used the word 'apply'
13:50tomojSrPx: maybe try putting [org.clojure/clojurescript "0.0-1535"] in your dependencies
13:50malcolmsparksclojure.core/apply takes 2 args yes, the first is the function, the second is the list of args
13:50tomojSrPx: and run lein cljsbuild clean I guess..
13:51tomojkinda strange to me that cljsbuild magically includes a cljs dependency
13:52SrPxtomoj: :dependencies [[org.clojure/clojurescript "0.0-1535"]] , with the double [[]] right
13:52tomojyeah
13:53SrPxtomoj: thanks but nothing. ):
13:53tomojI know some nodejs problems were fixed recently, can't remember if your error was one of them
13:53SrPxJust downloaded it today ;/
13:54SrPxWait actually, I'm not sure. Can I redownload the :plugins [[lein-cljsbuild "0.2.9"]] ?
13:54tomojno need
13:55SrPxHmm. Perhaps it's node.js's fault?
13:57SrPxWow it workeeeed.
13:57SrPxCan't believe (: just ran "lein deps"
13:58SrPxOh and lein cljsbuild clean as you said
13:58SrPxprobably was that
13:58tomojhuh..
13:58tomojI tried it and got a similar but different error
13:58SrPxWhat?
13:58clojurebotWhat is @
13:58SrPxWhich*
13:59tomojuncommenting `:optimizations :simple` made it almost work
13:59tomojwhich is odd - I thought the cljs compiler defaulted to :simple for node
14:00tomojbut then I also needed https://www.refheap.com/paste/2cdbc41ebdb9771ae45bfaad7
14:01tomojto avoid a different error
14:01SrPx'almost work'?
14:02tomojwell 'almost work' in that unless I set! *main-cli-fn*, I still get an error
14:02tomojwhich is expected
14:03tomojstrange though, even if cljsbuild told the compiler to use :whitespace, I'd thought it would still use :simple
14:04SrPxhmm
14:04SrPx(:
14:05tomojI'm surprised (js/console.log "hello") works - I always do (.log js/console "hello")
14:11amalloySgeo: delay*? wouldn't that just be fn?
14:13amalloyor maybe identity, since i assume delay* would be passed a function rather than an expression body
14:14tomojmemoize?
14:15amalloymaybe
14:16mudgejust curious what people's favorite clojure books are
14:16tomojI guess memoize might still execute the function more than once?
14:17tomoj&(let [f (memoize (fn [] (do (println "called!") 42)))] (future (f)) (future (f)))
14:17lazybotjava.lang.SecurityException: You tripped the alarm! future-call is bad!
14:19tomojdelay's mechanism for ensuring the fn is only called once seems magic
14:20tomojoh, guess not. deref is synchronized
14:22SrPxWhy it wouldn't work?
14:23SrPxI don't understand clojruescript's approach. 20k lines? Why not just compile to readable javascript? Is it impossible? Or because this way it is optimized?
14:33amalloytomoj: yeah, memoize can call twice. it's a fun little exercise to write a version that never does (but it comes out to be substantially slower than memoize, so presumably the tradeoff was made on purpose)
14:36hcumberdaleSrPx what are you doing with clojurescript?
14:36hcumberdaleHave not tried it,...
14:37SrPxAt the moment nothing special, just learning how it works
14:37SrPxI'm trying to get parenscript to work now , to compare them
14:38Drakesonis there a straighforward bridge between a dialect of scheme and javascript?
14:40hcumberdaleSrPx what is a possible usecase for clojurescript?
14:40hcumberdalereplace jquery? ;)
14:45cmnsure, or the power goes out, or your cat stays too long on your laptop's power button
14:45cmnsorry, wrong window
14:49SrPxhcumberdale: program things ?
14:49SrPxhcumberdale: not replace jquery, you'll probably use it with clojurescript
14:50SrPxhcumberdale: clojurescript is just a language that compiles to javascript and people using it are probably those who don't like javascript's syntax and stuff and prefer to code in a better language
14:51SrPxDrakeson: that's what I was wondering too
14:51SrPxDrakeson: if you find something please tell me, but it doesn't seem to be the case
15:03jamiihttp://i.imgur.com/6g8Fh.jpg
15:03jamiiClearly working hard here...
15:07tomojamalloy: shit
15:07tomojI used memoize wrongly
15:07amalloyeh?
15:07tomojI knew it felt fishy at the time
15:08tomoj(fn id-factory [part] (memoize (fn [& args] (datomic.api/tempid part))))
15:09tomojonly one thread touches that right now, but that could've been hell later..
15:11tomojI wonder thought whether that is a dangerous use of memoize or a bad idea generally
15:46zackzackzackIf I want to shush log4j when I am running lein tests, where should I put the log4.properties file?
15:48darqHi. (run 3 [q] (without [:a :b :c] [:a] q)) => (:b :c) ? is there a way in core.logic to get ([:b :c]) so that the result is in a vector
15:52dakronezackzackzack: you should be able to put it anywhere in your resource path, you can either set :resource-paths in lein2, or put it in the 'test' folder so it'll only take effect while testing
15:54zackzackzackdakrone: Haha! Into the test folder it goes
16:13amalloy(list (vec (run ...)))
16:14tomoj&(assoc {} 1 2 3)
16:14lazybot⇒ {3 nil, 1 2}
16:14amalloypffft
16:16raekhrm, I have a problem with aleph (or gloss, more specifically). when I try to read lines from a socket using :delimiers ["\r\n" "\n"], lines don't "get through" until the next line is sent...
16:16raekwhen I use :delimiers ["\n"] it works correctly
16:17amalloyraek: i assume you're spelling delimiters right in your real code?
16:19tomojnot being able to use your own libraries in a transaction fn seems cumbersome. I'm tempted to try to macroexpand on the peer that defines a fn, but that seems.. bad
16:19raekamalloy: yeah
16:22amalloyraek: https://github.com/ztellman/gloss/blob/0.2.2/src/gloss/data/bytes/delimited.clj#L48 looks like it might be relevant. i can't see the details, obviously, but it looks like it might be saying "the largest delimiter i might find is size 2, therefore i need two bytes to start looking for a delimiter"
17:04tomojwarning, if you accidentally say :db.type/ref when you mean :db.type/long, datomic will happily oblige
17:05CubicWhy does loop need to be a special form? Couldn't it have been a macro that evaluates to a fn?
17:07amalloyjust performance. let could be a macro too, but even scheme isn't that wasteful
17:11augustlhow do I create a multimethod that dispatches on whether an arg is a string or a function?
17:12augustl(class (fn [])) is "user$eval952$fn__953", not sure how to write a defmethod that dispatches on that..
17:14CubicDispatch on keywords :string and :function, and then just check in the dispatch function for string? or function?
17:14Cubic,(doc string?)
17:15clojurebot"([x]); Return true if x is a String"
17:15Cubic,(doc fn?)
17:15clojurebot"([x]); Returns true if x implements Fn, i.e. is an object created via fn."
17:15augustlhmm
17:15amalloyaugustl: IFn
17:19Cubicamalloy: I guess that depends on whether he wants ifn? or fn?
17:19amalloysure
17:21augustlended up just doing an if/else ;)
17:22augustlgetting "signing failed: No secret key" when trying to deploy to clojars with leiningen, is the process of "lein deploy clojars" documented somewhere?
17:22amalloyhttp://www.antiifcampaign.com/ always makes me laugh
17:23tomojuse objects to build a code!
17:24bosievim (vimclojure) question: closing the vimclojure window with ^c screws with it as i can't seem to reopen it. it always throws a "cannot find my window" exception
17:28bosienvm, found it
17:40yediis chris granger still streaming?
17:53muhoomudge: i like clojurebook.com, if you're coming from a web-dev, non-fp background
17:54mudgemuhoo: does it teach the fp way to program?
17:55muhoomudge: it's more "here's how to use clojure (and fp) to Do Stuff".
17:55mudgemuhoo: cool
17:55muhoovery practical. it certainly does use idiomatic, clojure/fp ways of doing stuff, but the focus is on practical tasks
17:56RaynesFirst of all, monads are like burritos.
17:56RaynesYou'll be fine now.
17:56muhooRaynes: the morning after, not so much.
17:57mudge*farts*
17:58muhooRaynes: i haven't messed with haskell much, but monads smell a bit to me like something that had to be invented to get around haskell's BDSM type system, much the way design patterns had to be invented to get around limitations in OOP
17:59Raynesmuhoo: Get out of my internet.
17:59muhoohehehe
18:00amalloymuhoo: you made that statement yesterday, but i don't think you listened to or noticed any of the counterarguments
18:00muhoodon't think i saw them, actually. must scroll back.
18:01amalloyit's like saying that parens had to be invented to fit the ludicrous requirements imposed on lisp by macros
18:01Raynesmuhoo: Monads weren't actually created for Haskell, right? It was Opal.
18:01amalloyRaynes: for mathematicians first :P
18:02RaynesYeah, but mathematical monads are different, right?
18:02amalloynaw
18:02RaynesWikipedia says they "are not identical"
18:02amalloywell. i'm not an expert on category theory by any means
18:03Raynesmuhoo: Why do you hate the Haskells?
18:04RaynesIt's so much fun.
18:04RaynesI've been writing random crap in it just for the sake of it.
18:04muhooi don't. i'm sure i'll learn it at some point.
18:04muhooamalloy: thanks, the discussion happened after i was AFK, and looks very informative.
18:38augustlshould I ever do the transient/persistent thing when building collections without first making sure it's actually a performance reason to do it in my system? :)
19:06Cubicaugustl: what thing?
19:48CubicAwesome. Just spend two hours fixing a bug that happened because I thought that '(start)==(list start) for some reason (I kinda knew it wasn't, but that slipped past me right now)
19:55hughfdjacksonCubic: painful experiences make for better programmers :D
19:55hughfdjacksonhopefully..
19:57CubicI guess. Made me realize that I could use a vector just as well as a stack as a list.
21:02XPheriorSo I've been messing around with this concept of seeding a database without knowing the concrete types. Does this make sense to anyone else? http://michaeldrogalis.github.com/dibble/
21:12fluke777Hi everybody. I have a problem with proxy. I am using this code https://gist.github.com/4053357 to call a visitor which create AST as it goes. For testing purposes I just change the state once I enter the method visitMetricExpr. What baffles me is that when I run it in REPL (nrepl) it always return 3. When I package to a jar use reply to run the exact same code it returns one. I am kinda lost not really sure where to look. Can anyone take a look and maybe
21:12fluke777something completely stupid that I am doing?
22:51augustlany suggestions for option parse libraries other than clojopts? It seems to not handle operands at all
22:52augustlhmm, seems that the actual problem is that it doesn't support --foo 123, only --foo=123
22:53amalloyaugustl: really? it uses the java port of gnu getopt, which i thought accepted both
22:53amalloyi wrote clojopts but haven't touched it in over a year; there's a contrib lib that's probably more maintained
22:53augustla http://pubs.opengroup.org/onlinepubs/9699919799/ compliant jvm option parser would be nice :)
22:54augustlI not sure if gnu getopt is posix compliant
22:54augustlthe biggest problem is ambiguities really, -bar can mean -b -a -r and -b=ar
22:54augustland so on
22:55augustlalready wrote one, but for Node.js ;) https://github.com/busterjs/posix-argv-parser
22:55amalloyi don't think that's an ambiguity; you just have to define whether b accepts a value, and whether a/r are valid options, after which there's a nonambiguous parse
22:56augustlindeed, as long as it's possible to define it beforehand it should be all good
22:57augustlhere's my code, https://www.refheap.com/paste/6533, running that with "lein run --port 4224" prints {:clojopts/more (4224), :port nil} for `opts`
22:57augustlbut --port=4224 works
22:57augustlinterestingly enough -p4224 doesn't, even though the help output says it does :)
22:58augustluh nvm I did --p4224
23:00augustlhttp://commons.apache.org/cli/ looks pretty good
23:00amalloyaugustl: if you say the arg's value is optional, then --port 4224 isn't attaching the value
23:01amalloyif you switch from optional-arg to with-arg, i think those both parse the same
23:02amalloyafaict that's how getopt in c behaves also, if you say the arg is optional
23:05augustlamalloy: ah, I see
23:12augustlthe apache commons lib worked just like I wanted :) https://www.refheap.com/paste/6534
23:16brainproxylooking to switch some deftype things over to defrecord, but upon doing so I'm getting exceptions in the REPL re: print-method
23:16brainproxythat is, as a multi-method it's not sure which dispatch to prefer
23:17brainproxywhat I'd really like is to have the same print-method impl that deftype gives me
23:20devthwhen using :keys in a fn's args list, can you do additional destructuring? e.g.: (defn f [{:keys [a]}] a), then i call: (f {a: [1 2 3]}) and i only care about 3.
23:21devthseems like i'd have to do another separate round of destructuring in a let form - just making sure i'm not missing something.
23:22amalloyno. just don't use the :keys shortcut
23:23amalloy(let [{[_ _ x] :a} m] ...)
23:26amalloyaugustl: did that fix your problem?
23:27devthamalloy: ah, hadn't thought of that. ty
23:29augustlamalloy: yup!
23:30jamiiTurns out you can just wing emacs list - https://gist.github.com/4053713
23:30jamiiSeems to work