#clojure logs

2015-09-23

00:00rritochTEttinger: My project is a fork of armed bear common lisp, with the key difference that mine is 100% maven compatible (The developers of ABCL specifically refuse to support using ABCL from maven), also my fork passes all of the ansi tests.
00:00rritochTEttinger: ABCL isn't compatible with clojure at all really since it can't be included as a dependency in it's current state.
00:01TEttingerI don't think clojure has a huge amount of effort put into interop relative to other important language features. the key features were all present in 1.0 for java interop except for maybe a few for gen-class things?
00:01TEttingerI think the STM was probably much more challenging than playing nicely with java
00:02rritochTEttinger: As for the multithreadding issue, there's a few reasons. It inherited ABCL's circular dependencies which outnumber class files 10x1 at least, and the massive use of static finals for things that should be "interned".
00:03arrubinTEttinger: For a lot of development, it can make a huge difference though. Having good database drivers through JDBC for instance.
00:03TEttingerwhat's the problem with static finals? I'm a bit unclear since I don't know a better way to imitate a constant in java
00:04rritochTEttinger: It's is an architectural flaw with the ABCL codebase that it has placed most of it's symbols as static finals so they can't be utilized in a thread-local context.
00:05rritochTEttinger: It isn't a problem with the java language, and it is something that can technically be corrected. The other developer on the jrelisp project I believe is working on that issue. Along with CLI support.
00:06rritochErr, maybe CLI isn't the correct term, he's working on .NET support. I don't recall the name of the interpreter.
00:07TEttingerCLR is a common term but not a synonym for CLI. CLR is common language runtime
00:07TEttingernot sure what CLI stands for in .NET context
00:08rritochaconz2: Either way, if your trying to make a big splash I can suggest a few open source projects that you could probably produce with the aid of jrelisp & clojure.
00:08rritochTEttinger: Sorry, I think your right, I think it was CLR. I'm really not a big .NET fan.
00:10rritochaconz2: Notably are opencyg, which I believe has it's own native lisp implementation, and common-lisp-stat. Neither of those projects will run on a JVM (yet) and could both make headlines if ported to clojure/JVM.
00:11TEttingerit really is remarkable to me what the MS team managed to do with C# relative to Java. generics without boxing and a really well-thought-out collection API that uses a similar concept to clojure's seq abstraction (almost all collection methods operate on the IEnumerable interface and return one as well), technically more powerful first-class functions than java's lambdas (since lambdas aren't closures)...
00:12TEttingerthe open source version of most of .NET appears to include immutable data structures in the core lib
00:12TEttingerincluding an equivalent to transients
00:16rritochaconz2: Small correction, it isnt' opencyg, it's opencyc (https://en.wikipedia.org/wiki/Cyc). Porting Cyc to clojure brings about 50% of AI technology to clojure, and porting common-lisp-state brings advanced statistical analysis to clojure. I've considered both projects but I'm not going to touch either project without funding since I neither work in the AI field or statistical analysis.
00:19TEttingera direct port might not be ideal for the common-lisp-state one, I would say. the approaches to pure/lazy functional code are different between the original language and in clojure, and statistics stuff seems like a perfect match for immutable/persistent data since you never want to change the data you're analyzing in the process of analyzing it
00:21TEttingerif you can do what it does in broad capability terms, that would be huge. even a small library that does statistics work that is challenging now would be nice
01:43rritochDoes anyone know how to fix vinyasa? "Failed: Java files did not properly compile [{java source directory}]
01:47rritochLooks like a known issue (https://github.com/zcaudate/vinyasa/issues/4)
01:55rritochI re-reported the issue as it's a slightly different, but related problem. https://github.com/zcaudate/vinyasa/issues/20
03:14neurostormi have som keyvals in a hash-map and would like to use it in a let... like (def b {:x 1 :y 2}) (let [b] (+ x y)) , can it be done?
03:15justin_smithneurostorm: no
03:16neurostormah, come on... a macro perhaps?
03:17justin_smithneurostorm: if the map is known at compile time, you could make that macro
03:17neurostormi just want to dynamicly set some bindings... they are not known at compile time.
03:17justin_smithmacros only run at compile time
03:18justin_smithand I'm not alone in the opinion that magical bindings that are inaccessible while reading the code and only known at runtime lead to terrible unreadable code
03:18justin_smith(which is why nobody made this functionality yet)
03:18neurostormyeah, i just wanted easy access to some data retuned from a request.
03:19justin_smiththen pass the data in?
03:19neurostormand would like a generic mehtod to do that.
03:19justin_smithyou know about destructuring, right?
03:20neurostormi do, and its nice, but for 10 vars 2 leves inside a map, it does not look nice.
03:20justin_smithwith destructuring you can bind the keys you expect to find to local values. That totally works. But how would you even write code that does anything meaningful with bindings you don't even know the names for until runtime?
03:21justin_smithyou are allowed to spread the left hand side of a let binding over multiple lines, I do it all the time
03:22neurostormi know the names, but would like to avoid have to do the deconstruction. And i would like to use this different placeres with different names.
03:22justin_smithneurostorm: best of luck
03:22neurostormjusk asking...
03:23justin_smithI'm doing my best to explain why this feature doesn't exist. If you don't agree with the rationale, feel free to try it I guess.
03:24justin_smiththe general clojure approach is that bindings should be explicit and clear, and any time you refer to some binding, it should be simple to see where that binding came from. It's something I personally like a lot about mainstream clojure code. But of course there are ways to break these rules if you really want.
03:25rritochneurostorm: See: https://clojuredocs.org/clojure.core/binding
03:26justin_smithrritoch: that has nothing to do with what he wants. He wants the values to be magically bound without him having to type out their names (getting them automatically from a map only known at runtime).
03:26justin_smithbinding has all the same limitations that let does
03:27neurostormi understand your argument, and maybe in general its a bad ide. Still i would have thought it was possible to set some binding in a more dymanic manner. I just want a closure or let-over-lambda make some keyvals from a hash-map accessible in the scope.
03:27justin_smithyou can do it, but it doesn't exist yet
03:27justin_smithof course it is possible, it would probably involve a macro plus eval
03:29rritochjustin_smith: Oh, ok. I see the problem.
03:31neurostormok... well, better ditch that idear. thanks for the input.
03:32rritochneurostorm: Sure, you can do it, but your going to have errors constantly, especially if you use variables not defined in the provided map.
03:33rritochneuostorm: Basically you just create a function that accepts a map and a form, you wrap the form in a function definition & let statement populated with the key/value pairs.
03:35rritochneurostorm: I'd think it would be something like... (fn [myvars myform] (do #_manipulate form #_(eval form which returns a function) #_( call function with values from myvars to populate let values)
03:36rritochneorostorm: You could make a macro which would generate that code so your final product is cleaner. It is going to be very error prone because your call to eval will fail if undefined variables (keys) are used.
03:37rritochneurostorm: If you can think it up, clojure can find a way to do it, but just because you can do something, doesn't mean you should.
03:38neurostormyes, i can see your point, will be difficult to use without make much more error handling.
03:38justin_smithwhich is fixed by explicitly attempting to bind those keys, which brings us back to how you would do it with destructuring anyway
03:46rritochneurostorm: If your going to use that psudocode, you should also switch the order of the arguments from myvars myform to myform myvars and take a partial of it since your form isn't going to change on each call.
07:43ashwink005can anyone suggest a good source to learn how to write deftests?
07:43ashwink005i.e. compojure project testing
08:08sandbagsamalloy_: ping .. wanted to ask you about (apply map list (partition xs))
08:32trissgosh I'm sure I'm finding searching the JIRA way harder than it should be....
08:33trissI'm told a ticket exists for adding documentation strings/error messages to :pre and :post conditions exists but I really can't find it.
08:34trissdoes anyone know where it is?
08:44puredangerI looked and I don't see it
08:46puredangerI I must be misremembering
08:48trissah thanks v much puredanger... good to know I'm not gong blind!
09:13the-kennyAnyone noticed issues with leiningen and clojure.test/use-fixtures? It seems that my :once fixture is run in parallel (or nested).
09:14the-kennyBackground: I start a webserver for an api in there. When running the tests with C-c , in Emacs, everything works fine. When I run `lein test', I get an AddressAlreadyInUseError and my logging says the server is started once, then stopped immediately, without any tests in-between
09:19the-kennyOkay, it works fine after updating Clojure from 1.6 to 1.7
09:26jeremyheilerthe-kenny: are you sure you didn't have any lingering processes?
09:26the-kennyjeremyheiler: It might have been that, yeah. That wouldn't explain why it worked in the REPL though.
09:26the-kennyI just wrote some code to randomize the port the server listens on for every test. That should prevent that in the future.
09:27jeremyheileroccasionally i'll find that i have 10 nrepl servers running because they were never closed by emacs
09:27jeremyheileror whatever should have closed them
09:28noncomwhat is the most idiomatic way to get all dates for the current week with clj-time?
09:38bjajeremyheiler: that's more realistic anyway (randomized ports). if you had a service that needed to both bind a port and have multiple copies listening on the same ip, you'd need to either assign those ip:port combinations ahead of time or use some sort of registry (I use zookeeper for an nrepl registry)
09:50bjanoncom, I feel like you'd have to define current week
09:50bjado you mean the next 7 days (inclusive of today)
09:50bjado you mean this Sunday through Saturday cycle? Monday through Sunday? Thursday through Wednesday?
09:51bjain any event, I'd imagine the answer involves either take or take-while and clj-time.periodic/periodic-seq
09:52eglibja: yes probably, but how do you get the start of the week?
09:52bjahow do you define the start of the week?
09:52mungojellyyeah weeks start differently in different cultures
09:52eglilet's assume monday :-)
09:53egliif I knew the current weekday I could (ago date ,,,)
09:54jeremyheilerbja: sure, wasn't arguing against randomized ports :-)
10:00bja(monday? (first (take 7 (periodic-seq (ago (-> (today) day-of-week dec days)) (days 1)))))
10:02bja(require '[clj-time.core :refer [ago days day-of-week today]] '[clj-time.periodic :refer [periodic-seq]] '[clj-time.predicates :refer [monday?]])
10:03bjathat code probably has a bug if the day is monday
10:03bjaactually, (days 0) works
10:03bjawell, works the way I want it to
10:03eglibja: is there a day-of-week function? I can't find it on http://clj-time.github.io/clj-time/doc/index.html
10:03bjait's part of the DateTime protocol
10:04bjahttp://clj-time.github.io/clj-time/doc/clj-time.core.html#var-DateTimeProtocol
10:04egliah, you're right
10:04eglidid a search on http://clj-time.github.io/clj-time/doc/index.html where it wasn't listed
10:04bjathe latest docs are for 0.8 though
10:04bjaI think clj-time has newer versions
10:09mungojellyadd the current day, stop if it's monday, go back and add days until one of them is monday, add days to the end until it makes seven
10:12noncombja: egli: mungojelly: so, take (now), find current day-of-the-week, lapse back to, say, monday, that's the start. add 7 - that's the end.. correct? that is straightforward but i thought maybe there is a simpler way
10:12bjanoncom, my code works
10:12bjajust remove the monday? first functions where I prove the first day is a monday
10:13bjait returns a seq, starting with monday and containing datetimes for the entire week
10:13bjathere is a function called ago which does the legwork for you
10:13bjaso you just need to find monday, and then tell periodic seq to start with monday, and give you datetimes in day increments
10:13noncombja: ah, i see, spotted your code. i missed that while reading the char
10:13noncom*chat
10:13noncomvery cool!
10:14bjaperiodic-seq is awesome
10:14troydmis it possible to create alist in clojure? or even a pair?
10:14bjatroydm: what do you mean?
10:14bja'(1 2) is a list
10:15bjaif you were inclined to do so, you could have a reader dispatch on some new mutable list and have syntax for it
10:19csd_How might I translate the CL macro (defmacro macro (&rest fn-names) '(progn ,(if fn-names '',fn-names '*fns*)))? The double syntax quote has me confused
10:22troydmbja: I mean something like (cons 1 2) in Scheme
10:23bjano, if you want something like that define it and then add syntax for it via reader dispatch
10:25troydmic
10:26bjaby define it, I mean create the data type and functions to manipulate it, and then use http://clojure.org/reader#toc4
10:26jeremyheilercsd_: which are backticks and which are quotes? my editor doesn't differentiate them
10:26jeremyheilermy irc client*
10:26jeremyheilerthey all look like single quotes to me
10:26bja^^^ what jeremyheiler said
10:27csd_jeremyheiler: all are single quotes
10:27jeremyheilercsd_: that doesn't compile
10:27jeremyheilerso, my approach is to macroexpand the cl code to see the output
10:28csd_hm maybe the book i'm looking at has a transcription error
10:28jeremyheilerthe quote in front of progn is probably a backtick
10:29jeremyheilerbecause of the , in front of if
10:29csd_see fn profile at the bottom of the page 290 https://books.google.com/books?id=eH6jBQAAQBAJ&lpg=PA913&dq=paradigms%20in%20artificial&pg=PA290#v=onepage&q=profile1&f=false
10:30csd_sorry, unprofile
10:30jeremyheilerit doesn't let me see page 290
10:30jeremyheilerwait, nvm, it does
10:32jeremyheilercsd_ ok, i got it. the quote in front of progn needs to be a backtick `, not a single quote '
10:32jeremyheileralso, the two quotes in front of ,fnames need to be backticks, not single quotes
10:32jeremyheilerthat at least compiles...
10:35csd_i'd think you can just directly translate that backtick to clojure's backtick / single quote, right?
10:35jeremyheileri think so
10:35jeremyheilerand cl , is clj ~
10:35csd_yeah
10:35jeremyheilerit's hard to tell which is a backtick and which is a quote in that book
10:35jeremyheileri have a copy at home, but i'm not at home, so i can verify :-/
10:36csd_but if fn-names is a list, i can see why '~ makes sense, but not why the extra '
10:37csd_maybe because without it, the unquote at the beginning of `if` will unquote it too>
10:37jeremyheilerin clojure, you may want to quote a symbol before syntax quoting it so that it doesn't become namespace-qualified
10:39csd_why syntax-quote at all? why not just use only regular quote
10:39jeremyheiler,'bar
10:39clojurebotbar
10:39jeremyheiler,`bar
10:39clojurebotsandbox/bar
10:40jeremyheilersee how the syntax quote implies a namespace
10:40csd_yeah
10:41csd_,''bar
10:41clojurebot(quote bar)
10:41csd_,`'bar
10:41clojurebot(quote sandbox/bar)
10:41csd_,'`bar
10:41clojurebot(quote sandbox/bar)
10:42TMA,``bar
10:42clojurebot(quote sandbox/bar)
10:42csd_i guess i should probably just install a CL compiler and see what this actually expands to and compare that with what happens in clojure
10:44jeremyheilercsd_: i consulted the resident cl'er who sits next to me and it is bakctick, quote
10:44jeremyheiler,`'~'(foo bar baz)
10:44clojurebot(quote (foo bar baz))
10:45jeremyheiler,`~'(foo bar baz)
10:45clojurebot(foo bar baz)
10:45TMA,`quote
10:45clojurebotquote
10:45sobelhere i sit at my javajob with a data integration engineer (sql lackey) title. contemplating whether i might need to find me a proper clojob.
10:46TMAoh, so quote symbol is a special case
10:46jeremyheilercsd_: so this code is evaluating fn-names once, and then quoting it so the list of fn-names isn't called as a function.
10:46jeremyheiler(defmacro macro (&rest fn-names) `(progn ,(if fn-names `',fn-names '*fns*)))
10:46jeremyheiler(macro foo bar baz) ;=> (PROGN '(FOO BAR BAZ))
10:47csd_ohh
10:48csd_right and so if there wasnt the unquote before the `if` sexp then that extra backtick wouldnt have been necessary
10:49jeremyheiler,(do (defmacro macro [& fn-names] `(do ~(if fn-names `'~fn-names '*fns*))) (macro foo bar baz))
10:49clojurebot(foo bar baz)
10:50jeremyheiler,(do (defmacro macro [& fn-names] `(do ~(if fn-names `'~fn-names '*fns*))) (macroexpand '(macro foo bar baz)))
10:50clojurebot(do (quote (foo bar baz)))
10:51jeremyheilercsd_: correct, but then the if would be the resulting expansion
10:53csd_yeah
10:53csd_i'd imagine that as you work more with macros that this all becomes idiomatic eventually
10:54jeremyheileryeah, but then you try to write a macro that expands into a macro
10:55jeremyheilerif you successfully do it, you become a wizard
10:55csd_good luck maintaining it too :-P
10:55jeremyheilerlol
10:55csd_thanks for explaining this all to me, very helpful
10:55jeremyheilersur!
10:55jeremyheilersure*
12:55codefingerPupeno: here's another option that might work well for you case (deploy local artifacts) https://github.com/heroku/lein-heroku
12:59jeremyheilerthat looks nice. i wasn't a fan of the git approach for clojure/java
13:00codefingerjeremyheiler: what was the rub? i agree in some cases -- especially since JVM artifacts so portable
13:01jeremyheilerhaving a lot of stuff in my git repos that don't need to be sent to heroku
13:01jeremyheilerespecially when my build pipline is designed for deploying a jar
13:02codefingerjeremyheiler: yea, i'm not a fan of checking things into Git that don't need to be there. So lein-heroku is perfect for uberjars
13:32pseudonymousHey - can anyone explain why this explodes (kicker: it never does when testing in a repl) https://gist.github.com/anonymous/3e9f961067277e71cee0
13:34amalloyuh, because you are referring to stuff in cider.nrepl?
13:35amalloyif-require doesn't really work at all
13:35amalloyhm, actually if-require looks okayish
13:36amalloybut you have to call it at the top level to be effective, not inside a function
13:36pseudonymousI hope so, I literally spent 2 hours baby-stepping through its writing.
13:36pseudonymousOh, and then capture the results in a def ? )
13:36amalloyactually as written i'm not sure it even works at the top level, because you're using a let
13:37amalloydoing requires outside of ns is pretty tricky
13:39pseudonymousamalloy: Yea, I'm coming to see that :(
13:40justin_smithpseudonymous: the only time I have successfully used require at runtime, is if I also use resolve instead of referring to the symbols required directly
13:40justin_smithpseudonymous: this is helpful for avoiding needing to do AOT for example
13:42justin_smithpseudonymous: the problem is that clojure won't compile code that calls cider.nrepl unless cider.nrepl is available at compile time. Your macro needs to be a bit more magical than it is.
13:42justin_smithor you need to use resolve
13:42justin_smith(perhaps even a combination of these things - the macro could use resolve!)
13:44pseudonymousjustin_smith: not quite sure I follow. Just tested something from another library (which I already use in other files) - that worked. If I'm understanding you correctly, this trick will basically only work provided the ns in question is already referred to in other parts of the project ?
13:45justin_smithpseudonymous: the compiler won't compile code that calls things that it can't resolve
13:45justin_smithpseudonymous: which means you need to manually use resolve yourself
13:45justin_smithit works accidentally if the namespace is actually available because someone else (eg. your lein tooling) required the thing already
13:45pseudonymousAh, so the reason why it works for other libs is that I'm already using them and they're already resolved. This one isn't, so I'm fubar'ed.
13:46justin_smithright
13:46justin_smithbut, clojure will gladly compile code that *attempts* to resolve something at runtime
13:46pseudonymousSo time to delve into the mysteries of resolve...
13:46justin_smithso instead of foo.bar/baz you use (resolve 'foo.bar/baz) and cross your fingers it doesn't blow up with a nil at runtime
13:47justin_smith,(resolve 'this.does.not/exist)
13:47clojurebotnil
13:47justin_smith,(resolve 'clojure.set/union)
13:47clojurebotnil
13:47justin_smith,(require 'clojure.set)
13:47clojurebotnil
13:47justin_smith,(resolve 'clojure.set/union)
13:47clojurebot#'clojure.set/union
13:47justin_smithsee, magic!
13:48pseudonymousOooh. Hmm Well.. that shouldn't be a problem, the macro is written to guard against that exact case
13:48justin_smithpseudonymous: right, you don't even need require - just use resolve, and sometimes you get nil and deal with it
13:48justin_smitheasy-peasy
13:49justin_smithif resolve returns something non-nil, you know you can use it
13:49justin_smithalso this is all terrible and should have a fancy evocative name like monkey-summoning
13:49pseudonymouseh? Which part, exactly ?
13:50justin_smithconditional behaviors determined by the side effects of other dependencies
13:50pseudonymousI can't remember exactly *where* I found it, but Immutant has a dev plugin which (in hindsight) used resolve to conditionally pull in various plugins
13:50justin_smithwhich can lead to weaird things like bugs that only happen if you require foo.bar in another namespace - just consider how weird that is
13:51justin_smithI'm not saying it's never useful! but let's be real about how spooky and illogical it is
13:52pseudonymousjustin_smith: well it's not like I'd want to build everything around it, but for the odd wrapper somewhere, it should be OK, so long as it isn't extremely necessary to have it (which is exactly the case here)
13:53justin_smithpseudonymous: sure, just trying to keep perspective about the terrible consequences if we accept this sort of thing as normal - using resolve at runtime should always be guilty until proven otherwise
13:54justin_smithbut sometimes it's a fine way to do something that would be a total mess if you couldn't do it that way
13:54pseudonymousjustin_smith: btw, this was really enlightening. It's so much simpler and doesn't require a custom macro (and THAT is a real win in my book). On the downside, I spent all that time writing one ;__;
13:55justin_smithheh :)
13:58amalloypseudonymous: you also could have just found someone else's implementation of it. that macro has been written many times
14:00pseudonymousamalloy: I searched a little (not well enough) and found something much like the macro I wrote - but the one I came across didn't support a vector-style libspec, so I set out modifying it, with terrible results (repl issues) and finally I decided to write everything one step at a time to minimize chances of screwing up. It was educational enough, so I'm OK with having done it.
14:01justin_smithclearly we need a variation on "require", more like "nice-to-have"
14:02justin_smith(ns foo.bar (:nice-to-have [dwim.core :as dwim])) ...
14:04bjajustin_smith: I'm going to steal "monkey-summoning" for the next time I do something ambiguously evil in clojure
14:04justin_smithbja: heh, I really think it should be reserved for situations where a feature might ambiguously exist and you don't know until runtime, but OK
14:05bjaok, there is a precise usage
14:05justin_smithbja: I guess that could also be called "petting schroedinger's cat"
14:05bjahow about for conditional execution between deployed scenarios and non-deployment
14:05justin_smithoh yeah...
14:07bjajustin_smith: so this is monkey summoning? https://gist.github.com/3b4096aeec6a4f6992ab
14:08justin_smithbja: since you get significant difference in definitions based on runtime environment it could count
14:09justin_smithfunny enough, I did something similar as a lein plugin (so that we could unambiguously see the state of the git repo inside artifacts)
14:09bjayeah, we have a ring middleware that exposes this
14:10bjawe just have it stashed inside a utility library
14:10bjaalong with like 30 components
14:28neoncontrailsIs any particular data type implied by the term 'register'?
14:29neoncontrailsI typically think of registers as lists, but must they be?
14:29rhg135stacks maybe
14:31rhg135I always hear 'push onto' which screams stack
14:32neoncontrailsYeah that's true. Would it be preposterous to call a string a register?
14:33rhg135it technically could be used as one
14:34rhg135but semantically, they're very different
14:38neoncontrailsYeah that's sort of what I was thinking too. Thanks, just wanted to make sure it wouldn't be wildly inaccurate to call this generic arithmetic calculator a register machine
14:38neoncontrailsit's structurally like one, but uses concatenate instead of cons to build the result
14:42mikerodwould I be correct in thinking that from a stacktrace - if I see a my.ns.name__init.<clinit> in it that that means that it is an AOT-compiled loading path vs no AOT files present?
14:43mikerodI guess what I mean is, is it true that my.ns.name__init does not exist at all if there is no AOT compilation
14:43mikerodin a purely JIT world, there are no classes loaded that have a name suffixed with __init
14:53rhg135I think that file gets compiled on load even on no aot
14:57mikerodrhg135: I was trying to determine if that were true or not
14:58rhg135i may be wrong though
15:00mikerodI don't see anywhere in clojure.lang.Compiler that refers to that suffix other than Compiler.compile() which is for AOT
15:01mikerodI searched all over for both RT.LOADER_SUFFIX
15:01mikerodand __init strings
15:01mikerodand when I track the JIT compile path, I don't see any place that'd be generated. it is meant to compile the ns itself, so it may not have any place in the JIT world
15:02mikerodthis was just something helpful in troubleshooting a crazy classloader issue with some mixed AOT (bad). I started thinking the presence of the my.ns__init at all meant there was loading off of AOT classes
15:09RedNifreSo I just started with the REPL and for fun, I tried (def man doc) but it says "can't take value of a macro". What does that mean?
15:09jeremyheiler,(doc doc)
15:09clojurebot"([name]); Prints documentation for a var or special form given its name"
15:09jeremyheiler,(source doc)
15:09clojurebotSource not found\n
15:09rhg135that doc is a macro
15:09jeremyheileryeah
15:10RedNifredoes that mean that it only works when I type it in the REPL? That it's sort of not meant to be used in the code? Or is it more complicated and I should learn about macros first?
15:11jeremyheilermacros are code that generate code, and cannot be referenced
15:11jeremyheilerthey only exist at compile time, not runtime
15:11rhg135you can't pass it around like a function
15:12rhg135,+
15:12clojurebot#object[clojure.core$_PLUS_ 0x281717fa "clojure.core$_PLUS_@281717fa"]
15:12rhg135,doc
15:12clojurebot#error {\n :cause "Can't take value of a macro: #'clojure.repl/doc"\n :via\n [{:type clojure.lang.Compiler$CompilerException\n :message "java.lang.RuntimeException: Can't take value of a macro: #'clojure.repl/doc, compiling:(NO_SOURCE_PATH:0:0)"\n :at [clojure.lang.Compiler analyze "Compiler.java" 6704]}\n {:type java.lang.RuntimeException\n :message "Can't take value of a macro: #'clojure....
15:16justin_smithRedNifre: also, the repl uses clojure.repl (which includes doc), and your files won't have access to clojure.repl unless you explicitly require it
15:16justin_smithRedNifre: but usually you only need the stuff from clojure.repl in ... a repl
15:16RedNifremakes sense
15:17mungojellyi guess the reason macros and functions are both all lower case is so you can add an optional different shape to a function that already has callers?!
15:17justin_smithmungojelly: what does that even mean?
15:18mungojellyif you're not going to change existing function calls silently to macros, then it would make sense to distinguish them so you can see in the code if things are macros, so i assume the invisibility is to sneak them in like that
15:18justin_smithfunctions and macros are both lower case because that's how it's been as long as lisps have been case sensitive, upper case macros are a convention in languages with crappy macros that only do string substitution, because string substitution breaks things in really weird ways
15:19mungojellyi'm just talking about for readability, in clojure you have to guess whether things are macros or not, a lot of stuff is like, how does this function do this, oh ok it's all macros it turns out, all lower case just means "function or macro" and you have to learn/guess/experiment to know which is which
15:20jeremyheiler"all lower case" is just the status quo in clojure
15:20justin_smithmungojelly: the assumption that a macro would not be lower case is newer than lisp macros are
15:20mungojellyit's become "obvious" to me that defn is a macro, but it gradually got "obvious" over the course of several weeks of getting accustomed to it
15:21RedNifreBy the way, how far does clojure go on the functional side? Are things like curried functions, monads etc. included?
15:21ToBeReplacedi would consider a change from function to macro a breaking, non-backwards compatible change in any library
15:21justin_smithRedNifre: neither of those. Because we get varargs and dynamic typing instead, respectively
15:21mungojellysomeone a couple days ago here was talking about writing their own currying so that must not be there? there's monads somewhere but no one uses them
15:22mungojellyToBeReplaced: then do you think there's any reason to have the same style for them?
15:22justin_smithRedNifre: but the normal data types are all immutable
15:22ToBeReplacedmungojelly: no, i loosely agree that i'd rather see a naming convention for macros that distinguishes them from functions
15:23RedNifreWhy is "defn" a macro instead of a function? Is it to not allow strange programs that define functions at runtime?
15:23justin_smithRedNifre: the opposite, because you can't use macros first class
15:23justin_smithwait...
15:23mungojellyRedNifre: it's just to write the syntax of it, to make it shaped the way it is
15:23amalloyRedNifre: here is one of the basic things distinguishing macros from functions
15:24ToBeReplacedRedNifre: "intern" is the function it calls... it's just convenience around that
15:24amalloyfunctions always evaluate all of their arguments before running the function
15:24RedNifreawww
15:24amalloyso if defn were a function, (defn foo [x] 1) would evaluate foo (which doesn't exist), then [x], (which doesn't exist), and then 1
15:24RedNifreI was hoping for Io-like "lazy if you want" evaluation of parameters.
15:24justin_smithnope!
15:24mungojellyyeah a macro is like, wait, hold on, before you evaluate those things, i'm gonna rearrange them a little, ok now evaluate them
15:26RedNifreIf Clojure has strict evaluation, how can the defn macro use a regular function internally? How to write a function body without evaluating it?
15:27justin_smithRedNifre: btw you can do (defmacro man [& args] (cons 'doc args))
15:27mungojellyfn is a "special form" right? even more powerful yet
15:27rhg135quoting
15:28mungojellyand there's some built-in reader macros that look for some ~*!@*~&!@ around words but there's no (easy) way to add more of those
15:28rhg135and code is just data
15:28amalloyRedNifre: various "special forms" have special evaluation rules
15:28RedNifreI guess I'll have to read more of the book before I drown in an endless sea of further questions (currently reading "seven languages in seven weeks")
15:28ToBeReplacedRedNifre: "intern" is the "def" part, "fn" is the special form part
15:28amalloyeg, "if" is a special form, whose evaluation rule is different from the rule for function calls
15:29neoncontrailsRedNifre: These are awesome questions, but don't worry if none of this makes sense to you yet. Macros are without a doubt the most advanced feature of the language, and I noticed in #clojure-beginners you're literally beginning your first REPL session
15:29RedNifreah, so I guess (defn id [a] a) is a macro for something like (intern "id" ["a"] '(getParam "a")) huh?
15:30rhg135sorta
15:30justin_smithRedNifre: 'a instead of "a", and it uses the fn special form
15:30justin_smithand then fn calls fn* which calls some java
15:30RedNifreYes, I'm in my first REPL session and in the first Clojure chapter of the book :)
15:31amalloyRedNifre: that is the general idea, yes. wrong in basically every particular, but going in the right direction
15:31mungojelly,(macroexpand '(defn twice [n] (* n 2)))
15:32rhg135clojurebot is gone
15:32mungojelly:(
15:33ToBeReplacedin case it's of interest... i wrote a lib a while back that uses intern to programmatically create public functions instead of writing a bunch of defns: https://github.com/ToBeReplaced/lettercase/blob/master/src/org/tobereplaced/lettercase.clj#L11
15:33oddcullyso we are finally botfree
15:33RedNifrehumans win
15:33oddcullyjay!
15:33neoncontrailsI noticed that. Who maintains clojurebot? I feel moved to help
15:34mungojellyi think it's hiredman
15:35neoncontrailshiredman: do you need more hands to help with Clojurebot?
15:40hiredmannope
15:42RedNifreI don't understand why (< 1) is true but (<) is not allowed. My intuition is that (<) should also be true.
15:43RedNifre...because all elements or an empty list are ordered in accending order, like all elements in a list with one element in it.
15:44justin_smithRedNifre: that's actually a fair point, and you're not the first one to bring it up here
15:44justin_smith,(=)
15:44amalloyjustin_smith: it's more true for = than for < though
15:45amalloyi think gfredericks argued fairly convincingly on that point last time
15:45justin_smithright, I was attempting to provide an even better example
15:45amalloynotably, RedNifre, you'd lose the "law" that < is the inverse of >=
15:46RedNifreIs it? What about (< 1) vs (>= 1)? Both are true...
15:46amalloyoh, are they? i guess so. i take it back then
15:49RedNifreHow much success did you have trying to introduce Clojure at the office?
15:49neoncontrailsI've always just thought of < > as functions with a fixed arity of 1 or 2, defaulting to true in the base case
15:49neoncontrailsIs that not right?
15:49RedNifreNo, you can also do (< 1 2 3) -> true or (< 1 2 3 1) -> false
15:50neoncontrailsOh interesting. That's more consistent with other arithmetic functions, I suppose
15:50RedNifreI tried (< 1) and was surprised that it worked, then I remembered that + works for varargs, so it made sense to try (< 1 2 3) which worked and (<) which didn't.
15:51RedNifreStrange, (+) is 0 but (-) isn't allowed.
15:52RedNifre(*) is 1, which makes sense, so I guess it gives me the Monoid for * or +, but why not for - or /? Shouldn't (-) be 0 and (/) be 1?
15:53amalloyRedNifre: - and / aren't monoids either way, because they're not associative
15:53RedNifrepoint taken
16:00neoncontrailsamalloy: Not to sound creepy, but do you blog? I feel like I could learn a lot from you
16:01amalloyno. i wrote a few articles several years ago, mostly about clojure, when i was working at hubpages
16:02amalloyhttp://amalloy.hubpages.com/ confuses me, because it says i have 7 articles but only lists 4 of them and i don't see any way to find the rest
16:02neoncontrailsIf you ever feel inspired to start one, I'd love to read it.
16:05neoncontrailsEven reading your solutions to 4clojure-like problems (if not those problems exactly) would be a great resource. Your solutions remind me of what good code can look like
16:05amalloyyou can mostly find my writings on stack overflow and in #clojure
16:05amalloyneoncontrails: well, so look at my 4clojure solutions then
16:05neoncontrailsHeh, I didn't know they were published. I'll go look
16:06amalloyalthough actually not all of them are things i would endorse; i replaced my solutions with other users' solutions if they reported a bug like "hey my solution to #43 isn't working"
16:06amalloyneoncontrails: (almost) everyone's 4clojure solutions are published
16:06amalloyonce you solve a problem, you can see anyone's solution unless they opt out
16:07neoncontrailsI noticed yeah. Which is a cool idea, but certain problems I couldn't solve right away
16:09shemit is edifying to see good code in small portions.
16:10justin_smithyeah, that makes the bots very useful, when they are here
16:10justin_smithbut bot-running is a chore
16:14RedNifreI just noticed that nil behaves like an empty list/set/map/string etc. but not as 0 in (+ nil) or 1 in (* nil). So I guess the rule for nil is that it's an empty container? Or what exactly?
16:14justin_smithRedNifre: it is equal to the Java NULL
16:15RedNifrebut you can't (map count nil) in java and get an empty map.
16:15justin_smithRedNifre: and not equal to 0, and overloaded with the empty list for cons, and overloaded with false for truth checks
16:16justin_smithRedNifre: also seq treats nil as an empty sequence (and eg. map, filter, etc. call seq on their last arg)
16:16RedNifreah, that makes sense.
16:16justin_smithit's a weird mix of historical reason stuff
16:16lodin_RedNifre: seq of an empty collection returns nil.
16:16lodin_,(seq {})
16:17justin_smithbut for our particular lineage, equality with 0 is not part of the heritage
16:17lodin_No bot?
16:17RedNifreRegarding other languages, what do you think of Scala, Erlang and Haskell?
16:17RedNifrebot broke earlier today.
16:18justin_smithScala isn't simple enough, Haskell is great but makes me feel stupid, I haven't tried Erlang
16:20neoncontrailsHeh. Yeah, the evaluation of nil has taken some getting used to.
16:20neoncontrailsSomeone pointed out to me here (was it you, justin_smith?) to use (not (seq (<your list>)) as a base case for recursion
16:21neoncontrailsThat hasn't gotten less weird to me in the past three weeks, heh
16:21amalloyjustin_smith probably would have told you to use empty?
16:21justin_smithneoncontrails: in the original lisp, a list was a cell containing the current item's value and a cell containing the address of the next cell. There was a special nil cell which meant "there is not next cell", and using that alone meant an empty list
16:21justin_smithamalloy: yes, I would have
16:22neoncontrailsright, which enabled (null? the-empty-list) to return true right?
16:22justin_smithright
16:24RedNifreHm, looks like I don't have "null?". Is that a 1.7 thing? I just went with the Clojure in the Ubuntu repository which is 1.6... how old is that one and how much does Clojure change between versions?
16:24justin_smiththe current value was the Content of the Address Register, and the address of the next cell was in the Content of the Decrement Register, leading to the famous "car" and "cdr" functions (which I keep forgetting don't exist in clojure)
16:24neoncontrailsjust a wild guess, but is the presence/absence of that sentinel cell predicated on whether the language spec supports tail-end recusion?
16:24justin_smithno
16:25amalloyRedNifre: they're talking about a different language
16:25neoncontrailsDon't they by another name? first:car::rest:cdr
16:25justin_smithsure, yeah
16:26justin_smithRedNifre: yeah, sorry, this is all legacy / background
16:31lodin_nil is actually a bit odd in Clojure I think, since it complects (to use Clojure jargon) empty collections and missing values.
16:32justin_smithlodin_: and falseness
16:33neoncontrailsScold me if I'm being a little too Louis Reasoner here: would this definition work in Clojure the way null? does in Scheme?
16:33neoncontrails(defn null? [lat] (or (empty? lat) (= (first lat) nil)))
16:33justin_smithneoncontrails: shoudl null? return true for [nil 1] ?
16:34neoncontrailsAw man. Right you are
16:34justin_smithneoncontrails: try (comp nil? seq)
16:35lodin_That too. I would probably be OK with empty collections being false though (like empty list in Python is false), which they're not in Clojure, so you have to seq it.
16:35justin_smithexcept I think that gives a result you wouldn't expect for ""
16:35justin_smith#(and (coll? %) (nil? (seq %))) something like this maybe?
16:36amalloyjustin_smith: should it return false for nil?
16:36justin_smithoh, right
16:36justin_smith:P
16:36justin_smithso wrap the whole thing in a (or (nil? %) (and ...))
16:37justin_smithwhich probably still gets it wrong for some case
16:37RedNifreHm, I'm not sure I understand varargs and "empty?"... this gives me "array is not a function" or "empty list is not a function" errors... but I thought the "empty?" check would preventh that? What's wrong with this: (defn >>= [maybe & f] (if (empty? f) maybe (if (= maybe nil) nil (>>= (apply (first f) [maybe]) (rest f)))))
16:38RedNifreI'm trying to use it like (>>= "hello" count #(+ 3 %))
16:40justin_smithRedNifre: that (rest f) adds a new level of list nesting at each recursion
16:40justin_smithmaybe you want (apply >>= ...)
16:41RedNifreoh, right, the list counts as one parameter... good catch...
16:41RedNifreI guess apply also works with multiple lists, huh?
16:41justin_smithit works with multiple args, only the last arg is unpacked
16:41lodin_RedNifre: And you don't need (apply (first f) [arg]), just do ((first f) arg).
16:42justin_smithunless you expect to unpack arg...
16:42justin_smithwhich does not seem correct here
16:42justin_smithoh wait, the vector, hah, neverm ind
16:42justin_smithyeah, drop the apply and the vector
16:43lodin_RedNifre: The base case, so to speak, of apply takes a function and a sequence. Then there's convenience forms that essentially conses stuff onto the args.
16:44RedNifregreat, this works now: (defn >>= [maybe & f] (if (empty? f) maybe (if (= maybe nil) nil (apply >>= ((first f) maybe) (rest f)))))
16:44justin_smith(+ 1 2 3) (apply + 1 2 [3]) (apply + 1 [2 3]) and (apply + [1 2 3]) are all the same thing
16:45lodin_RedNifre: See also some-> btw.
16:46RedNifreHm, I don't understand the doc for some-> and (some-> "hello" count #(+ 3 %)) gives me something odd...
16:46justin_smithRedNifre: some-> rewrites forms
16:47justin_smithit would work if you changed #(+ 3 %) to (+ 3) or (#(+ 3 %))
16:49RedNifreindeed it does but I neither understand why nor what "rewrites forms" means.
16:49RedNifreBut it's getting late anyway, gotta go.
16:49RedNifreWell, the language looks interesting, so I guess I'll be here again tomorrow :)
16:49justin_smithRedNifre: try (macroexpand '(some-> "hello" count))
16:49justin_smithit's a macro, it rewrites the code before compiling it
16:50justin_smithRedNifre: admittedly (macroexpand '(-> "hello" count)) is much easier to read, and gives almost as much information (given that some-> is much like -> ...)
16:51RedNifreHm, I peeked ahead, macros are part of chapter two so I'll hopefully be wiser tomorrow ;)
16:51RedNifreThank you all for your help and have a good night.
16:51justin_smithyou too
16:54lodin_I think maybe I will start to call macros "user-defined keywords".
16:54justin_smithlodin_: but we already have something called keywords
16:55lodin_Haha, yes. So "User-defined syntax keywords"?
16:55justin_smithlodin_: "user defined syntax"
16:56justin_smithbecause it doesn't just define a symbol, it defines a syntax for evaluation
16:56justin_smithor else it didn't need to be a macro
16:58lodin_justin_smith: I wanted to avoid syntax because I think non-lisp people associate syntax with stuff like semicolons, where the brackets to, if a comma is allowed at the end of a list, if whitespaces matters, etc.
16:58lodin_And keywords are not thought of as syntax, but rather language features.
16:58amalloylodin_: stuff like, whether you need []s around the bindings in a let?
16:59lodin_amalloy: Or that you have [] instead of () in bindings. And #{} for literal sets, etc.
17:00amalloyright, my point is that that *is* syntax, and it's exactly what macros do
17:00amalloylet is a macro
17:03lodin_amalloy: Right. So is defn, but in most other languages I think people would think of it as "the keyword for defining a function".
17:04amalloyi don't think that's true at all. java and c, for example, don't have any keyword for defining a function
17:04lodin_amalloy: "class"?
17:06mungojellypeople associate syntax with getting confused by syntax which is why they should associate macros with syntax so they'll know what's going on when they're confused by the syntax of macros
17:07amalloya keyword indeed, for defining a class
17:09mungojellyproject naming around here is funny! i feel like i'm supposed to think of just one quirky word for my names! but i think i'm going to go with stringplayground
17:20lodin_mungojelly, amalloy: I've found that people that do not know any lisp but are sufficiently interested think that writing macros is what you do all day as a lisp programmer. I've read and heard people be hindered in learning Clojure because of it, because they think they should write a macro to solve the problem (or "write a program to write the program"), rather than just solving it directly.
17:30neoncontrailsjustin_smith: curious. Why is this? http://pastebin.com/N0PTgx6a
17:34lodin_neoncontrails: null-v2? always returns true (because it returns a function).
17:38neoncontrailsHmm. I see that you're right, I must've mistranslated his idea
17:39irctcHi everyone. :)
17:39lodin_neoncontrails: When he wrote (comp nil? seq) he ment the function seq. Not as a placeholder for a sequence.
17:40lodin_*meant
17:40neoncontrailsOh! That makes sense
17:40lodin_neoncontrails: So (def null-v2? (comp nil? seq))
17:40irctcDoes anyone know how to refer to an actual html file from compojure handler without actually writing views functions with Hiccup html generating?
17:41irctcI want to simply point to an existing html file, not to a function that will generate it.
17:48irctcdoes anyone have experience doing this in Compojure?
17:49lodin_irctc: I don't really, but would compojure.route/files function help you?
17:51irctcI tried with ring resource-response but that didn't seem to work.
17:52irctcThanks lodin_ that seems like it could help. I'll test it out in a min and get back to you with the results. :)
17:59irctclodin_ for some reason it just skips over my designated route and evaluates true for a route which accepts some parameters.
18:00irctcMaybe I'm not using it right. I am new to Clojure so maybe I'm not doing something as I should.
18:01lodin_irctc: Haven't really used compojure, so I'm not of much help I'm afraid.
18:03irctcOk, thanks for pointing me to some resources though. I appreciate that. :)
18:13hlolli,(defn debug [s] (prn s))
18:14hlolli,(defn quoted-prn [f] (prn `@f))
18:14hlolli,(quted-prn (debug "dontcare"))
18:15hlollisandbox broken?
18:15hlolli,(quoted-prn (debug "dontcare"))
18:17hlolliHow can I deref an arity and symbolic quote it?
18:17lodin_hlolli: Huh?
18:17hlollithe `~ and ~@ dont work
18:18lodin_hlolli: What do you want to achieve?
18:19hlolliIn what I wrote above Id want it to print (#'sandbox/debug "dontcare")
18:20lodin_hlolli: Then you want to resolve 'debug, using the function resolve.
18:20CVTJNIIWhat is the best way in Clojure to perform a function on two contiguous values in a vector, returning a vector that is one entry shorter? So say if I have [ 1 2 3 4 5 ] and I want to add contiguous entries, getting [ 3 5 7 9 ].
18:21hlolliyou mean `(resolve f) instead of `@f ?
18:22lodin_CVTJNII: Don't know about best, but you could do (map + x (rest x)) where x is your vector.
18:23lodin_hlolli: f will be a list containing the symbol 'debug and the string "dontcare".
18:23CVTJNIIlodin_, That's a lot better than what I thought I'd have to do, thanks
18:24lodin_CVTJNII: map is extra nice in that it works on functions with higher arities than one.
18:25hlolliall I get is (clojure.core/resolve sandbox.quoted-prn/f)
18:26hlollisorry if I mistunderstand you
18:26lodin_hlolli: What is it you want to do again? Really.
18:26hlolli,(defn debug [s] (prn s))
18:26hlolli,(defn quoted-prn [f] (prn `(resolve f)))
18:26lodin_Wait. You're not using defmacro.
18:27hlolli ,(quoted-prn (debug "dontcare"))
18:27hlollihoping for (#'sandbox/debug
18:27hlolli "dontcare")
18:30lodin_hlolli: I'm still not really sure what you want to do, but you probably want to use defmacro somewhere.
18:31hlollihmm yes, when you mention it
18:33lodin_hlolli: If you use defmacro, the values that you get in your parameters are unevaluated Clojure forms, which is probably want you want. Don't use ` or anything in there yet.
18:35hlolliyes, I think so too. But maybe it doesnt matter that Im calling from (clojure.core/quote namespace.function arg) instead of (namespace/function arg)
18:36lodin_hlolli: ?
18:36hlollinevermind :)
18:37hlollimy technical english is also bad.
18:39lodin_hlolli: Just see what happens if you do (defmacro quoted-prn [f] (prn f)).
18:41hlolliIt will print correctly, still doesnt give me namespace before the function name.
18:43hlollionly if I symbolic-quote it as argument... but maybe I wont need it in my case...
18:43hlollisymbolic-quote I mean ` symbol
18:43lodin_hlolli: You shouldn't do syntax quote (is the proper term, I think) at all in this case.
18:44lodin_hlolli: What you get is unevaluated, meaning that the symbol is just a symbol. It's up to you to decide what to do with it.
18:44hlolliyes I think so too, thanks so much
18:45lodin_hlolli: Which is why you need resolve. Resolves looks up what's associated with a symbol in the namespace.
18:45lodin_s/Resolves/resolve/.
18:46TEttingerclojurebot seems down. hiredman, no rush, but is clojurebot easy to bring back?
18:47hiredmanyeah, just got oomkilled
18:48lodin_hlolli: Note that it will only work if you have something that resolves as the first value in your form.
18:48TEttingerthanks hiredman
19:04TrioxinI should be able to run Clojure on rPI no problem right
19:04Trioxinit comes with JVM on it
19:05Trioxinmaybe even arduino too?
19:07spoofednoobon a raspberry you are better served with Clojurescript/nodejs
19:09spoofednoobfor arduino you are out of luck ;)
19:27irctcTake care everyone. Good night! :)
19:40trisshey all.. just raised a jira about allowing messages to be specified for pre and post conditions: http://dev.clojure.org/jira/browse/CLJ-1817
19:41trisswould somebody mind checking it for anything I might have missed?
19:41trissall comments much appreciated!
19:57trisserm I accidentally inserted my ticket twice? can i delete it or is leaving an apologetic message the only way to get rid of it?
19:58trissoh poop... bit worried that all made quite a bit of email noise and stuff. sorry if anyone recieved it!
20:07mungojellytriss: i'm new here but i think that idea sounds awesome, i've been wanting more places in clojure to put strings explaining
20:12amalloyjust send them an email apologizing for the excess emails
20:18trissamalloy: sounds like a plan!
20:19trisscheers mungojelly... pleased someone thinks its a reasonable idea!
20:19mungojellyjust to be clear, the "core" ns means nothing, and this core.clj has no particular purpose and i should just delete it and put a nameofminethatmakessensetome.clj?
20:21mungojellytriss: i think it's the best sweet spot between the idea that code is just self documenting (which it isn't), and sprinkling random observations around (which just get out of date or are noise), if there's text attached to it in an actually meaningful way, then it really accurately explains itself. but idk that's just my guesses/intuitions.
20:22mungojellyi'm thinking for stringplayground i'm going to start with a stringplayground.sandbox and then next i'm planning to add stringplayground.slides which will be blending infinite string sequences and then stringplayground.swingset can be a gui frontend 8)
20:25trissmungojelly: I like to think so. Error messages make nice docs sometimes.
20:25mungojellyone of my favorite parts of clojure so far is the idiom of bringing in a long .ed name into a shorthand form, like it's something.thingy.blah so it's :as s.t.blah or whatever, and then if you read the file you can expand that shorthand in your mind, it's succinct without being um encoded
22:28mungojellyhow can i get "lein test" to run inline unit tests? i tried putting (with-test ...) around things and it doesn't see them?
22:35mungojellyor should i use midje?
22:44justin_smithmungojelly: lein test looks for files under test/ in your project, and loads those, it doesn't load regular namespaces for test definitions directly
22:47mungojellyam i missing some benefit to putting tests separate from other code? why not mix them?
22:48justin_smithit's just a preference thing I think
22:48justin_smithI don't have a strong opinion on it myself
22:49justin_smithmungojelly: as a workaround you could make test/foo/bar_test.clj that just requires your regular ns, and that would make the test definitions load so that lein test runs them
22:49justin_smithit's a little silly, but it would work
22:49mungojellywell i'm looking instead at midje, it seems sensible and interesting so far
22:50justin_smithlein test and clojure.test are two different things btw
22:50justin_smithclojure.test is part of clojure itself, lein test is just a tool using it
22:55mungojellyhmm, midje has an infix bit to its syntax with the => thing so someone called it "faux infix" that's funny, it's like infix is so rare around here it doesn't register as existing even if it does
22:55justin_smithit's called "faux infix" because clojure doesn't start by resolving => and applying it to the surrounding forms
22:55justin_smithbecause there's no way to make clojure do that
22:55justin_smithso it's faux
22:56mungojellyok sure i see, it has a prefix too so it doesn't actually infix
22:57mungojellyi think it's pretty whatever you call it, the prefixing and then infixing, very readable
22:57justin_smiththe "fact" is the part of the form that clojure resolves, and the fact macro is the thing that looks for => and generates the resulting forms
22:58mungojellyit does make sense to choose who gets to decide the syntax, and "the middle" isn't as defined a place as the beginning. hmm, the end is perfectly well defined too but i've never heard of any backwards lisps.
22:59justin_smithmungojelly: forth works that way
22:59mungojellyno it's just endless, i mean just like lisp syntax but reversed
22:59justin_smiththe funny thing, with postfix you don't need parens - the interpreter / compiler whatever just invokes each word as it gets to it
22:59mungojelly((n 2 +) [n] foo defn)
23:00justin_smithmungojelly: what I'm saying is that because it is postfix it doesn't need parens
23:00justin_smithso they don't use them
23:00mungojellyyou don't need them if you otherwise distinguish who gets to determine the syntax
23:00mungojellyforth just is lacking in syntax, thus why everyone hates it i suppose, i found it fun enough, but i didn't make anything serious with it
23:01mungojellybut if you do a reverse lisp then you can have the last element be a macro that decides what happens with the evaluation of the earlier elements