#clojure logs

2015-09-12

00:17kavkazjustin_smith: Ah flyspell-popup is nice, I like it, thanks
00:18kavkazgood for the markdown side of my emacs usage
00:20kavkazIs it okay to shadow the top-level parameter name with a parameter name in a letfn function definition? Given that they both refer to the same variable of course
00:27mungojellyis the clojure grammar too simple for anyone to have bothered saying it as BNF? i like BNF i'd like to see it just to make sure i'm not missing anything
00:35mungojellyhere it is in ANTLR https://github.com/antlr/grammars-v4/blob/master/clojure/Clojure.g4 so i guess i'm satisfied :)
03:52felipedvorakSo I have finally succeeded in answering Project Euler problem number 1 with Clojure, but now I was wondering if someone could read the code and criticize it for me. I'm worried if this is functional or not, and if the solution is too bizare.
03:52felipedvorakhttp://pastebin.com/rYZb8mVT
03:53felipedvorakYou must get a sum of the numbers below 1000 that are divisible by 3 or 5.
03:53felipedvoraksorry someo*one but you probably have alerts turned off anyway...
03:54kungifelipedvorak: I can help you a little
03:55kungi,(reduce + [1 2 3 4])
03:55clojurebot10
03:55felipedvorakkungi: thanks
03:55kungifelipedvorak: you can use + directly in your reduce
03:55felipedvorakwow, I tried that but somehow it didn't work :/
03:55felipedvorakbut I had some problems with paredit earlier, it may be that it was the culprit of the errors
03:56kungifelipedvorak: yes paredit can be a huge problem first
03:56kungifelipedvorak: why does create-range have to return a vector?
03:57felipedvorakkungi: don't know hauhauh
03:57felipedvorakI'm with the impression vectors are more consistent
03:57kungifelipedvorak: consistent?
03:58kungifelipedvorak: instead of (reduce + [1 2 3]) you can also write (apply + [1 2 3])
03:58kungifelipedvorak: then you don't need the 0
03:58felipedvorakwow, apply is new to me!
03:58kungi,(apply + [1 2 3])
03:58clojurebot6
03:59felipedvorakthe 0?
03:59kungifelipedvorak: (reduce + _0_ list)
03:59felipedvorakalright!
04:00justin_smithkungi: you don't need the 0 anyway
04:00justin_smith,(reduce + [1 2 3])
04:00clojurebot6
04:00felipedvorakjustin_smith: Yeah, this is something I just realized, I'm always using reduce with an entry value when its not needed
04:01justin_smithfelipedvorak: well, better to supply a non-needed initial value than not provide one when needed
04:01kungiI just found my first real world usage of `tree-seq`
04:03felipedvorakkungi: the overall code, you would call this usable in the real world? the structure? sorry, I'm new to programming AND to functional, so I'm a bit (lot) confused hehe
04:04kungifelipedvorak: I would extract the (if (or (mod ... into its own predicate function `mod-3-5?`
04:04felipedvorakhmm
04:05felipedvorakvery nice
04:05kungifelipedvorak: And I would use a precondition in add-all-odd to check for the vector instead of using a comment
04:05felipedvorakI still don't know how to do that :)
04:05kungifelipedvorak: And btw. It does not expect a vector.
04:06felipedvorakvector? perhaps hehe
04:06felipedvorakkungi: I see, I'm removing this malformed mental constructo about vectors from my mind immediately.
04:06kungifelipedvorak: let me write it and show you my solution
04:07felipedvorakgreat
04:08kungifelipedvorak: solution is 233168?
04:08felipedvorakyeah
04:08felipedvorakhehehe
04:09kungi(defn mod-3-5? [x] (or (= (mod x 3) 0)
04:09kungi (= (mod x 5) 0)))
04:09kungi(apply + (filter mod-3-5? (range 1000)))
04:09felipedvorakok
04:10felipedvorakhehe still a lot to learn :)
04:10justin_smithkungi: use (zero? (mod x y))
04:10kungijustin_smith: yes
04:10kungistull a lot to learn :)
04:11justin_smiththat's why we are all here, even me believe it or not
04:12felipedvorakthanks both of you! :) 5am, my clojure addiction must come to an end for today
04:13kungifelipedvorak: good night :-)
04:24expez(defn bar [baz] (foo!)), should bar really be bar!?
04:25kungiexpez: What are you trying to communicate? -:)
04:25expezkungi: is the bang naming convention transitive?
04:26kungiexpez: in my opinion yes it is
04:26expezOr rather, I often see in the wild that it is not, but should it be?
04:26kungiexpez: Hmm no wait .... it depends
04:27kungiexpez: If you properly hide your impurity in a function then ! may not be transitive
04:27clojurebotexcusez-moi
04:28justin_smithkungi: except in clojure.core ! often means not safe in a transaction, and unless you do some intense defensive programming that will be transitive
04:28justin_smitheg. because it combines retries and side effects
04:38justin_smith(doc io!)
04:39clojurebot"([& body]); If an io! block occurs in a transaction, throws an IllegalStateException, else runs body in an implicit do. If the first expression in body is a literal string, will use that as the exception message."
04:55amalloyi don't think transitive is the right word for that
04:55amalloycontagious would be my choice
04:58justin_smith"the flu is a transitive property of humans"
05:03amalloyyes indeed, for any three humans a, b, c, if a flu b and b flu c, then a flu c
05:04amalloytoday's achievements: make flu into a verb
05:04justin_smithheh
05:04sobelnomenclature question: if a function has a remote side-effect (e.g. sftp cwd) should it end in !
05:05sobelor is that more aimed at namespaced vars
05:05justin_smithsobel: I'd say it's safe to skip if it's idempotent, but usually yes it should
05:05sobelhmmm. i like that.
05:05justin_smithsobel: my rule of thumb is "what if someone used the function inside a swap! call and it was done 50 times in a row"
05:05justin_smithwould that suck? if so, use !, if it wouldn't matter, no
05:06sobelseems sensible enough.
05:06justin_smithsobel: not that I always follow this advice (handler code is especially egregious here in my codebases)
05:06sobelit's side-effect grey area
05:07justin_smiththe kind of bug that's been haunting us lately is double transmits on a websocket in a react app
05:07justin_smithlike - sometimes the server gets two requests and it should have gotten one
05:08justin_smithnot all our request handlers listening on the websocket are idempotent, so we get weird ass bugs (many coming from weirdness in react it seems (probably because misusing react))
05:08justin_smithI would just debounce server side, but that only handles the symptom (and increases latency)
05:08sobeli hear that
05:10justin_smithit appears one bug was being caused by a side-effecting button that was acting like an innocent link, so that a pop-up preview caused a double-trigger of the event (maybe)
05:10justin_smithor, I should say "css magic tried to make an innocent link be a side effecting button"
05:11amalloydebounce? is that a common term?
05:11sobelyes
05:12justin_smithamalloy: it is a way to turn sputtering event clusters into a single event, comes from analog electronics, where a switch will literally bounce
05:12amalloyi feel like i've heard it in a past life, and can infer meaning from context, but have no real idea how i would have learned it
05:12justin_smithrebound
05:12sobelyes, it is literally slew-rate limiting
05:12amalloyslew-rate! it's like i have suddenly forgotten how to understand english
05:13justin_smithit's also closely related to how things like double-click are possible (if not technically used)
05:13justin_smithsecond event during bounce period = this is a double click
05:14justin_smith(also check for confounding parameters like x/y motion that would counterindicate, of course)
05:15sobelso idempotent handlers would prevent the 'bouncing' in the first place
05:15justin_smithright, but some of our handlers create resources for the client, this isn't negotiable
05:15justin_smithalso, some idempotent actions are CPU expensive, so triggering twice is bad
05:16sobelso, can't that still be faux-idempotent (create-or-ignore)
05:16justin_smithI was also tempted to invent a higher order function that would return "your function, but refuses to run a second time". I could even abuse memoize for this if I was feeling dirty. But this also only fixes the symptom.
05:16sobelyeah, i wasn't quite clear how memoize wouldn't work
05:16TEttingerrunonce to parallel defonce, justin_smith?
05:17TEttingerboth rhyming with Beyonce
05:17justin_smithsobel: they are allowed to create two resources with the same parameters, it's a time-dependent thing - it's just that if the amount of time is under 5 seconds they won't get an interesting result
05:17justin_smithTEttinger: haha, awesome idea
05:19justin_smith(defn runoncé [f] ...)
05:19sobel(inc justin_smith)
05:19sobel,(inc justin_smith)
05:19clojurebot#error {\n :cause "Unable to resolve symbol: justin_smith in this context"\n :via\n [{:type clojure.lang.Compiler$CompilerException\n :message "java.lang.RuntimeException: Unable to resolve symbol: justin_smith in this context, compiling:(NO_SOURCE_PATH:0:0)"\n :at [clojure.lang.Compiler analyze "Compiler.java" 6704]}\n {:type java.lang.RuntimeException\n :message "Unable to resolve symbol:...
05:20sobelok
05:20justin_smithsobel: the first one was right, but lazybot is on vacation I guess
05:20sobelclearly
05:21sobeli like the fn, defoncé
05:24sobel(def Brawndo™ [] (basically-mtn-dew) )
05:24sobelyes, unicode makes programming fun
05:26sobel🐙
05:44TEttingersobel: unicode is fun
05:44TEttinger,(def def "Pfft, can't take the value of a macro, eh?")
05:44clojurebot#'sandbox/def
05:45TEttinger,def
05:45clojurebot"Pfft, can't take the value of a macro, eh?"
05:45justin_smith,(macro? def)
05:45clojurebot#error {\n :cause "Unable to resolve symbol: macro? in this context"\n :via\n [{:type clojure.lang.Compiler$CompilerException\n :message "java.lang.RuntimeException: Unable to resolve symbol: macro? in this context, compiling:(NO_SOURCE_PATH:0:0)"\n :at [clojure.lang.Compiler analyze "Compiler.java" 6704]}\n {:type java.lang.RuntimeException\n :message "Unable to resolve symbol: macro? in t...
05:45justin_smith,(:macro (meta #'def))
05:45clojurebot#error {\n :cause "Unable to resolve var: def in this context"\n :via\n [{:type clojure.lang.Compiler$CompilerException\n :message "java.lang.RuntimeException: Unable to resolve var: def in this context, compiling:(NO_SOURCE_PATH:0:0)"\n :at [clojure.lang.Compiler analyzeSeq "Compiler.java" 6891]}\n {:type java.lang.RuntimeException\n :message "Unable to resolve var: def in this context"\n ...
05:45TEttingerfine special form
05:45justin_smithhaha
05:46TEttinger,(map def '(a b c) [1 2 3])
05:46clojurebot#error {\n :cause "Unable to resolve symbol: def in this context"\n :via\n [{:type clojure.lang.Compiler$CompilerException\n :message "java.lang.RuntimeException: Unable to resolve symbol: def in this context, compiling:(NO_SOURCE_PATH:0:0)"\n :at [clojure.lang.Compiler analyze "Compiler.java" 6704]}\n {:type java.lang.RuntimeException\n :message "Unable to resolve symbol: def in this conte...
06:25noncom|2i am thinking about hosting a webserver written in clojure with the frontend written in clojurescript somewhere. the service is a CRM-like thing, i am wondering, what minimal and what recommended machine specs are?
06:25noncom|2in particular, how much RAM do I need for that?
06:25noncom|2no huge load is planned, just some document office work
06:33winknoncom|2: I've successfully hosted a soup clone in pure clojure on a 5$ digitalocean box (incl. postgres)
06:34winknoncom|2: sooo... I wouldn't go lower :) but should be enough for a first shot
06:34noncom|2very nice!
06:35winkI think it will depend on your concurrent users as well
06:35noncom|2well, for the moment there'll be no more than 100 users with occasional access to forms and documents, so should be ok. 512 or 1024 ram will do then
06:35noncom|2btw what is soup? :_
06:36noncom|2:)
06:36winksoup.io - a microblog with some social functions
06:36winkmostly posting pictures
06:36noncom|2ah, i see
06:38noncom|2cool!
06:39noncom|2wink: btw, have you used hoplon?
06:39winknever even heard that
06:39noncom|2i'm just picking the framework for now
06:40noncom|2i worked with luminus, and there's also hoplon..
06:40noncom|2so will try hoplon too then
06:41winkI've also mostly used luminus
06:41winkand somethin before that...
06:42winknoir
06:42noncom|2yeah, noir is deprecated now. luminus builds on the best remaining parts of noir, compojure and stuff
06:42noncom|2hoplon is more innovative, but idk is it all good or bad or just different
06:43noncom|2for now it looks very cool, but different
06:43noncom|2sometimes it is hard to choose between two techologies esp if you see no clear difference between them unless you've made a big project to feel it all through
06:49winkhehe
06:49winksounds like our rewrite from ember to angular
06:50winkI'm only playing around with clojure web apps, nothing serious
06:50winkso far luminus was fine
06:50noncom|2yeah, me the same :D
06:50winkand unlike with noir (when it got deprecated) I don't see a good reason to change anything even if it might be a lot better
06:51winkthat said, the time will come when I am nosy enough to try my 30th web framework
06:51winkstill havent used a rust one for example :)
06:52noncom|2i did not use any rust even at all yet
06:52noncom|2tried go though, liked it, but i have no real tasks for that
06:52noncom|2besides, getting off a lisp is hard.. :/
06:52winkyeah I needed a small windows gui for ffmpeg
06:53winkthat's where I had my problem to solve
06:53noncom|2haha, i worked with ffmpeg through java-cv, so i was able to do it in clojure :D
06:53noncom|2java-cv is cool
06:54noncom|2thanks for the info! gotta go now, cheers! :)
06:54winkbye
07:45crockethi
07:45crocketIs there an alternative to datomic?
07:48ianhedoesithttps://github.com/tonsky/datascript
07:53muhukit's in-memory only AFAIK.
07:56mswIs there a quick (clj) repl command to check in which protocol(s) a given method (say .. toString) is (potentially) defined?
07:57Bronsamsw: toString is not a protocol method
07:58Bronsamsw: for actual protocol methods, (:protocol (meta #'proto-method))
07:58crocketdatascript is not an alternative to datomic.
07:59ianhedoesitthat's the closest I'm aware of
08:01mswI see, thanks Bronsa.
08:09Bronsawoah datascript now supports clojure too, neat
08:25crocketWhat makes datomic special?
08:27muhukcrocket: special in what way?
08:27crocketI don't know
10:05blucas%n
10:23tmtwdhow do I empty a whole channel in core async?
11:50justin_smithtmtwd: keep reading until you can't read any more in a loop?
11:52mungojellyis that really the idiom? i too was wondering if i should say like take-all or something
11:54mungojellybtw i'm running that ants.clj from rich's talk "clojure for java developers" or w/e that's one of the most popular talks on clojure, this is an awesome toy, someone should have linked me to this when i asked, this looks fun
12:08expez1.7 is such a breaking change it's not even funny
12:08expezEven library author now rewriting their libraries to use reader conditionals effectively forcing all consumers to also run 1.7 if they want patches
12:08expezEvery*
12:10Bronsaexpez: 1.7 is a breaking change?
12:10expezIs there any reason at all to ship cljc files to the consumer over two platform specific files?
12:10expezBronsa: effectively yeah
12:11Bronsaexpez: every release has had additional features over the previous ones, what's special about 1.7?
12:12expezBronsa: I suppose the previous releases were nice to haves, but a lot of people seem to think cljc is essential.
12:13expezI get the allure of only maintaining a single file, but that should be an implementation detail and I'd prefer if people still shipped clj and cljs files :/
12:14Bronsacljc *is* essential if you want to use reader conditionals
12:15expezobviously?
12:16expezYou don't *have* to write your library with reader conditionals, though. And if you do I'd prefer if you processed those files as part of deployment and also shipped platform specific files so I don't have to upgrade to 1.7 to receive patches!
12:16justin_smithexpez: why can't you use 1.7?
12:17expezjustin_smith: *I* can, but I don't want to force everyone using CIDER and clj-refactor to use 1.7 :/
12:17Bronsaexpez: oh come on, having to maintain both a clj and a cljs version of a library is *so much worse* than using reader conditionals
12:18expezBronsa: Sure, but you can process those files and put the clj and cljs files in the jar along with the cljc file...
12:19Bronsaexpez: that's what people did with cljx before clojure had native support for reader conditionals
12:20expezGuess I'm done here if nobody sees a problem
12:20expezJust needed to vent
12:20Bronsaexpez: why can't cider/clj-refactor just process the cljc files internally to strip the reader conditionals?
12:21kavkazHow come the REPL is not letting me do (map Integer/parseInt <some-seq>) but it lets me do (map #(Integer/parseInt %) <some-seq>)
12:21kavkaz?
12:21justin_smithkavkaz: methods are not first class
12:23kavkazjustin_smith: So it's not a function object?
12:23kavkazlike (fn []), (defn [] ...) or #()
12:23justin_smithno, Integer/parseInt is a static method
12:24justin_smithanother way to put it is that functions are objects, Integer/parseInt is not an object
12:24kavkazjustin_smith: Oh i see
12:24kavkazNow that I think about it from a Java perspective
12:27justin_smithkavkaz: and since a static method is not itself a class, it isn't actually a thing that you can place on a call stack - in order to do so, clojure would have to implicitly create the anonymous function version for you
12:28justin_smith*not itself an object* - sorry
13:43Narfingerhiho, i am just starting out to learn clojure and i wonder if there is a similar library for xml parsing as hxt for haskell
13:43Narfingerfor anybody who does not know, you basically define your structure of elements and it does the reading and writing according to the structure
13:53justin_smithNarfinger: we don't actually need something that strict, since we don't have Haskell's type system
13:53justin_smithNarfinger: not to say it doesn't exist - it might, but there is less motivation
14:06justin_smithNarfinger: if your data source is actual XML, clojure.data.xml might work (though it does have its limitations related to namespaces iirc)
14:14noncom|2justin_smith: once you said "i prefer websockets where available" - so, where are they not yet available?
14:14Narfingerok i will look around thanks
14:17justin_smithnoncom|2: some http servers / some clients, depends on what you are required to deploy to / support
14:18justin_smithnoncom|2: though sente has a nice feature where it works with a post based fallback if websockets are not supported client side
14:19noncom|2but all general browsers do have support... i just wander, what a client today would not support it.. but i think i'm not gonna get in this situation...
14:19justin_smithnoncom|2: http://caniuse.com/#feat=websockets
14:20justin_smithso unless you need to support android 4.3 or ie 9, you are probably good?
14:21noncom|2justin_smith: wow, that was exactly what i was looking for!
14:21noncom|2thanks!
14:33mungojelly-> and ->> are fun but also they seem random, it seems like semantics is given sometimes to the positions to try to unrandomify it with partial success, i thought of maybe something that threads through maps by key or something so it could be more explicitly semantic
14:34noncom|2mungojelly: they are not random in any degree
14:34noncom|2mungojelly: what is your original task?
14:34noncom|2mungojelly: maybe you're looking for get-in?
14:34mungojellynoncom|2: hm? i'm just learning clojure. what i mean is that you're threading through the first/last argument, which gives those positions special powers
14:35justin_smithmungojelly: you can use ->> inside ->
14:35justin_smithand if you need a position that isn't first or last, you can use as-> inside ->
14:35mungojellywhich is almost like having a semantics, and then there's things like um, the sequences it said somewhere are all sequence last, so then that approaches semantic order to it so you can thread through the last which happens to be a sequence, yay
14:35mungojellyoh cool i don't know as-> yet what's that?
14:35oddcully,(doc as->)
14:35justin_smith,(-> 1 inc (-> as n (* n n)))
14:35clojurebot"([expr name & forms]); Binds name to expr, evaluates the first form in the lexical context of that binding, then binds name to that result, repeating for each successive form, returning the result of the last form."
14:35clojurebot#error {\n :cause "Unable to resolve symbol: n in this context"\n :via\n [{:type clojure.lang.Compiler$CompilerException\n :message "java.lang.RuntimeException: Unable to resolve symbol: n in this context, compiling:(NO_SOURCE_PATH:0:0)"\n :at [clojure.lang.Compiler analyze "Compiler.java" 6704]}\n {:type java.lang.RuntimeException\n :message "Unable to resolve symbol: n in this context"\n ...
14:36justin_smith,(-> 1 inc (as-> n (* n n)))
14:36clojurebot4
14:36justin_smith,(-> 1 inc (as-> n (* n n) (inc n)))
14:36clojurebot5
14:37mungojellyso -> threads at the beginning, ->> at the end, and as-> in the middle, it's beautiful, i'm not saying it's not beautiful
14:37mungojellybut also you're like manually building something, i'd rather they were more like magic magnetic connectors and you wave them at one another and they fall in line good
14:37noncom|2mungojelly: correction: -> threads at the second place
14:38noncom|2mungojelly: well, these are core macros and are intended to be very simple
14:38oddcullyas-> with the varname/position as you like (not only once, not only in the middle)
14:38noncom|2mungojelly: also, take a look at the swiss arrows clojure library :)
14:39noncom|2mungojelly: the core functions/macros must not have magic. they all have very simple meanings. magic can be created in libraries
14:40mungojellyha well this is all very magic to most programmers still but i do think i see what you mean
14:40noncom|2mungojelly: also, in most cases it is sufficient to use just -> or ->> or, rarely, their combination, as justin points out
14:41mungojellyare you saying you don't like my idea :p
14:41noncom|2mungojelly: if you find yourself in need of more, it can be a sign that you need a (let) form with clearly labeled subresults
14:41noncom|2mungojelly: nono, it's not that i don't like the idea
14:41mungojellyi want to thread semantically too, if the things i'm threading through have arguments with semantic names and i can say "thread through the :foo arguments" then i can take a random collection of stuff and throw it together more carelessly
14:43mungojellyor like you could take the same chains and thread them through various ways, like what are the chances a chain that works with -> is also going to work with ->> because it's haphazard but if they had semantically marked arguments they could easily happen to work with multiple ones
14:43mungojellymaybe i'm just talking about monads again idk
14:44noncom|2mungojelly: yes, this looks like modals, and you could have such functionality here, but really, it is far from basic
14:44noncom|2mungojelly: it is not always clear for the compiler, what do you really want to do and when it should signal you an error
14:45noncom|2mungojelly: with that much guessing it can quickly break things
14:45noncom|2since lisp is very fluid
14:45noncom|2mungojelly: here's what - why don't you try to write such a macros youself?
14:46mungojellywell because i just learned clojure's macros yesterday, i suppose. i made a few simple things and it went fine as soon as i got used to all this # business. ;)
14:47noncom|2mungojelly: actually, in the end you may come up with a pretty useful library, that's serious and a good excercise
14:47noncom|2congrats with learning the stuff :)
14:48mungojellyhere's something i'm thinking of writing, i want an abstraction that's a grid of tiles, like the tiles each know how to draw themselves and there's a display context that asks the tiles in its field of view to draw themselves, etc
14:48mungojellyis there something like that already, a generic tiles interface?
14:50mungojellyit seems to me like that would be a friendly context for beginners to start making things in, because they just need to make a few tiles that know how to be tiles, and then ideally there'd be various pretty viewers and tools that they're compatible with
14:50noncom|2mungojelly: never heard of such a thing. how are you going to draw them, what graphics api to use? or you mean just data rendering of an n-dimensional grid?
14:50mungojellythere's a zillion games written with tiling systems but none of the ones i've read yet have the tiles written as a separate abstraction :(
14:51mungojellynoncom|2: weeeeeeeeell i could target a particular graphics api, or i could target some intermediate abstraction, what do you think would be useful??
14:51mungojellylike they could just say a list of polygons to paint on their tile, and then various viewers could translate that into various graphics apis
14:51noncom|2mungojelly: ah, i see. yep, you could very well do that. i would ofcourse decouple data rendering from the drawing api. and for the draving api in your particular case i'd pick the quil library that bases over processing
14:52mungojellyi saw something about quil and it looked awesome but i haven't tried it yet
14:53mungojellyone way i think would make sense to do it is to have tiles that know how to draw themselves in a zillion different ways, like they can make a tiny little version of themselves for zoomed out views, and say how to paint themselves as ascii, etc
14:54noncom|2quil is a very simple, friendly and powerful tool that will let you do things reaaaally quick without boring stuff. then, when you have your engine functional, you can plug in other renderers
14:54mungojellythen if you make a tile set that implements all the different ways of viewing it you can view the same game made with those tiles through all those lenses
14:54noncom|2mungojelly: interesting
14:57noncom|2mungojelly: with that idea you could create tiles described by a certain dsl with symbols that draw themselved in various ways
14:58mungojellyi'd think of implementing that like tiles are a map with :ascii goes to a function that paints the ascii, etc., so like {:ascii paint-ascii :polygons paint-polygons} is that clojurey
14:58noncom|2you mean ascii and polygons are two different renderers?
14:58noncom|2well, it's not about clojure i think, its about the concept more
14:59noncom|2i think more clojuric and functional would be to have a single language (a DSL) to describe a tile and then have interpreters of that DSL for every renderer
15:00mungojellyi was wondering earlier in general, is that what you do in clojure is fill data structures with functions you want to use, i thought of putting fields in my things and tucking functions into them but maybe i'm just messily recreating some object system i should use?
15:01noncom|2mungojelly: hm, you could have functions stored in datastructs if you need that. but i am not sure about your specific cases. when i started clojure i was constantly finding myself recreating OOP
15:01noncom|2after a period it gone, OOP and clojure (FP that it is) got separated completely, not i can use them independetly
15:02noncom|2s/not/now
15:02mungojellywell i mean the dsl is that there's tiles with attributes, so not much to it, {:name "I'm a happy tile!" :tiny-ascii "***\n*!*\n***\n"} etc, but then i think of tucking code(-like data) into them somewhere to make them pop
15:02noncom|2mungojelly: having fns in datastructs is perfectly fine if you really need this
15:03noncom|2mungojelly: if you're asking about having a function stored within it to render it like ((:renderer tile) (:data tile)) then that's recreating OOP :)
15:04noncom|2is this what you mean?
15:04justin_smithyeah, you don't need to recreate OOP in clojure, we've got protocols/records/multimethods for this
15:04justin_smithactual OOP!
15:05noncom|2yeah, and even going futher than justin is saying, i almost never use protocols/records/multimethods in my programs :D so i went even that far
15:05mungojellyi read that there's something called protocols, but i haven't understood yet how they go
15:06noncom|2not that it is a good example, many people use them, but that's just how it can possibly be too
15:06mungojellyso many facts about clojure are stirring my head and making it feel soupy
15:06justin_smithmungojelly: in pure clojure, the only way to have a method is to implement a method is to implement some protocol defining that method
15:06mungojellyclojure does seem to cohere though, there's some sense to it, the words are all somewhat memorable (a blessed rarity among lisps)
15:07noncom|2mungojelly: yeap, clojure is that type of soup that is used to make crystals
15:07justin_smithoh wow that was a mess
15:07justin_smiththe only way to implement a method is to implement some protocol defining that method
15:08mungojellyit just turns into actual normal java method dispatch right? so i get to copy my intuitions from there. that's part of what makes this language so learnable.
15:08mungojellyit's so hard to tell because of course every language is easier to learn than the last but it really does feel like a very easy language to learn.
15:08justin_smithmungojelly: pretty much, aside the fact that we don't really do concrete inheretence (only interfaces)
15:09mungojellyit's an odd thing in computer science, that inheritance didn't turn out to be very useful. in theory it seemed like it was going to be useful. hm.
15:11noncom|2nah, inheritance is a very artificail concept, that's why it did not work
15:11noncom|2does not go well hand-in-hand with the rest of the type theory
15:11noncom|2well, it works, but in a much more limited application that many anticipated
15:12mungojellyclojure though scares me it's so much the other way, by which i mean nothing has any defined structure at all you're just biting at keywords in things :/
15:13justin_smithmungojelly: it's possible to have more structure - via things like defrecord, even deftype, protocols, prismatic/schema and core.typed
15:13justin_smithit's all optional though
15:13noncom|2well, it's just a lisp with unstrict typing
15:13noncom|2yeah and what justin says
15:14noncom|2there are ways to impose total control of your structures
15:14noncom|2turns out you don't need them most of the time though
15:14noncom|2but sometimes yeah
15:14mungojellyyeah of course it's possible, but i mean just in general as a habit it seems to be the code here just works with bare data structures and secretly understands the semantics of them
15:14noncom|2because in lisp there's actually not much semantics :)
15:15mungojellyof COURSE my thingamabob has a doohickey as its third whatzit, what else would it have
15:15noncom|2:)
15:17noncom|2my story was this: i wanted to learn a lisp for a very long time, but did not understand. then i became java, then, as a soft OOP->FP transition i was scala... was storming lisp walls several times never getting a grasp. i simply could not understand. then at one moment i understood that there's nothing to understand. it's just simple and it works.. was a revelation of sorts
15:18mungojellyi still don't understand common lisp, the concepts are fine but put them all together with that WEIRD VOCAB and i can't follow a thing. but i learned scheme from SICP, which is fantastic.
15:20noncom|2hmmm maybe :D
15:21noncom|2but there's just lambda and variable names..
15:25noncom|2mungojelly: so, if you're going to explore the tiling system or write the intellectual threading macro, cool! if you have some progress later, we're glad to witness and try it out :)
15:26noncom|2as i am programming games myself, i am especially excited about the tiling system excersise..
15:26mungojellywhat are you up to? any code up i can read? i need to read a bunch of clojure
15:28mungojellyugh if my tiles want to move should they request to move from a board manager or what sigh
15:29mungojellyi definitely feel like i'm not thinking clojure-y enough
15:29justin_smithIMHO unless you have a strong reason to do things otherwise, a tile should be pure data, and you should have a function that takes a board of tiles and returns a new board of tiles (including any moves needed)
15:30noncom|2mungojelly: well, actually lately i am using a game engine (JMonkeyEngine 3) to create software for audio-visual installations, mappings and stuff... unfortunately it is protected by my employers contract but i can share the wrapper for JME3, if you later come to it
15:30justin_smithso the board is a big container, tiles are smaller containers inside it, and the logic is in a function that transforms boards by moving tiles
15:31noncom|2mungojelly: yes, you have data and separately - functions that manipulate it
15:31mungojellyjustin_smith: yes that's sorta what i was thinking but then.. do i ask every tile every time if they want to move? :/
15:31noncom|2mungojelly: but i also be happy to answer any game programming related questions you might have regarding clojure specific stuff... and other people here too do games
15:32noncom|2mungojelly: you just update the whole board at once
15:32noncom|2mungojelly: like push the board through the monad
15:32mungojellywell what i don't know is what you already have. do you have anything? is there anything i can play with? i mean like little abstractions, toys
15:32justin_smithmungojelly: it depends on what your ruleset is? if it's like chess, the "player" abstraction should decide what should move, if it's like conway's life, you should process one group of 9 at a time, each time determining the fate of the one in the middle...
15:33mungojellyjustin_smith: i'm just making a general abstraction for building various toys and games and experiments on. maybe serious things too i suppose w/e.
15:34mungojellyit's like a toybox that comes with some generic empty boards and some sets of tiles and then you can build from there
15:34mungojellytake the alphabet tiles, make a word game
15:34justin_smithmungojelly: well, in that case you'll probably need to support both those models (plus others)
15:34noncom|2mungojelly: eh, sorry, no real functional code to play with :/ all is protected by the contract :/
15:37justin_smithmungojelly: one cool design which is very popular in the game world, and fixes a lot of the problems introduced by OO in games, is ECS
15:37justin_smithentity component systems
15:38mungojellythe whole time i've been learning to program i've been reading programs for games with tiles in them hoping for something i can pick up and play with but it's always, for row, for col, row * width * hope you got the rotation right, draw the imperative sequence of things :(
15:38justin_smithit's like you took the object graph, and made a normalized database out of it - you have a list of ids representing all entities in the game, and each property is actually a table mapping from an id to a value
15:38mungojellyjustin_smith: everyone's saying ECS over and over but i don't understand what the big deal is. they weren't doing that already? wtf?
15:39justin_smithmungojelly: the difference is with ecs the player doesn't have a color
15:39justin_smiththe game has a table of colors, that maps the player id to a color
15:39justin_smithso it's not OO at all in the layout
15:39justin_smithcloser to sql
15:40mungojelly..which they weren't already doing? every basic programming text tells you not to hardcode numbers. do we not understand that colors are numbers and you can't do that with colors either. hardcoded numbers everywhere.
15:40justin_smithmungojelly: the point is, there is no player object
15:40justin_smithand before ecs they were doing OO, where your entities are objects
15:41mungojellyi've been so irritated the whole time i've been learning by the lack of anything for me to play with and it's my theory there's no good reason for it at all, which i now will have to back up with some code, but i don't see what the problem is, i really don't, just give beginners any toys at all. :(
15:42mungojellyi want to give them some boards, like maybe finite boards and infinite boards, and then some tiles to put on the board
15:42justin_smiththen do that
15:42justin_smiththe problem with easy tools for beginners is that too often big systems are built with those tools, as if you had a temple made of tinker toys. What works in the small isn't the same as what works in the large.
15:43mungojellyand then there's an example game and what it says is, give me some tiles and arrange them like this, so then of course you can make a different program that arranges them differently, or different tiles to plug in
15:43mungojellyyeah like these incredible movies people have been making in scratch, have you seen those?!
15:44mungojellyi checked it out because TIOBE said that Scratch is one of the top languages so i checked out what people are making with it lately. give people any tools they can use at all, even if it's difficult, and they'll do it. they'll do difficult as long as they can observe incremental progress.
15:44tmtwdhttp://pastebin.com/qrvqc90E what is the .. in this function? and the -target and -value?
15:44justin_smithsure, and my job would be a living hell if I had to make things in scratch
15:45justin_smithbut it's a great tool for learning, and a great toy
15:45justin_smith(doc ..)
15:45mungojellyunlike those users, you'd quickly add new blocks
15:45clojurebot"([x form] [x form & more]); form => fieldName-symbol or (instanceMethodName-symbol args*) Expands into a member access (.) of the first member on the first argument, followed by the next member on the result, etc. For instance: (.. System (getProperties) (get \"os.name\")) expands to: (. (. System (getProperties)) (get \"os.name\")) but is easier to write, read, and understand."
15:45noncom|2tmtwd: yes, one of the java interop things
15:46justin_smithtmtwd: .. is like -> but only for methods
15:46tmtwdoh
15:46mungojelly(doc ...)
15:46clojurebotPardon?
15:46mungojellyjust wondering
15:46justin_smithtmtwd: so -target is actually property access (.-target e)
15:46tmtwdoh I see
15:47tmtwd(.-target e) and (.-value )
15:47tmtwdright I get it
15:47justin_smithright, the whole form is actually (.-value (.-target e))
15:49augustlanyone else suddenly getting "error in process filter: Wrong number of arguments: (1 . 1), 0" in emacs for cider-jack-in?
15:49justin_smithmungojelly: I've done a lot of visual programming (mostly in puredata), and the biggest problem is that the number of relations between things that you can draw clearly is limited on a 2d surface, we can easily read text and infer a larger collection of relations with less ambiguity
15:49justin_smithaugustl: sounds like you updated something in your cider ecosystem
15:50augustlI haven't touched it since I installed it but for some reason I have a -snapshot dependency
15:50augustlso perhaps it was updated automatically by leiningen
15:50augustl(in my ~/.lein/profiles.clj)
15:50justin_smithyup, snapshots are intended to update
15:50justin_smithbut that's an elisp error
15:51augustlwhen I set this up a long time ago I had to use snapshots to make it work
15:51augustldoh, I did update all my packages in emacs too
15:52justin_smithaugustl: in my experience when I update any packages that are in any way related to cider in emacs, I need to delete my elc files before things work again
15:52mungojellyjustin_smith: one mistake i think all those systems make is they're ugly, or rather just boring looking. you're wiring up boxes, and they're all boxes. they need to be like candy cane striped and fluffy if they're this sort of thing, something that engages your visual perception of them.
15:52justin_smithaugustl: emacs / cider should be smart enough to work this out itself, but somehow is not
15:52noncom|2mungojelly: btw, maybe nightcode by zach oakes is getting close to what you're saying
15:52mungojellyeven scratch is just about being cute and silly and yet the blocks are all pretty much the same except they're color coded. boooooooring.
15:52augustljustin_smith: will try that, tnx :)
15:53mungojellynoncom|2: i tried to run it and it didn't work. :( nightcode, nightrun or something, i tried the one that makes games. but when i clicked to show the code it just showed a greyness. :(
15:54noncom|2hmmm.. should not be like that
15:54mungojellyi thought i'd see if i was doing anything obvious wrong and then write to the author
15:55noncom|2what could possibly be done wrong with a program that should work out-of-the-box?
15:56augustlhmm, deleting the elpa folder solved the problem. I'm this close to throwing out emacs.. Why do I have to waste time with mundane bugs in software that's at least a few centuries old
15:57kavkazaugustl: Personally I don't really have any alternative to emacs + CIDEr
15:58kavkazCIDER*
15:58kavkazI was using vim with the lein repl in a tmux session, but it wasn't the same
15:58augustlyeah, I'm addicted to its paredit too
15:58justin_smith~justin_misth
15:58clojurebotGabh mo leithscéal?
15:58justin_smith~justin_smith
15:58clojurebotjustin_smith is sits on a throne of lies
15:58justin_smith~justin_smith
15:58clojurebotjustin_smith is sits on a throne of lies
15:58justin_smithugh keeps getting the wrong factoid
15:58kavkazof course there's the eclipse plugin counterclockwise, but It's really not the same, because I'm too hooked on the vim bindings
15:59justin_smithanyway, I gave up on cider, and now code by banging parens with rocks
15:59justin_smithkavkaz: cursive is probably the most extensive integration right now
15:59kavkazjustin_smith: you mean emacs version 1.0
15:59kavkaz?
15:59justin_smithkavkaz: I mean zero editor integration
15:59kavkazthey added pebbles and sticks in version 1.5
15:59justin_smithheh
16:00augustlall editors having "added paredit" in a relatively late changelog lose a lot of trust from me :P
16:01kavkazjustin_smith: do you use cursive?
16:01justin_smithkavkaz: I use emacs with no repl integration
16:01kavkazjustin_smith: Ah i see
16:01justin_smithkavkaz: I edit the code in emacs, save it, then reload it in my repl terminal
16:01kavkazjustin_smith: That's what I used to do with vim in tmux
16:01kavkazbut i need those rainbow parentheses lol
16:02mungojellywhat is cursive, how do you extend it
16:02oddcully~cursive
16:02clojurebotGabh mo leithscéal?
16:02noncom|2its simply a clojure ide on top of jetbrains idea
16:02mungojellyi've gotten a vague impression that cursive is a cool thing so i have it on my list of things to try
16:02augustlkavkaz: I've found "highlight opposite parentheses" to be sufficient
16:03noncom|2many ppl say cursive is cool!
16:03noncom|2it is being actively developed
16:03kavkazI'm gonna give it a shot with cursive, I have 240mb free space on my SSD lol
16:03augustlmungojelly: cursive is "oh god which editor do I hate the least whatever I'll throw money at the problem"
16:04oddcullyi run vim-fireplace most of the time and check from time to time into cursive, what it complains about
16:06kavkazNah I'll stick with emacs
16:08kavkazaugustl: To me emacs just has been a better experience. But I understand the struggle of trying to get it to work the way you want it to
16:09kavkazIt's been said very well, vim is something that works right off the bat, emacs is something that you have to poke around with
16:12augustlemacs is my favorite so far as well
16:18kavkazHonestly I think bbatsov's work on CIDER and Clojure mode makes emacs very sufficient for Clojure
16:21kavkazAlso all the other contributors for those projects, I know there's at least a couple here
16:21kavkazand for other community projects as well
16:23augustlyeah that part is really nice, it's emacs itself I'm struggling with - it's so big!
16:25Tagoreemacs can be kind of tricky- it kind of comes from a different time.
16:27justin_smithI don't know, I figured out emacs itself OK, but I'm too stupid to use cider properly
16:27TagoreIt can also be very rewarding, especially if you want to do the kind of programming Slime and its alternatives allow.
16:31TagoreHmm- well I just joined this channel, so I'm missing context.
16:31TagoreAnd I'm just starting to play with Cider- have used Slime a lot in the past though.
16:32TagoreWhat's up with Cider?
16:32TagoreAnd you?
16:33kavkazCider is honestly very minimal
16:33justin_smithTagore: I used cider, it's features kind of worked, and every time any part of it was upgraded the whole thing would break
16:33kavkazjustin_smith: perhaps if you have an extensive emacs config as it is, many things will break
16:33justin_smithI got tired of fixing it all the time, and stopped using it. But clearly other people are productive with it.
16:33kavkazwhen I started I only had evil mode on
16:34justin_smithkavkaz: being able to switch to evil mode was a bonus of leaving cider
16:34kavkazaugustl: check out braveclojure.com, he talks about emacs, I got a couple pointers from there
16:34kavkazmost of my proficiency with emacs comes from practice though... well, as with anything
16:35kavkazjustin_smith: Ah i see. I don't think evil mode broke too many bindings. Perhaps this is an earlier version of cider you're talking about?
16:35kavkazAnyways I gotta go guys
16:35augustlI guess a core problem is my grumpyness.. I don't want to have to deal with weird errors after updating packages that are solved by basically a "clean' :)
16:35justin_smithkavkaz: versions 0.5 through 0.9, things broke all along the way
16:35justin_smithaugustl: exactly
16:36justin_smithperhaps my fundamental problem was imagining a paradigm where packages could be updated
16:38expezExpecting software marked unstable to be stable isn't fair
16:39expezCIDER uses semver so you should expect some stuff to break until it reaches 1.0
16:39justin_smithOK
16:40justin_smithexpez: I guess I got used to clojure world, where I can use core.async 0.00001-ALPHA-asdlkfjasdklfj and then upgrade to 0.00002-ALPHA-joiasdf and things don't break
16:40augustlthe problem seemed to be with emacs and how it compiles packages though
16:40expezSome people are even using the Melpa build while complaining about it being unstable. Melpa is like the development snapshot so unless you're willing to jump into the debugger every now and then you should definitely use melpa-stable
16:41augustlor I guess at least you could say emacs makes it possible for cider to update in a way that is broken unless you do a "clean" of already compiled elisp
16:41justin_smithexpez: I wasn't using melpa, but you've concinced me to try cider if there's ever a 1.0
16:41expezjustin_smith: the package manager gets better in emacs 25, but now you often have to manually delete packages after upgrading because emacs kept some of the old stuff around :/
16:42justin_smithexpez: I guess cider was the only emacs thing I ever used that saw breaking abi changes, so it looked like a cider problem rather than an emacs one. But yeah, that sounds like a problem with emacs.
16:44justin_smithexpez: also the nature of the projects I'm working on mean I expose some hairy edges UX wise. I have four clojure processes running at a time, juggling them is much easier when none of them are in my editor
16:44expezjustin_smith: CIDER is 16k lines of Elisp now, and 4k lines of clojure. I doubt many other packages you use are of similar complexity.
16:46justin_smithyeah, that's very likely true
16:46expezjustin_smith: you should check in every now and then to help find nasty edge cases :)
16:46mungojellyexpez: huh that is big, what all does it do?
16:46TagoreJustin: do you have a way of interacting with a running program right now that works for you, or are you restarting it every time you change the code?
16:46justin_smithTagore: I use (require my.ns :reload)
16:46justin_smithit's simple and it works
16:47expezmungojelly: check out the readme here https://github.com/clojure-emacs/cider for a list stuff
16:47justin_smithoops, (require 'my.ns :reload) of course
16:49mungojellyam i prematurely optimizing by thinking of having my tiles say what kind of tile they are and referring to one copy of how to draw them etc., will clojure make it ok if i just put the same thing over and over for the same tile. oh i guess it won't make it ok in serialized forms or whatever. so i should definitely just have the board be indirectly pointing to the tiles.
16:50srbakerheya folks.
16:50srbakeri'm using enlive-html to do some scraping for my first clojure project.
16:50mungojellyi'm just going to have them indexed by a vector of [x y] i guess, indexing by vectors is pretty, or should i name them x and y like {x: 0, y: 0} hm
16:51srbakerfirst q: what's the easiest way to print out the value of a function so i can see what it's giving me? i think it's a map, but i'm not sure
16:51srbakeri currently have just a println
16:51TagoreI haven't used that approach, so I have no idea what it's like to program using it. I have always found it very nicve to be able toi interact with a running Lisp image from my editor.
16:52srbakerhttp://pastebin.com/J9Q7bsyk that's what println gives me. but i'm having a hard time mapping over it
16:52srbakeri don'tknow why
16:52clojurebotCool story bro.
16:52justin_smithsrbaker: there's prn if you want the output to be less ambiguous, or you could print the type of the thing
16:52srbakeraha, prn is what i wanted for now. thanks
16:53justin_smithsrbaker: here's my trick (-> d type) followed by (-> d count) (-> d first type) (-> d first keys) (-> d first :attrs)...
16:53justin_smithsrbaker: this is very quick if you are using the arrow keys in the repl, you can find your data quickly
16:53justin_smithsrbaker: also, it helps to put a pprint at the end sometimes to get multi line printout
16:53srbakerokay i've updated the paste: http://pastebin.com/Rqrgv8D1
16:53srbakerwhat type is that? and where do i get a list of functions i can use with it?
16:53srbakerspecifically, i want the string at the end.
16:54justin_smithit's a list which contains a number of things, including hash maps
16:54justin_smithsrbaker: use the -> as I recommended above, you'll find a series of accessors that get the data you want
16:55justin_smith(where d is the var containing that whole big blob of data of course)
16:56srbakeri suppose i should probably set up emacs to be more helpful
16:57justin_smithsrbaker: here's how to do it (I just used your paste as the starting data) you don't need emacs, this is just a regular repl https://www.refheap.com/109471
16:58srbakernice. tanks
16:58srbakerthanks
16:58justin_smithjust fixed the formatting
16:59srbakerweird. so what's working in the repl is not working in my code
16:59srbaker(defn vf-days [] (html/select (vf) [:p.p1]))
17:00srbakerwhen i try to do first type on that, it complains that it can't convert it too ISeq
17:00srbakerwhen when i prn it, and paste it into (def d on the repl, no problem
17:00justin_smithsrbaker: OK, what does your code say the type is?
17:01srbakerLazySeq
17:01srbakerer
17:01justin_smiththen you should be able to get the first item of that
17:01srbakerwhoops. missing parens
17:01srbakerhah
17:02srbakeri'm sure i'm not the first dude to run into that :P
17:02justin_smiththe learning process never ends
17:18srbakeris there a has-key function?
17:18justin_smithsrbaker: contains?
17:18srbakeri want to know if a map has a key :tag
17:18justin_smith,(contains? {:tag "OK"} :tag)
17:18clojurebottrue
17:18srbakerwhat's ,?
17:19justin_smith,(contains? {:bag "OK"} :tag)
17:19clojurebotfalse
17:19srbakerah, thanks
17:19justin_smithsrbaker: it makes clojurebot evaluate things
17:19srbakernice.
17:20justin_smithsrbaker: also, in normal clojure code , is whitespace
17:20_Bruno_hey guys, does anyone know why (into {} [[:a 1] [:b 2]]) => {:a 1, :b 2} while (into {} ['(:a 1) '(:b 2)]) => throws ClassCastException??
17:20justin_smith,,,,,(,,,,,+,,,,,,,,,,21,,,,,,,10,,,,,11,,,,),,,,,,,,,,,,,
17:20clojurebot42
17:20justin_smith_Bruno_: because lists cannot be coerced to map-entries, but vectors can
17:21_Bruno_I came across this by trying to manipulating a sequence and turn it into a map, and I was curious to understand why the vector version works but it breaks with lists or sequences.
17:21srbaker(defn new-day [item] (if (contains? (item :content) :tag)) ...
17:21srbakeri'm getting "unable to resolve item in this context" which is confusing :(
17:21justin_smithsrbaker: too many parens
17:21justin_smithfor starters...
17:22justin_smithor wait...
17:22justin_smithsrbaker: are you sure that's what you have? because that should not complain about item - I mean if item is not callable it would complain about that
17:22justin_smith(:content item) would be more canonical
17:22_Bruno_justin_smith: is there any particular reason why would you not coerce a list into a map entry?
17:23justin_smith_Bruno_: I'm not totally certain of the reasoning, but I do know that clojure can use a vector as a map entry without creating a new data structure
17:23justin_smithor something like this...
17:23justin_smithbut this can't be done with a list
17:24_Bruno_I guess the protocol need to be extended to lists as well.
17:25justin_smithwell, lists aren't associative
17:25justin_smithso I don't know if extending the protocol even makes sense in that case
17:25_Bruno_MapEntry isn't either, it need just a tuple of two values
17:26srbakerit is complianing about item
17:26justin_smith_Bruno_: yes it is, all vectors are associative, and mapentry is a vector
17:26justin_smith,(associative? [])
17:26clojurebottrue
17:27srbakerit is definitely complaining about item :(
17:28justin_smithsrbaker: can you use refheap.com to show us the whole function?
17:28_Bruno_justin_smith: vectors are but here you are trying to bridge Java's MapEntry which only cares about a key and a value which in turn can be extracted from a list with `first` and `second`
17:28justin_smith_Bruno_: no, this is clojure's map entry, which is a two element vector
17:28lumaclojure's mapentry is a vector
17:29justin_smith_Bruno_: this isn't about the java data structures in hash maps at all
17:29_Bruno_justin_smith: it's java's one ClassCastException clojure.lang.Keyword cannot be cast to java.util.Map$Entry
17:30justin_smith,(into {} ['(:a :b)])
17:30clojurebot#error {\n :cause "clojure.lang.Keyword cannot be cast to java.util.Map$Entry"\n :via\n [{:type java.lang.ClassCastException\n :message "clojure.lang.Keyword cannot be cast to java.util.Map$Entry"\n :at [clojure.lang.ATransientMap conj "ATransientMap.java" 44]}]\n :trace\n [[clojure.lang.ATransientMap conj "ATransientMap.java" 44]\n [clojure.lang.ATransientMap conj "ATransientMap.java" 17]\n ...
17:30justin_smithoh, right, sorry
17:30srbakerhrm. not getting that error now. must've had some parens missing
17:30justin_smithanyway, the Map$Entry is a vector of two elements, regardless of provenance
17:30srbakeror too many at the bottom
17:31_Bruno_justin_smith: thx, i'll dig in the source code
17:31justin_smith_Bruno_: it's very unlikely you'll convice the core clojure team to change conj such that it would convert lists to map entries
17:32justin_smiththough I guess it could be done hypothetically as a local extension
17:32lumaclojure map's cons tries three different things: it checks if the object is a java.util.Map$Entry, then checks if it's a clojure.lang.MapEntry, then treats it as a sequence of java.util.Map$Entry without checking
17:32justin_smithluma: oh! I feel much less stupid now, thanks
17:32justin_smithluma: and it's conj not cons, of course
17:33lumain the java source, it's cons (but in clojure, conj obviously)
17:33lumahttps://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/APersistentMap.java
17:33justin_smithoh, cool
17:33srbakerso the canonical form is (key map) for getting values from maps?
17:34justin_smithsrbaker: if the map is not a literal but the key is, yes
17:34srbakerokay
17:34justin_smithsrbaker: the idea being that you know what the key is because it's literal
17:34justin_smithwhereas what happens if the map were a list instead? or nil?
17:43lumareading my comment again, the second check is actually for vector and not MapEntry
17:43lumaso that's why vector works but a list doesn't
17:45_Bruno_luma: looking at the code it looks like that lists or sequences are not accepted in order to be able to distinguish between the two following cases: (conj {} [:a 1] [:b 2]) and (conj {} {:a 1 :b 2})
17:45lumasounds reasonable
17:45_Bruno_the first one is a variadic parameter as seq of vectors
17:45lumasince seqing a map results in a sequence of mapentries
17:45_Bruno_the second one is a seq of map.entry
17:46justin_smithI keep forgetting that (conj {} {}) works
17:52srbakeris there a pretty print function that will make these maps a bit easier to read when i print them?
17:52justin_smithclojure.pprint/pprint
17:52srbakertack
17:52justin_smithit's automatically imported into your starting ns as pprint if you use nrepl
18:14srbaker,(seq? "")
18:14clojurebotfalse
18:15justin_smith,(map seq? [nil [] {} ()])
18:15clojurebot(false false false true)
18:36srbakerokay, this is a super weird error
18:37srbakerhttps://www.refheap.com/109472
18:37srbakeri'm sure it's someting to do with my expectionat of how the if works
18:37srbakerin new-day
18:37justin_smithsrbaker: line 10, (true)
18:37justin_smith,(true)
18:37clojurebot#error {\n :cause "java.lang.Boolean cannot be cast to clojure.lang.IFn"\n :via\n [{:type java.lang.ClassCastException\n :message "java.lang.Boolean cannot be cast to clojure.lang.IFn"\n :at [sandbox$eval25 invokeStatic "NO_SOURCE_FILE" 0]}]\n :trace\n [[sandbox$eval25 invokeStatic "NO_SOURCE_FILE" 0]\n [sandbox$eval25 invoke "NO_SOURCE_FILE" -1]\n [clojure.lang.Compiler eval "Compiler.java"...
18:37TEttinger,true
18:37clojurebottrue
18:37justin_smithsrbaker: parens in clojure are not for grouping
18:38justin_smiththey are for calling things
18:38srbakeroh
18:38srbakerright, of course
18:38srbakerand that shouldbe false :P
18:38srbakerexcellent. thanks
18:39justin_smithalso, line 100 (= (:tag (first item))) will always return true
18:39justin_smith,(= (:tag nil))
18:39clojurebottrue
18:39justin_smitherr, I mean line 11
18:39srbakeroh, right, i'm missing :strong
18:41justin_smith,(map #(apply (first %) %&) (iterate #(conj % =) [= =]))
18:41clojurebot#<ArityException clojure.lang.ArityException: Wrong number of args (0) passed to: core/=>
18:42srbakeri'm getting a lot furhter when i switched to test-driving this.
18:42justin_smithsrbaker: yeah, that can help a lot when it comes to keeping your steps organized
18:42justin_smith(and ensuring you don't break something as you fix something else)
18:42srbakerespecially since i've practised TDD pretty much without exception since about 2001
18:44justin_smith,(map #(apply (first %) (rest %)) (iterate #(conj % =) [= =]))
18:44clojurebot(true true true true true ...)
18:44justin_smithsrbaker: that would help too!
18:45justin_smithsrbaker: I'm a big fan of how you can make tests easy to implement in clojure by separating logic from side effects
18:45justin_smithwell, I mean you can do that in other languages too, but clojure has some nice facilities for this sort of thing
18:46amalloyfeature request: since (apply f x [y z]) is the same as (apply f [x y z]) already, (apply [f x y z]) should work too
18:47giantwaffelcatwhy do people think clojure is a lisp
18:47dbaschgiantwaffelcat: because it plays one on the internet
18:47amalloyFR #2: replace all other characters in clojure source code with ( and )
18:47justin_smithgiantwaffelcat: because they disagree with you about the definition of the word lisp
18:48giantwaffelcatheh
18:48giantwaffelcatI'm just upset Clojure lacks cons
18:48TEttinger,cons
18:48clojurebot#object[clojure.core$cons__4090 0x6db6d0a6 "clojure.core$cons__4090@6db6d0a6"]
18:48justin_smith,(cons 'a nil)
18:48clojurebot(a)
18:48giantwaffelcatjustin_smith: not proper cons
18:48TEttingerdo you mean cons pairs?
18:48giantwaffelcat,(cons 'a 'b)
18:48clojurebot#error {\n :cause "Don't know how to create ISeq from: clojure.lang.Symbol"\n :via\n [{:type java.lang.IllegalArgumentException\n :message "Don't know how to create ISeq from: clojure.lang.Symbol"\n :at [clojure.lang.RT seqFrom "RT.java" 535]}]\n :trace\n [[clojure.lang.RT seqFrom "RT.java" 535]\n [clojure.lang.RT seq "RT.java" 516]\n [clojure.lang.RT cons "RT.java" 655]\n [clojure.core$con...
18:48giantwaffelcatTEttinger: yes.
18:49TEttinger,['a 'b]
18:49clojurebot[a b]
18:49dbaschgiantwaffelcat: don’t focus on the cons, think of the pros
18:49TEttingerit is not that much different.
18:49giantwaffelcatalso the fact nil isn't the (canon?) empty list is annoying
18:49amalloyanything you can do with improper lists you can do with real lists anyway
18:49giantwaffelcatdbasch: ...goddamnit
18:50TEttinger,(seq (range 0))
18:50clojurebotnil
18:50TEttinger,(seq [])
18:50clojurebotnil
18:51TEttingerif empty list was equivalent to nil, would appending to it result in a list or a vector?
18:51TEttingerconj can produce either
18:51srbakeraw shit, partition-by won't do what i want anyhow :(
18:51TEttinger,(conj nil 1)
18:52clojurebot(1)
18:52TEttingerappears to be a seq anyway
18:52srbakeri was hoping that given a list of 1, 2, 1, 2, 1, 2; i could partitionon (= 1 1) and get three lists. whoops!
18:53TEttinger,(partition-by (partial not= 1) [1, 2, 1, 2, 1, 2])
18:53clojurebot((1) (2) (1) (2) (1) ...)
18:53TEttinger,(partition-by (partial = 1) [1, 2, 1, 2, 1, 2])
18:53clojurebot((1) (2) (1) (2) (1) ...)
18:53TEttingerah!
18:53TEttingeryou may want group-by, not sure
18:53srbakeroh
18:53justin_smithTEttinger: group-by returns a hash-map
18:53TEttingererr, no...
18:54TEttingeryeah I realized it was wrong after I said it
18:54TEttingerstill waking up
18:54srbakeri basically want to iterate the list, and start a new sub-list every time (new-day) is true
18:54justin_smithsrbaker: sounds like a good time to use reduce
18:55srbakeryeah.
18:56justin_smith,(apply conj (reduce (fn [[done curr] el] (if (even? el) [(conj done curr) [el]] [done (conj curr el)])) [[][]] [1 2 1 1 2 1 1 1 2 1 1 1 1 2])
18:56clojurebot#<RuntimeException java.lang.RuntimeException: EOF while reading>
18:56justin_smith,(apply conj (reduce (fn [[done curr] el] (if (even? el) [(conj done curr) [el]] [done (conj curr el)])) [[][]] [1 2 1 1 2 1 1 1 2 1 1 1 1 2]))
18:56clojurebot[[1] [2 1 1] [2 1 1 1] [2 1 1 1 1] [2]]
18:56TEttinger(inc justin_smith)
18:56justin_smithevery instance of an even number starts a new vector
18:56TEttingerlazyboooooot!
18:56justin_smithKHAAAAAAAN
18:57srbaker ,(apply conj (reduce (fn [[done curr] el] (if (odd? el) [(conj
18:57srbaker done curr) [el]] [done (conj curr el)])) [[][]] [1 2 1 1 2 1 1
18:57srbaker 1 2 1 1 1 1 2]))
18:57clojurebot#<RuntimeException java.lang.RuntimeException: EOF while reading>
18:57srbakerwhoops
18:57justin_smithsrbaker: yeah, one liners only with lazybot
18:57srbaker ,(apply conj (reduce (fn [[done curr] el] (if (even? el) [(conj done curr) [el]] [done (conj curr el)])) [[][]] [1 2 1 1 2 1 1 1 2 1 1 1 1 2]))
18:57clojurebot[[1] [2 1 1] [2 1 1 1] [2 1 1 1 1] [2]]
18:57TEttinger,(apply conj (reduce (fn [[done curr] el] (if (odd? el) [(conj done curr) [el]] [done (conj curr el)])) [[][]] [1 2 1 1 2 1 1 1 2 1 1 1 1 2]))
18:57clojurebot[[] [1 2] [1] [1 2] [1] ...]
18:57srbakeri'm actually oversimplifying with 1 and 2
18:58justin_smithsrbaker: I assumed, but I also figure you can do the mutatis mutandis to make it work with your code
18:58srbakerit's literally: a list of lists. the list is either a 1 element string; or a list of things where the first element is a hash with :tag => :strong
18:58srbakerand it comes in, in order.
18:58justin_smithsrbaker: do they always strictly alternate?
18:58srbakeri'm writing a bot to scrape and parse the lunch menus for the two restaurants near our office
18:58srbakerso we can ask a slack bot what's for lunch.
18:59justin_smithsrbaker: admirable plan
18:59srbakerjustin_smith: yes, they always alternate. but the list elements mightbe varied
18:59srbakerhere's the menu: http://valfarden.nu/dagens-lunch/
18:59justin_smithin that case you can ditch the reduce and use partition-all 2
18:59justin_smith,(partition-all 2 [:a :b :a :b :a :b :a :b])
18:59srbakernope. while there are two options per day this week
18:59clojurebot((:a :b) (:a :b) (:a :b) (:a :b))
18:59srbakerit's not always true
19:00justin_smithahh, OK
19:00srbakerii think reduce will do it
19:00justin_smithin that case a reduce to start new collections as you go should handle it then
19:00justin_smithyeah
19:00srbakeryep. it's a pattern i'm not familiar iwth, and it's 1am
19:00srbakerso i'm probably going to give up for the night shortly
19:01srbakerthe solution is reduce, so i can start with that in the morning
19:01srbakeri know how i'd do this with #inject in ruby, which is just reduce.
19:01justin_smithsrbaker: do note that this is using a non-obvious idiom of making a collection of collections as the accumulator, and conditionally emptying an in-progress collection into the master collection at each step
19:02justin_smiths/emptying/putting oops
19:06justin_smithI should totally write a splits function that does what people keep expecting split-with to do
19:09amalloyflatland.seq has partition-between
19:09amalloyer, flatland.useful.seq
19:10_Bruno_justin_smith: what do you think split-with should do?
19:12justin_smith_Bruno_: I'm fine with what split-with does, but what people keep expecting it to do is slice a collection based on a predicate
19:12justin_smithso that each item that is truthy for that predicate becomes the start of the next subsequence
19:12justin_smith(which is also useful and I think deserves to be its own function)
19:12_Bruno_justin_smith: isn't that partition-by ?
19:13justin_smithI think that's a special case of amalloy 's partition-between
19:13justin_smith_Bruno_: partition-by only splits once
19:13justin_smithoh wait,
19:13justin_smithyou are right
19:13amalloyjustin_smith: no, he's not
19:13justin_smith_Bruno_: it's almost partition by
19:14_Bruno_the one which split only once is split-at
19:14justin_smithbut still not quite - that one starts a new coll every time the f returns a different value
19:14amalloyyour predicate thing is different from partition-by, but not because of number of splits
19:14amalloyright
19:15justin_smithwhat I am talking about is (splits #{:a} [:a :b :a :b :c :a :c]) => ((:a :b) (:a :b :c) (:a :c)))
19:16amalloyright. which is different fro partition-by
19:16justin_smithamalloy: yeah, and it can be done with partition-between just by testing the pred on the second item in the arg
19:17_Bruno_justin_smith: could be called split-when
19:17justin_smith_Bruno_: that's a good name for it
19:18amalloythe split- family of functions each split once, and the partition family split N times. if you were going to define this function i wouldn't call it split-X
19:18_Bruno_amalloy: partition-when then :-)
19:20oddcullypartition-at
19:22justin_smith,(defn partition-when ([p? [c & cs]] (partition-when p? cs [c])) ([p? [c & cs] acc] (cond (empty? cs) [acc] (p? c) (lazy-seq (cons acc (partition-when p? cs [c]))) :else (partition-when p? cs (conj acc c)))))
19:22clojurebot#'sandbox/partition-when
19:22justin_smith,(partition-when #{1} [1 2 1 2 3 1 2 3 4 1 2 1])
19:22clojurebot([1 2] [1 2 3] [1 2 3 4] [1 2])
19:23justin_smithoh it dropped the last part there...
19:23oddcullythen do a partition-when-all
19:24_Bruno_(defn partition-when [p c] (->> c (partition-by p) (partition-all 2) (map (partial apply concat))))
19:24justin_smith,(defn partition-when ([p? [c & cs]] (partition-when p? cs [c])) ([p? [c & cs :as coll] acc] (cond (empty? coll) [acc] (p? c) (lazy-seq (cons acc (partition-when p? cs [c]))) :else (partition-when p? cs (conj acc c)))))
19:24clojurebot#'sandbox/partition-when
19:24justin_smithoddcully: it was just a bug, I don't need the all version :P
19:25justin_smith,(partition-when #{1} [1 2 1 2 3 1 2 3 4 1 2 1])
19:25clojurebot([1 2] [1 2 3] [1 2 3 4] [1 2] [1])
19:25justin_smith_Bruno_: that's a nice way to do it too
19:28noncom|2i am using the latest version of tower and timbre from ptaoussanis and tower cannot be required because it does not find "timbre/logp", how can this be?
19:28noncom|2both are of the latest versions and from the same author
19:28noncom|2did anybody encounter such an issue?
19:30justin_smithnoncom|2: have you checked lein deps :tree ? that should show potential conflicts or misversionings
19:31amalloyjustin_smith: the lazy-seq is in an odd place there. i think you want to either write (lazy-seq (cond ...)) or, better, (cons acc (lazy-seq ...)). and the last clause can/should use recur
19:31justin_smithahh
19:31justin_smithgood point, thanks
19:31justin_smith*points
19:31noncom|2nope, did not check, will look at it now
19:37noncom|2justin_smith: heh, it does not show anything, but manually i have found out that the latest version of tower uses timbre 3.3.1 while the latest version of timbre is 4.1.1
19:37noncom|2weird
19:39noncom|2damn so i hate when projects do not compile of incompatible logging frameworks...
19:39noncom|2had this happening in java many times
19:39noncom|2thats why i really prefer println
19:40justin_smithnoncom|2: I know, let's make a new logging framework api, that should fix this problem right?
19:40noncom|2yeah!
19:40noncom|2:D
19:41emdashcommaheh
19:41crocketWhat makes datomic attractive?
19:41emdashcommastrong, symmetrical features
19:41crocketIts EULA is unattractive, though.
19:43oddcullyhaha. and while you are at it also create a new linux distribution
19:45noncom|2sure! we'll get it integrated right into the core!
19:45oddcullya linux distro specialized in java logging
19:46noncom|2yeah!
19:46noncom|2and it will be very flexible, so the user will have to like, manually compile like 1000+ other libs
19:46emdashcommainfinitely configurable
19:46crocketFuck
19:46emdashcommamake sure it doesn't do anything useful out of the box
19:46emdashcommabetter, have a team of consultants to offer
19:47noncom|2yeah! and we'll provide a script that does half of the setup for ubuntu 10.04 coz we care
19:47oddcullyexport EDITOR=nano sorted!
21:53elvis4526Is there a way to pass arguments to tests ?
21:53elvis4526Let's say for example when you're inside a fixture
21:53justin_smithno, fixtures don't pass data to tests
21:53justin_smiththough they can use binding of special vars
21:54justin_smithelvis4526: but remember that you can call test/is inside a normal function, and then call that function from multiple tests
21:54justin_smith(or multiple times in one test)
21:54justin_smithand then, you absolutely can pass in eg. different test data to the same harness
21:55Trioxinwhat do ppl use for clojure on windows? intellij?
21:56Trioxincursive..
21:57cflemingTrioxin: People use all sorts of things, but I try to make it easy with Cursive
21:57cflemingInstalling lein can be tricky so I bundle it, and you can do all your leiny things from the IDE
21:58cflemingWhich is useful for getting started - you'll want it working on the command line at some point though
21:58elvis4526justin_smith: okay thanks. Special vars are the same thing as normal vars, right?
21:58Trioxincursive seems to not be out yet
21:58justin_smithelvis4526: not quite
21:58justin_smith,(def *foo* 1) ; elvis4526 note the warning
21:58clojurebot#error {\n :cause "denied"\n :via\n [{:type clojure.lang.Compiler$CompilerException\n :message "java.lang.SecurityException: denied, compiling:(NO_SOURCE_PATH:0:0)"\n :at [clojure.lang.Compiler analyzeSeq "Compiler.java" 6891]}\n {:type java.lang.SecurityException\n :message "denied"\n :at [clojurebot.sandbox$enable_security_manager$fn__835 invoke "sandbox.clj" 69]}]\n :trace\n [[clojureb...
21:58cflemingTrioxin: It's not officially released but it works fine, it's as stable as anything else I think
21:59justin_smithelvis4526: anyway, in a real repl, if you try (def *foo* 1) it will warn you that the var is not declared dynamic, even though it has earmuffs
22:00justin_smithelvis4526: you make a special var with (def ^:dynamic *foo*)
22:00elvis4526Ah, right. I just tried with a non-special vars in the fixture and its still working
22:00justin_smithoh, you can use def too
22:01justin_smithbut with a dynamic var you can use (binding [*foo* ...] ...) to rebind
22:02elvis4526the stackoverflow answer I read made it sound like the stars were just there to let know the programmer that the var was not dependant on lexical scope
22:02justin_smiththe convention is that dynamic vars have ear-muffs
22:03justin_smithand yes, dynamic vars don't use lexical scope
22:03elvis4526okay - and what's exactly the difference between let and binding ?
22:04TrioxinCursive > La Clojure?
22:04Trioxinboth are intellij plugins
22:04elvis4526Trioxin: La Clojure is not maintained anymore AFAIk
22:04Trioxinkth
22:04Trioxinx
22:04crocket
22:04justin_smithelvis4526: let binds values to symbols that must be explicitly passed into a form to be used by that form
22:04oddcullyi'd forget about ≠ cursive
22:05oddcullyit's all old
22:05justin_smithelvis4526: binding changes the value of a dynamic var, and this has effect until another binding form is reached, or the scope of the binding call is escaped
22:05justin_smithand this does not rely on passing values in, it changes the execution environments view of some var
22:06justin_smiththe reason we make dynamic vars look weird is because the scope and value rules for binding can lead to programs that are hard to reason about
22:07justin_smith(but calling def inside runtime forms instead is even worse, mind you)
22:09elvis4526okay i get it - thanks
22:09elvis4526i'm not sure where dynamic vars would be that useful though
22:10justin_smithfor situations where you need to change some code's execution environment. It's very useful for the UI of emacs, so much so that the default is for variables to have dynamic binding.
22:10amalloythey're easier to misuse than use correctly
22:10justin_smithvery true
22:11amalloythe compiler and other tooling like emacs make use of a fair number of dynamic vars, but most user programs won't
22:11justin_smithelvis4526: another example, *out* is a dynamic var, because a repl user should be able to change where a subprogram sends its output without adding an extra arg to every output function
22:12elvis4526yeah it make sense - cool
22:20Trioxinso, I want to write my first clojure program (first lisp for that matter) and i have cursive and it's asking me what project type so I guess I should start with Java EE Application??
22:21justin_smithTrioxin: there should be a "lein project" option, or something like that
22:21Trioxini dont see that
22:22amalloyyou don't want a java application or a java ee application
22:22Trioxinhttp://screencast.com/t/xMMZ4ZVwffW
22:23oddcullyTrioxin: for reasons unknow, it shows java ee... do a `lein new lerl` and open that project
22:23crocketStay away from java ee
22:24crocketjava ee involves application servers which you don't want to deal with.
22:24justin_smithTrioxin: that was the UI for "additional libraries and frameworks" and you don't need any of them - just a basic leiningen project
22:24Trioxinleiningen isn't under the clojure tab
22:24crocketEmbed jetty in your web application. Don't embed your web application in a java-ee application server.
22:25justin_smithTrioxin: there's an option on the left to use Leiningen as the build / dependency manager
22:26oddcullyTrioxin: do the `lein new` dance and then open/import from idea
22:26Trioxinso don't use the clojure tab to use clojure.. ok
22:26justin_smithcfleming: I think your further assistence might be required here
22:26justin_smithoddcully: he doesn't know lein yet I don't think, he was trying to do this via cursive (which I guess should be easier on windows?)
22:27oddcullyjustin_smith: then he has to learn. idea is just a borken editor
22:28Trioxini've used other versions of this but not for java, for html5, php, C, C++, D
22:28Trioxini mean not for lisp
22:30Trioxinchoosing clojure as my first lisp
22:31oddcullyTrioxin: i hate to bust the bubble, but idea is not the ``be all end all'' ide; cursive might lack right now the means to generate a project out of thin air. it's the same for "advanced" gradle, ...
22:32Trioxinguess I'll just find a clojure tutorial first and then i'll know how to do it all right
22:33Trioxinelse I'll never cause the singularity
22:33Trioxinloljk
22:34Trioxinor am i?
22:34cflemingTrioxin: La Clojure is now officially deprecated in favour of Cursive
22:34oddcullyno you are
22:34oddcullyall of them is depricated by not beeing useable
22:35Trioxinim not using la clojure
22:35Trioxinand i've done a lot of machine learning code
22:35cflemingTrioxin: In that screencast you sent, "Leiningen" appears on the left hand side as one of the project creation options.
22:35Trioxinyes
22:36cflemingThat's the one you want
22:36cflemingThat will allow you to create a new lein project
22:36oddcullycfleming: not for me it doesn't
22:36oddcullystuck at some java ee nonsense
22:37cflemingoddcully: What are you doing, exactly? File->New->Project..., select Leiningen from the left hand side list?
22:37Trioxinhold on updating my jdk first and then going back in there
22:37Trioxincfleming, new project, then that yes
22:38oddcullymeta-i -> ``Create New Project'' -> ``Leinigen''
22:38Trioxinwell, I was under "Clojure"
22:38Trioxinand I checked out the other as well not knowing what it was then looked it up and about to open it again
22:39Trioxinidea
22:39cflemingoddcully: What do you have meta-i bound to?
22:39oddcullycfleming: start intellij
22:39cflemingOk
22:39oddcullycfleming: that little window, with the "pick your project" stuff
22:40cflemingoddcully: So you select "Leiningen", and the next step is Project SDK and Additional Libraries and Frameworks
22:41Trioxinoh he's doing the same thing I am
22:41oddcullycfleming: yes. it's project sdk (1.8 here) and then it provides only java ee BS
22:41cflemingRight.
22:41oddcullythis is on linux, if you mind
22:41Trioxinsame on windows
22:41cflemingWhere are you seeing the Java EE stuff?
22:41cflemingUnder "Additional Libraries and Frameworks"?
22:41Trioxinhold on ill screencast it again and try the leiningen
22:42oddcullycfleming: configure your idea to start up where the projects get picked
22:42cflemingoddcully: I don't understand what you mean
22:42oddcullyiirc there is some switch that prevents loading the last project
22:42cflemingOh, right
22:42cflemingOk
22:42cflemingOne sec
22:43Trioxinin my case there is no last project
22:43oddcullycfleming: isn't it way to early in the morning in jolly good england?
22:43cflemingOk, let's go though this together
22:43cflemingoddcully: It would be, but I'm in jolly good New Zealand
22:43Trioxinok lol
22:44oddcullyin that case... i'm way to early in the morning...
22:44oddcullyonce you are at that
22:44cflemingOk, so I'm on the "Welcome to IntelliJ" screen, previous project list on the left, IntelliJ logo on the right
22:44oddcully"idea startup screen thingy"
22:44cflemingCreate New Project
22:44oddcullypick ``create new project''
22:44cflemingLeiningen
22:45cflemingChoose your SDK
22:45oddcullyfor me there is regardless what i pick ``java ee''
22:45cflemingoddcully: Can you send a screenshot of what you're seeing?
22:45oddcullye.g. if i pick gradle, there is gradle stuff...
22:45oddcullyfor leinigen there is only revolting java ee stuff
22:46cflemingoddcully: I need a screenshot to know what you're seeing
22:46Trioxinhere's what he's doing
22:46Trioxinhttp://screencast.com/t/nEzBL05ONJ
22:46cflemingTrioxin: Thanks
22:47Trioxin;)
22:47cflemingOk, so that's all under additional libs and frameworks, you don't want any of that
22:47cflemingIt's all unselected by default
22:48oddcullywell without a flash player i can not confirm it...
22:48cflemingJust press next after doing the SDK
22:48cflemingYou should see Project name: Project location: Template: Template options:
22:49Trioxinyes
22:49cflemingSo if you just want a basic project, give it a name and location and press Finish
22:49cflemingIf you want to use a lein template, enter its name and any args it needs
22:51Trioxineh. i used an uppercase char
22:51Trioxinthere's an iml file
22:52cflemingThe iml file is the IntelliJ module file
22:53cflemingYou don't care about that
22:53cflemingYour namespaces will be under the src and test directories
22:53Trioxinoh wait
22:53Trioxini did it without the uppercase erorr. now much more files
22:54Trioxina project.clj file
22:54Trioxinsrc
22:54Trioxincore.clj
22:54justin_smithoh, yeah, it probably would not like a capitalized name
22:55Trioxinoh I have a hello world app
22:55oddcullycfleming: i can confirm, that clicking ``next'' and ignoring the java ee ends up in a clojure prohect
22:55Trioxinand my own namespace
22:55cflemingNice
22:55oddcullys/h/j/
22:55Trioxinaaaaaand
22:55Trioxinsome code I've never tried to understand sooo
22:55Trioxinlol
22:56oddcullyfrom what is generated this looks like a `lein new xxx`
22:56cflemingTrioxin: Right click on the project.clj file in the root, and select Run REPL for <whatever>
22:56cflemingoddcully: That's exactly what it is
22:57oddcullyshall i dare to use e.g. `figwheel` for the template?
22:57cflemingFortune favours the brave
22:57justin_smithhaha
22:57Trioxinthe result of that didn't run my code
22:57Trioxinit ran some server
22:57Trioxinthen gave me the clojure version
22:57cflemingTrioxin: And gave you a window on the right?
22:58Trioxinyeah
22:58oddcullyworks fine too...
22:58cflemingTrioxin: That's what you want. Now you're ready for a Clojure 101 tutorial.
22:59Trioxinoh but my binary or jar or whatever... something was just compiled right?
22:59justin_smithTrioxin: clojure has a repl
22:59oddcullycfleming: get lost of that java ee stuff... it's scary sh**
22:59justin_smithTrioxin: the repl compiles forms as you enter them
23:00Trioxini was expecting hello world
23:00justin_smithTrioxin: the idea is that you can use the repl to interactively define things, and then use the things that work to build up your app
23:00cflemingoddcully: I can't do anything about that, if you never use J2EE just uninstall the J2EE plugins and you won't see that.
23:00justin_smithTrioxin: you can run your -main to get the hello world
23:00oddcullycfleming: and while you are here... can we assume, that "current-2 years" will be the target for cursive for idea?
23:00justin_smithTrioxin: but that's not what the repl does right away
23:01cflemingoddcully: Yeah, last two major versions. Currently I sort-of support 12.1 but that's going away soon. 13.1 support will go away when 15 becomes GA
23:01Trioxini get what you're saying but how do I run the existing code?
23:01justin_smithTrioxin: what namespace is your repl in (you can tell from the prompt)
23:01justin_smithif it's in your core namespace, you can run (-main)
23:01cflemingjustin_smith: Trioxin: actually in the title of the REPL tab
23:01cflemingIn Cursive
23:01justin_smithcfleming: oh, OK :)
23:01oddcullycfleming: cool. i'd rather buy cursive than 15
23:02cflemingTrioxin: click in your main editor window
23:02cflemingTrioxin: Then Tools->REPL->Load File in REPL
23:02Trioxinim in core. i just ran core and it exited with code 0 and showed that in bottom console
23:02Trioxinoh k
23:03cflemingThat will load your code into the REPL
23:03Trioxinit's loaded
23:03cflemingThen Tools->REPL->Switch NS to current file
23:03cflemingYou should see the REPL NS change to the NS of your file
23:04Trioxinyes
23:04cflemingblah.blah.core, probably
23:04cflemingOk, now you have your code from your editor loaded, and your REPL is in the same NS.
23:04cflemingGo to the REPL editor at the bottom right, and type (my-function), or whatever your function is called - I don't recall what lein generates off the top of my head
23:05Trioxinfoo
23:05cflemingOk, (foo) then
23:05Trioxini did but it didn't do anything
23:05cflemingSorry guys, I have to go
23:05Trioxini just typed it
23:06Trioxinit autocompleted
23:06cflemingHit Cmd-Enter
23:06cflemingOr Ctrl-Enter if you're on Win/Linux
23:07oddcully(inc cfleming)
23:07oddcullylazy bumbot
23:07cflemingYou should also be able to type (+ 1 2) and hit Cmd/Ctrl-Enter and see 3 come out.
23:07cflemingAww man, my fake internet points!!!
23:08ro50Hi everyone I'm a linux noob...when I tried to install leiningen the install 'worked' but I could only run lein in sudo mode
23:08justin_smithcfleming: I'll make sure you get them eventually
23:08amalloyro50: you used apt-get?
23:08justin_smithro50: it's better to just install lein to your ~/bin/ and not do a system wide install
23:08ro50I tried from the web site, apt get doesnt have version 2.x
23:08amalloywell that's good
23:08cflemingOk, I really do have to go. Trioxin: assuming you can execute things there, check out Aphyr's Clojure from the ground up, or Clojure for the Brave and True, and just ignore the bit where it tells you to install Emacs :)
23:09justin_smithro50: that's the right way, lein manages it's own version better than linux would do it for you
23:09Trioxink thanks
23:09oddcullyapt-get lein? that would get you lein 0.01?!
23:09ro50in ~/bin/ the ~ refers to the 'home ' folder?
23:09justin_smithro50: right, and make sure that is on your path too of course
23:09oddcullyro50: yes, ~ is $HOME
23:10justin_smiththe idea is to have it be executable, but belonging to your user only
23:10ro50ok ~ is home of my normal account is / is root of the entire os right
23:10justin_smithro50: right
23:10ro50my home folder doesnt have a /bin so i make one
23:10justin_smithyup
23:11justin_smithro50: many linux distros come with a shell set up to add ~/bin/ to your PATH at startup if it exists
23:11justin_smithbut this is easy to fix if yours does not
23:11justin_smiths/startup/initial login/
23:12TrioxinHello World!
23:13Trioxinfinally
23:13ro50ok I installed it but it says lein is not currently installed
23:13Trioxindon't know why a hello world needs an argument but okay
23:13ro50when I type lein in the terminal
23:13Trioxinoic it concatenated
23:13Trioxinsweeeeeeet
23:14justin_smithro50: is your ~/bin in the $PATH variable in the shell?
23:14ro50uh im not sure
23:14oddcullyro50: in a _new_ terminal try `which lein`
23:14ro50nothing happens
23:15ro50after typing $PATH I get: me@me ~ $ $PATH bash: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/usr/lib/jvm/java-8-oracle/bin:/usr/lib/jvm/java-8-oracle/db/bin:/usr/lib/jvm/java-8-oracle/jre/bin: No such file or directory
23:15justin_smithalso double check that ~/bin/lein is executable, and then check that ~/bin/ is on your path (you can use echo $PATH to do that)
23:15justin_smithro50: oh, you can also get your PATH from an error message :)
23:15justin_smithso no, ~/bin/ is not on your path, and you need to add it
23:15justin_smithin your shell you can do PATH=$PATH:~/bin/
23:16justin_smithto make this happen automatically it can be added to your shell init file, usually .bashrc or .login or .profile or something
23:16justin_smith(all will be hidden files in your home directory)
23:18ro50oh there is already something in there for that
23:18ro50i will try reset and see if it works
23:18ro50brb
23:19justin_smithoh man he left before I could tell him about "bash -l"
23:19oddcullyhe'l be right back
23:20justin_smithoddcully: right, but he didn't need to reboot
23:20justin_smithor whatever he thought he had to do
23:20oddcullyhe is doing the ole windowsaroo: reboot to update the env
23:20justin_smiththe ms-dance
23:21Trioxinso, I'm used to curly braces and this defn shows the closing ) on the same line as the last statement in it. Is it bad form to close the function on the next line?
23:22justin_smithTrioxin: yup
23:22Trioxinwhyyyyyyyyyyyy
23:22justin_smithTrioxin: we have different standards around here
23:22justin_smithTrioxin: I like it because it means I don't get confused about which kind of code I'm reading
23:23justin_smith(if the braces are on their own lines, I'm reading an algol, if on the same line, I'm reading a lisp)
23:23rem500hi got it working thanks everyone
23:23justin_smithrem500: cool, right as you left I was like "use bash -l instead of logging out or rebooting" but I was too late
23:23justin_smithlol
23:24rem500has anyone else read the leiningen vs the ants story it's good
23:24oddcullyrem500: kindled it
23:24justin_smithyup, that's where the name of our build tool comes from - ant is a popular build tool for java
23:24oddcullyjustin_smith: also salve
23:25TEttingerTrioxin: I totally used to feel that way. I quickly got accustomed to closing parens on the same line because it saves a lot of space
23:25justin_smithoddcully: salve?
23:25oddcullyjustin_smith: vim-salve
23:25Trioxinis "I don't do a whole lot." here a comment? http://hastebin.com/purosucode.lisp
23:25TEttingerdocstring
23:26justin_smithTrioxin: it's considered the official documentation of that function
23:26Trioxinoooo
23:26justin_smithTrioxin: you can look up doc for functions using the doc function too
23:26justin_smith,(doc +)
23:26TEttinger,(defn foo "I don't do a whole lot." [x] (println x "Hello, World!"))
23:26clojurebot"([] [x] [x y] [x y & more]); Returns the sum of nums. (+) returns 0. Does not auto-promote longs, will throw on overflow. See also: +'"
23:26TEttinger,(doc foo)
23:26clojurebotExcuse me?
23:26clojurebot#'sandbox/foo
23:26Trioxinwell, I hope I like this enough to not want to go to CL
23:26TEttinger,(doc foo)
23:26clojurebot"([x]); I don't do a whole lot."
23:26TEttingerthere we go
23:27justin_smithTrioxin: cursive will use doc-strings for help popups iirc
23:27rem500I tried to learn clojure a month or so ago but now im back even though I'm busy
23:27TEttingerTrioxin: it's definitely an active community here. not sure if the same can truly be said of CL, which has been a bit more subdued I would say
23:28Trioxini really wanted to try lispworks but it was a billion dollars
23:28TEttingeryou're more likely to find up-to-date libs in clojure than for CL, I would say.
23:28rem500i never thought id see a lisp make a comeback
23:28oddcullyTrioxin: better pay cfleming
23:28Trioxini can use all that is java in clojure right?
23:28TEttingeryes
23:29TEttingeralso, technically, all that is Scala or Groovy or any JVM language, though Java remains the easiest to call
23:29justin_smithclojure / java interop works very nicely going both directions
23:29justin_smithothers might not be as easy (scala makes things harder then they should be to be sure)
23:29Trioxininteresting
23:29TEttingerOlajyd used the Scala Storm stuff from Clojure, that was... interesting
23:30TEttingerit worked though
23:30Trioxinwhat about mobile dev how is that coming?
23:30Trioxini see lein-fruit and something for android
23:31Trioxingoby
23:31justin_smithyeah, there are projects, I've only done things with mobile via web-apps myself
23:31TEttingerI think, as for many many platforms, the best approach is "make a web app that the user can view on mobile and on desktop." and clojure has excellent support for that via clojurescript
23:31Trioxinclochure
23:31justin_smithTEttinger: exactly, that's what's worked for me
23:31oddcullyi put some cljs stuff up for me mobile dudes. my last mobie projects made made me imagine killing people
23:32TEttingerthere are also various things that let you convert a webpage to a web app. I believe Intel's XDK consumed Appcelerator Titanium
23:32Trioxinwell I write all my mobile in HTML5 using cordova but I was thinking for heavy lifting...
23:32TEttingeryep, clojure works well on servers
23:32Trioxinor maybe better API access on the mobile platform
23:32Trioxinwell, more not better
23:33TEttingerI've had clojure processes open for months without intervention. And, that was on a windows laptop with overheating issues
23:35Trioxinwonder how hard it would be to port my ANNs from c
23:36TEttingerI'd imagine a rewrite would be easier than a port, myself. probably a lot shorter
23:36justin_smithANN ?
23:37TEttingerthe approaches used in C programs and in Clojure programs are really not at all similar.
23:37Trioxinneural networks. been doing prediction code lately on a side project
23:37TEttingerhave you looked at Torch at all?
23:37Trioxinno
23:37TEttingerTorch struck me as unusually high-level Lua meant for neural networks and other scientific code
23:38TEttingeralso it has GPU acceleration for CUDA stuff
23:38TrioxinI started with matlab
23:38Trioxintorch seems cool
23:41TEttingerthere's some stuff in that area for clojure but I haven't looked into it as much
23:42oddcullyi'm parsing factorio files with instaparse... i hope there is some jlua...
23:42TEttingerI've found clojure is really really good for writing complex collection heavy code without making your brain explode
23:42TEttingerthe immutable collections are a big contributor to brain stability
23:43Trioxini see clojure has been used in robotics, that's good
23:43justin_smithcan verify, I have an explosion-prone brain and clojure is very nice about not lighting the wick
23:44justin_smithor was that "can verify, am exploded brain"
23:44Trioxinwell it doesn't look too touch. I'm sure if I can learn all these other languages I can get this
23:45Trioxini'm just wanting it mostly for the paradigms
23:45TEttingerclojure's also hilariously good at code golf. some CL people described Clojure as a Lisp meant for writing one-liners :)
23:45TEttinger(part of the joke being that any lisp program can be rewritten as a one-liner)
23:45TEttinger(for very long lines)
23:47Trioxinafter this I'll get into python and then my brain will be complete with programming. I've stuck with the same languages for too long and all these papers come out in PY and ppl talking about lisp paradigms. must not miss out
23:51Trioxinwill it be difficult to understand CL knowing clojure?
23:51Trioxinwow you weren't overselling the java interop. that was ez
23:52justin_smithin my experience using clojure after common lisp and scheme, there was a break in period of being constantly annoyed about minor syntax differences, followed by everything being easy because the core building blocks were the same.
23:53Trioxinfair enough
23:53justin_smiththough CL and even scheme use mutable data structures much more than we do in clojure, so they make a wider variety of programming styles possible that don't work as nicely in clojure
23:54justin_smiththe tradeoff is that due to clojure being more constricted in style we get nice things like easy concurrency (due to eschewing the things that make concurrency really hard, like rampant mutation of data)
23:54justin_smithTrioxin: it is easy to code CL or scheme as if they are clojure, coding clojure like one of the others is a bit harder
23:55justin_smith(and probably not a good idea even when it isn't hard)