#clojure logs

2015-08-27

00:47sojacquesHi guys, I have a little question, is there anything similar to http://tour.golang.org for clojure? A friend of mine is looking for a brief introduction to the language, and I can't really find one that allows you to try as you read
00:47jeayesojacques: The koans allow you to learn interactively.
00:48jeayeBut there's not much ceremony around it all, so you need to be a bit quick on your feet.
00:48sojacquesjeaye: is there any way to do the koans in a browser?
00:49jeayeOf course.
00:49sojacquesoh, there are clojurescript koans for that. Fantastic
00:50jeayeRight, that's the one. _Basically_ the same, as far as beginners are concerned.
00:51sojacquesThanks a lot, I bookmarked this, it's going to be very convenient to explain my friend what I'm doing all day
00:51sojacquesfriends*
00:58seangroveFor a function that expects keyword args, is there a way to just pass a plain map?
01:00seangroveugh, (apply concat {})
01:06mangeseangrove: I've seen people use a function like this to do it, (defn mapply [f kwargs] (apply f (apply concat kwargs)))
01:54amalloy~mapply
01:54clojurebotYou have to do something like (defn mapply [f & args] (apply f (apply concat (butlast args) (last args)))), which just goes to show why unrolled keyword args are a bad idea
01:55amalloyseangrove: ^
01:57amalloy(inc gfredericks) ; for that, iirc
01:57lazybot⇒ 147
02:28sveriambrosebs: ping
02:58crocketHow do I convert a data structure into a textual representation readable by clojure?
02:59neoncontrailsDefine "readable"?
03:00neoncontrailsAnd maybe "data structure" too. What type?
03:07dstockton,(pr-str {:a 1 :b 2})
03:07clojurebot"{:a 1, :b 2}"
03:08dstockton,(clojure.edn/read "{:a 1, :b 2}")
03:08clojurebot#error {\n :cause "clojure.edn"\n :via\n [{:type java.lang.ClassNotFoundException\n :message "clojure.edn"\n :at [java.net.URLClassLoader$1 run "URLClassLoader.java" 366]}]\n :trace\n [[java.net.URLClassLoader$1 run "URLClassLoader.java" 366]\n [java.net.URLClassLoader$1 run "URLClassLoader.java" 355]\n [java.security.AccessController doPrivileged "AccessController.java" -2]\n [java.net.URL...
03:17neoncontrailsHow many of you would use Clojure in an interview setting? Strictly curious
03:18oddcullyhaha
03:24jeayeWhat a ridiculous interviewer that must've been.
03:44crocketdstockton, thanks
03:44crocketneoncontrails, ^^
03:44crocket,(doc pr-str)
03:44clojurebot"([& xs]); pr to a string, returning it"
03:44crocket(pr-str '(3 4 [:a :b]))
03:44crocket,(pr-str '(3 4 [:a :b]))
03:44clojurebot"(3 4 [:a :b])"
04:02Leonidasneoncontrails: what's wrong with HashMaps?
04:02LeonidasI feel it's like having an issue with the colour blue.
04:03neoncontrailsNothing. It's strictly not implied by use of me
04:03neoncontrails*map
04:04LeonidasMust've been hilarious, did you get the job? :)
04:04neoncontrailsThat's precisely what I thought too. I had fun, but I think if an interviewer wants to ding me for using map, we probably won't get along well anyway
04:05neoncontrailsIt was a practice interview actually, so purely fun and games. But the guy was older than me, and more experienced
04:07wasamasaage doesn't prevent you from sillies
04:07neoncontrailsI did get briefly excited nonetheless, like, "Ooh, a chance to talk about how cool map() functions are!"
04:10neoncontrailsIt did make me wonder though. How common *is* knowledge of map/reduce/filter?
04:11Empperidepends on who you ask
04:11Empperibut if you look at the broad majority of the programmers then not very
04:11neoncontrailsIt's standard at my university; one can't pass SICP without becoming an expert on functional style
04:11EmpperiI'd say 10% of the programmers doing programming for living know those
04:11Empperior so
04:11neoncontrails!!!
04:11Empperithe skills of an average programmer out there is not exactly dashing
04:11neoncontrailsreally only 10%?!
04:12Empperiit's just a guess but yeah
04:12EmpperiI've done my fair share of code auditing, training etc so I think I have a hunch
04:12neoncontrailsWell, that can be forgiven, maybe (I don't think I'm a terribly good programmer)
04:13Empperiand I've interviewed propably hundreds of people for programming jobs
04:13neoncontrailsI'm just surprised that it's not common parlance by now... even Java has map now, I heard?
04:13Empperithese days most of the guys I interview do know those but that's because I'm at the last interview and rest have been filtered out already (
04:14Empperiyeah java has map, filter, reduce, flatmap and so forth
04:14Empperiin java 8
04:14Empperithe problem is, most of the guys writing java out there don't use java 8 yet
04:14Empperithey can't or are too afraid to upgrade since their code is so brittle
04:15Empperior their customers are too afraid to allow that
04:15neoncontrails,(filter (fn [interviewer] (knows? interviewer 'filter)) (map interview interviewer))
04:15clojurebot#error {\n :cause "Unable to resolve symbol: knows? in this context"\n :via\n [{:type clojure.lang.Compiler$CompilerException\n :message "java.lang.RuntimeException: Unable to resolve symbol: knows? 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: knows? in t...
04:15Empperiand even if they had java 8 they'd have to know how to use those
04:16Empperiit is wildly different to use java Streams API and build on top of that instead of good ol' mutable variable mess
04:16neoncontrailsI have only heard mediocre experiences with it
04:16Empperiit's quite nice
04:16Emppericertainly a huge improvement to Java
04:17neoncontrailsFor me, the transition from Scheme -> Java 7 was distressing because it lacked both my bread and butter
04:17Empperianyway, there are people out there writing client-server architecture where their server receives commands in a way that their clients write commands to database "command" table and the server polls that
04:18Empperiand clients when they've written that command start polling that same table and wait that specific line is deleted
04:18Empperiand then both read and write happily to the exact same database
04:18Empperiyes, this is from a real software I audited
04:18neoncontrailsI came to appreciate that map/reduce aren't just making my life easier, that they really shape the way I organize my thinking
04:19Empperithe reason they implemented it like that was that they didn't know how to write concurrent software or how to use sockets and they didn't bother to google for ready implementations
04:19neoncontrailsHa, yes. I haven't worked in industry yet where these things start to matter
04:20Empperithat kind of people really do get paid for doing programming work and they can go on doing their work like that for decades
04:20neoncontrailsBut I hear that when I do have to work with databases, it will be an easier transition from my current way of coding
04:20oddcullyEmpperi: ppl get creative to get over fences
04:20Empperiindeed
04:20Empperithey had a slight performance and maintanibility problem and bought consultancy from us
04:20EmpperiI wonder why they had these problems...
04:21neoncontrailsHeh
04:21oddcullyand slight is needs alot of quoting fingers, right?
04:21Empperiyup
04:21Empperithere were hundreds of the clients talking to that "server"
04:21oddcullys/is/
04:21Empperiall accessing the very same database
04:21Empperiwriting stuff there
04:21Empperithey also had strange bugs
04:22Empperiturns out they were using MySQL and it's myisam database
04:22oddcullyhaha
04:22neoncontrailsThis is kind of a loaded question then, but supposing all of these things are true:
04:22Empperimyisam does not have proper transactions it works in auto-commit mode
04:22neoncontrailsThat most programmers aren't terribly familiar with functional programming methods
04:23Empperiyes, correct
04:23Empperifunctional programming has been gaining in popularity in the last 5 years
04:23neoncontrailsThat most employers aren't familiar enough with them to really assess your whiteboard solutions written in a functional style...
04:23neoncontrailsWhat then?
04:23Empperibefore that it was rare to find anyone who actually knew that stuff
04:23Empperineoncontrails: then it means you should look elsewhere :)
04:24Empperiyou don't want to go to that company where the interviewer doesn't know what map/filter/reduce does
04:24Empperiyou'd die in brain hemorrage there
04:25neoncontrailsHahaha. I completely agree, but then I wonder, are the companies that consider FP an asset advertising themselves as such?
04:25oddcullycheck for the reaction: either they feel dumb and will not hire you or they will have a revelation
04:25Empperisome are, others arent
04:25neoncontrailsWhere would I find the companies that my problem solving approach fits in, in other words
04:27Empperihard to say, depends on where you live
04:28neoncontrailsCalifornia
04:28oddcullyan indication also can be companies where the job description does not focus on e.g. one programming languages. like "you know scala, python, ocaml and/or racket"?
04:28neoncontrailswith roots in both bay area and Southern CA
04:28oddcullyif a shop is already polyglot it will be alot easier to impress them with new stuff
04:29neoncontrailsIt seems (limited experience) like the language preferences are most often articulated by recruiters
04:30neoncontrailsThat the same job might have different criteria depending on whether it's posted by HR or a headhunter
04:31neoncontrailsWhen I see a language preference and it's through a headhunter, I usually apply anyway, maybe with a note that I'm happy to learn Ruby or whatever
04:32neoncontrailsBut I dunno, do you think that it's a red flag when a preference is stated at all?
04:35Empperimy company (in Finland) recruits guys who do not know the languages we use
04:35Empperiif he/she is good then he/she will learn our tech stacks
04:38neoncontrailsThat sounds like an extremely good attitude to have
04:38neoncontrailsCrossing fingers that enough companies in CA agree with that :)
04:43Empperithere aren't that many people who know Clojure for example in Finland
04:43Empperiwe are currently the largest company in Finland doing Clojure seriously
04:43Empperiand even we have only like 10% of our projects using Clojure
04:44Empperiso if we wan't new guys into our Clojure projects we usually need to hire someone who doesn't know it yet
04:44Empperibut who wants to learn
04:45im_learningi want to learn
04:46Empperiso your nick says lol
04:47im_learningyea
04:48im_learningI just wanted to get in touch with one fucntional programming language. confused which to choose, haskell or clojure?
04:49gilliardWhy not both?
04:49Empperiyeah
04:49Empperithey are both functional but in many ways very VERY different
04:49Empperiyou'd be better off learning both
04:49gilliardThe differences will teach you a lot about languages.
04:50Empperithe same way one becomes a better Java programmer by learning Clojure one also gets a better Clojure programmer by learning Haskell
04:50Empperiand vice versa
04:50im_learningnice point.
04:50Empperithe further apart from your comfort zone you go when learning a new language the more you'll learn
04:52im_learningI always want to get into serious stuff like this. But the problem is the day-time job? How you guys manage your time to learn these?
04:52Empperiwell, right now I don't lol
04:52lambda-smithim_learning: sacrifice the sleep time
04:52EmpperiI have a 11 month old daughter who takes all my free time
04:52wasamasafree time is overrated
04:52neoncontrailsThat question was on my mind, too, a few weeks ago. I decided to go with Clojure first
04:53Empperibut fortunately my employer is very flexible in many ways
04:53EmpperiI can learn stuff at work too
04:53Empperibut yeah, do programming at your free time
04:53oddcullyim_learning: sell your tv
04:54Empperipick up a project you'd like to do and which is simple enough you might actually finish it too
04:54neoncontrailsA criticism of Clojure, that it's just a thin wrapper around Java, is also somewhat of a benefit in terms of interoperability and ability to use Java's fantastic API features
04:54Empperiand write it in language x
04:54Empperisomething like a blogging platform
04:55im_learninghow about solving algorithamic questions in language x?
04:55Empperigood way to learn too
04:55Empperibut might not introduce you to the way of thinking in that language
04:56gilliardYeah if I'm picking up a brand new language I'll usually pop over to projecteuler or similar. Especially if I don't get big chunks of time all at once.
04:56neoncontrailsWell all of the languages will give you a solution, some of the languages will give you a great solution
04:56Empperibecause well known algorithms are well known anyway
04:56Empperiyou'll mostly learn syntax that way
04:56Empperiand that algorithm
04:57im_learningso solving problem will help you learn syntax, doing project will help you learn the insight of that language.
04:58im_learningempperi, what kind of projects you do with clojure?
04:58neoncontrailsdoing projects helps you define what the problems are, I think
04:58neoncontrailswhich is a bit easier said than done
04:58Empperiim_learning: mostly stuff with web ui
04:59Empperibut there's a ton of stuff going under the hood
04:59Empperienterprise stuff and so forth
04:59neoncontrailsit's one thing to be handed a little problem, say, "sum of the first 3,000,000 prime numbers"
04:59Empperiright now we are building this system with micro-services architecture with elastic search and very complex search queries and terabytes of input data
05:00neoncontrailswhich might be a bit tricky, but it's a totally different difficulty than figuring out the problems that you need to solve to get your app to run on an android phone
05:19Kneivaim_learning: I've used my commute time to learn stuff. Like solving these problems: https://www.4clojure.com/ When I got to the harder problems and had to really think about them I could do the thinking while helping my child to fall asleep.
06:10ToxicFrogHuh.
06:10ToxicFrogWhen I try to lein run, it dies trying to download the leiningen jar from S3.
06:11ToxicFrogWhen I try to download it manually, I get an XML file saying "access denied".
06:11ToxicFrogIs Lein hosed for anyone else?
06:12Empperiwindows?
06:17ToxicFrogEmpperi: linux.
06:32gilliardI just tried it & "works for me"
06:44vijaykiranToxicFrog: proxy ?
06:44ToxicFrogvijaykiran: nope. And it passes the certificate checks fine, it just doesn't subsequently serve me the jar.
06:50ToxicFrogIs it possible that 2.3.1 is just too old?
06:51ToxicFrogYeah, that's the problem.
06:51ToxicFrogApparently S3 serves 403 rather than 404 if you try to follow a dead link!
06:51gilliardnice
06:52ToxicFrogAnd 'lein upgrade' requires the jar to function, so if you wait too long between upgrades your only option is to download the latest script from github by hand.
06:53gilliardHow old is 2.3.1?
06:54ToxicFrogTwo years, apparently. I could have sworn I did a lein upgrade more recently than that.
07:21kungiIs there no alter-var-root in clojurescript?
07:25Empperinot that long ago there was no vars as you understand them in ClojureScript
07:25Empperiand still they aren't equivalent to what we have in Clojure
07:27kungiEmpperi: Ok ... Thank you. Then I have to do it properly :-)
07:35spradnyeshjava interop question: i have:- "class A { public enum B {P, Q, R}}" how do i access A.B.P from clojure? i've done [import A :as A], but accessing A.B.P gives "unable to find static field B.P"
07:37Empperiif you have it like that then the enum declaration is instance dependent
07:37Empperiin java terms, this wouldn't work: A.B.P
07:38Empperithis would: new A().B.P
07:38Empperiso same applies to clojure
07:38spradnyeshEmpperi: ohh yes, sorry missed it
07:38spradnyeshthanks :)
07:38Empperinp
07:42spradnyeshEmpperi: http://stackoverflow.com/a/663849/4329629 (nested enums are implicitly static). ;; in my case i'm using a external library w/ no 0-arity constructor for A()
07:42spradnyeshalso, i see a "A.B.P" reference in the java source code (of the library)
07:43spradnyeshbut i'm not able to figure out how that translates to clojure world
07:52spradnyeshfound: A$B/P
07:53spradnyeshsearch for "nested" in http://blog.jayfields.com/2011/12/clojure-java-interop.html
07:54spradnyeshactually, for enum, i had to use (com.blah.blah.A$B/P) w/ the function call
08:02Empperiah true
08:02Empperiinstance specific enums wouldn't make sense anyway
08:02Empperinow that I think of it
08:03EmpperiI just always write static enum when doing java .)
08:19gilliardEmpperi: I don't have a java dev env handy to try it, but you can put fields in enum values can't you? So an instance-specific enum could be used like that? Although I'm not sure what use it would be IRL.
09:01justin_smithspradnyesh: [import A :as A] -- :as isn't valid on imports
09:01justin_smithI think an enum in a class would be an inner class, so you want A$B/P
09:02justin_smithwhere P is a static member of B, which is an inner class of A
09:03spradnyeshjustin_smith: sorry, typo
09:04spradnyeshjustin_smith: yes, that's what i found (see above) A$B/P, but doesn't work w/o fully-qualified-name
09:04justin_smithoh, sorry, I didn't see that
09:06justin_smithspacepluk: inside the ns form you want (:import x.yz.A) which allows A$B/P instead of x.yz.A$B/P
09:06justin_smithbut that's about as much shortening as you can get in clojure I think
09:06justin_smithsorry, misdirect above
09:06spacepluknp :)
09:13justin_smithactually, I think you can (import A$B) and fix his problem ... seems he left though
09:24pseudonymousIs there an easy way to build a lazy sequence of function calls which I can evaluate at some later point ? (I'm trying to create a form for short-circuit evaluation of incoming requests)
09:27snowellpseudonymous: You could quote the calls (turning them into lists) and then (eval) them at said later point
09:27snowellFor all I know, this is a terrible idea/practice, so use with caution ;)
09:28pseudonymoussnowell: that's also the only idea I have right now. But it just seems as if there's something with these lazy sequences that may work .. ?
09:30justin_smithpseudonymous: laziness might be less controlled than you need - it isn't recommended to mix laziness and side effects - what about using delay and @ to force the delay?
09:31justin_smith,(def d (delay (do (prinln "forced") :d)))
09:31clojurebot#error {\n :cause "Unable to resolve symbol: prinln in this context"\n :via\n [{:type clojure.lang.Compiler$CompilerException\n :message "java.lang.RuntimeException: Unable to resolve symbol: prinln 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: prinln in t...
09:31justin_smith,(def d (delay (do (println "forced") :d)))
09:31clojurebot#'sandbox/d
09:31justin_smith,d
09:31clojurebot#object[clojure.lang.Delay 0x2304a617 {:status :pending, :val nil}]
09:31justin_smith,@d
09:31clojurebotforced\n:d
09:31justin_smith,@d
09:31clojurebot:d
09:31justin_smithyou have very precise control with delays
09:33pseudonymousjustin_smith: I basically only intend to use it as a way of getting OR-like functionality - at the first error check which returns non-nil, I want to abort and return the formatted error to the user (thereby not evaluating the other checks) - there's no alteration of program state per se
09:33pseudonymous(But I guess I could wrap each check in a delay clause, it just seems a bit verbose)
09:37snowellpseudonymous: Could you use core.async and have it wait via (alts!) for a message to come over a specific channel?
09:37snowellOr go through the error checks with (some->)
10:01gfredericksamalloy_: I suspect ~mapply came from TimMc
10:01gfredericks~TimMc is the mapply prophet
10:01clojurebotYou don't have to tell me twice.
10:50TimMccan confirm
11:07justin_smithpseudonymous: sounds like you just want every? then
11:08justin_smithor maybe every-pred actually
11:11akabanderSo... I need to build a distributed app that will communicate with other instances over a network message bus. Must be a fairly typical pattern. Any suggestions for where to start investigations?
11:12noncomakabander: the aleph networking library?
11:12noncomin clojure we have stack traces lost in macros... why is this? will there ever be a better handling of this? is it possible at all?
11:13justin_smith,(def even-pos (every-pred #(do (print "even ") (even? %)) #(do (print "pos ") (pos? %))))
11:13clojurebot#'sandbox/even-pos
11:13justin_smith,(even-pos -1)
11:13clojureboteven false
11:13justin_smith,(even-pos 2)
11:13clojureboteven pos true
11:13Bronsanoncom: stack traces lost in macros?
11:13justin_smithpseudonymous: that's "lazy" in the way you want
11:13akabandernoncom: Thanks, checking it out
11:14justin_smithakabander: I've had decent luck with kafka after a pretty steep ramping up
11:14noncomBronsa: if i generate a fn in a macros then if there is an exception in this fn, the exception just points at the macros.. no way to get inside the generated fn
11:15Bronsanoncom: do you have an example? I'm not sure I understand
11:17noncomBronsa: umm, not at the moment. let me then first factor a clear example and then show you. maybe not today. this problem bothers me for a long time but i never fixed it. i will work to resolve this confusion by frist focusing on creating a simple reproduceable example
11:19justin_smithnoncom: one thing that makes stack traces that contain anonymous functions much easier to read is to "name" your anonymous functions (fn some-descriptive-name-here [] ...) - the name will be part of the generated class name for that anon-fn
11:19noncomthe examples in my original program are big and depend on many things so i cannot just present them, it will be hard to follow
11:19noncomjustin_smith: yes! a good advice. i tend to give names to them when i come acros the ones i did not yet name :)
11:21seangroveBronsa: Is it a monumental task to bring t.a.js up to date with cljs master?
11:23psHello all, I’m trying to run some tests with ‘lein cljsbuild test’ using phantomjs. When all tests pass, everything is ok, but if a test fail, phantomjs returns a non zero code, while the invocation of the parent ‘lein cljsbuild test’ returns 0 (no error). I assume lot of people do cljs tests in phantomjs and may be someone knows about a workaround or something I miss
11:25Bronsaseangrove: sorry I was afk yesterday -- the issue you were having was caused by tajs not supporting new cljs version yeah
11:25Bronsaseangrove: not the smallest of tasks I'm afraid
11:27akabandernoncom: I may go with jeromq
11:27noncomakabander: yeah, the mq family of libs seems cool, though i never used it
11:28akabandernoncom: it definitely seems to be robustly featured. Brings a bit of complexity, but I think I'll need some of the flexibility down the road.
11:29noncomakabander: i've heard only good words in address of zeromq, and jeromq seems to be a java replica
11:29noncomso yeah, that's bright! :)
11:32seangroveBronsa: No problem being afk, of course!
11:32seangroveBronsa: And yes, I suspected that between Dec 2014 and Aug 2015 there might have been some big changes, heh
11:36seangroveBronsa: Well, for what it's worth, it'd be great to have :)
11:36Bronsaseangrove: especially with cljs going bootstrapped
11:41seangroveBronsa: especially great, or especially big changes?
11:42seangroveBronsa: The bootstrapped/live-editing aspect is actually what I'm going for here https://www.dropbox.com/s/pvpgprg5kzq8sy4/dato_live_editing_2.mp4?dl=0 - I need t.a.js to properly persist the forms server-side
11:44kavkazHow come if I do (group-by identity (range 10)) I get a sequence which is not in order? I tried playing around with the force evaluation functions but I'm not too familiar with them
11:44kavkazAnd to be honest don't quite know what's happening
11:45justin_smithkavkaz: group-by creates a hash-map, hash-maps are not ordered
11:45seangrovet.a.js to figure out the var/def deps graph for the location of the inserts (while minimizing movement to be git-friendly) and additions to the ns-form, and clj-fmt to keep the changes to a minimum, regardless of where the change is coming from (emacs, vim, browser)
11:48Bronsaseangrove: especially bug changes
11:48Bronsabig*
11:53kavkazjustin_smith: Ah okay. I found that it retains the order of the sequence usually, but not with range
11:54kavkazWell, for any sequence I input by hand and feed it, it retains the order, but not range for example
11:54justin_smithkavkaz: normally = for small inputs
11:55kavkazjustin_smith: Ah, I see.
11:55justin_smithkavkaz: small hash-maps use a different implementation, one that will preserve order
11:55kavkazMakes a lot of sense now
11:55justin_smiththey automatically switch to a non-order-preserving version after hitting a certain size
11:56kavkazInteresting, I'll find another way to do what I need to do. Thanks for your help justin_smith
11:56sdegutisIs defonce lazy?
11:56justin_smithkavkaz: maybe you want a sorted-map?
11:56sdegutis,(do (defonce foo (prn :foo)) nil)
11:57clojurebot:foo\n
11:57sdegutisaww
11:57justin_smith,(into (sorted-map) (group-by identity (range 100)))
11:57clojurebot{0 [0], 1 [1], 2 [2], 3 [3], 4 [4], ...}
11:57sdegutistime for memoize
11:57kavkazjustin_smith: hmm, I'll take a look at that.
11:57justin_smithsorted-map will sort by the keys
11:58rasmusto,(sorted-set 1 2 3)
11:58clojurebot#{1 2 3}
11:58rasmusto,(set [1 2 3])
11:58clojurebot#{1 3 2}
11:58rasmustothat annoys me (the arity difference)
11:58justin_smith,(hash-set 1 2 3)
11:58clojurebot#{1 3 2}
11:58justin_smithrasmusto: comparing the wrong function :)
11:58rasmustoah, there's my answer
12:23seangroveBronsa: I suppose the priority is pretty low for t.a.js? Perhaps you could make some tickets to guide bringing it up to date? I'd like to build some stuff on it for an upcoming talk in Nov.
12:27rasmustois there a tool that will find all hash-sets in my code? (besides `grep set`)
12:28OlajydHi, Bronsa
12:29Bronsaseangrove: the big issue with tajs is that the cljs.core macros do a lot of non-trivial interop with cljs.analyzer and cljs.compiler, in tajs we need to replace that with a custom file that uses t.a internally rather than cljs.analyzer
12:29seangroveOuch, that does sound tough
12:29justin_smithrasmusto: maybe jvisualvm could show you via profiling? or yourkit, I hear that's even better
12:29Bronsaseangrove: meaning that tajs is bound to support specific versions of cljs and requires constant maintenance to keep it up to date with cljs
12:30Bronsaand I simply don't have the time to keep up with dnolen
12:30BronsaOlajyd: hi
12:30rasmustoyeah, I've used jvisualvm before. Maybe its overkill for what I need.
12:31rasmustoI'll use some old-fashioned visual inspection for now
12:31OlajydBronsa, I have a challenge that has been keeping me busy and cant seem to figur it out
12:34BronsaOlajyd: don't ask me specifically for general help, please, ask the channel
12:34Olajydok
12:34BronsaI'll help if I know how or if I have time to do so
12:42OlajydGiven sample rows [[“1” “2” “3”][“4” ”” “5”][“6” “” “7”][“8” “9” “10”][“2” “” “3”]] write a function that will return a pair of rows using the last non empty column (here it is col 1), ie [[[“1” “2” “3”] [“1” “2” “3”]] [[“1” “2” “3”] [“4” “” “5”]] [[“1” “2” “3”] [“6” “” “7”]] [[“1” “2” “3”] [“8” “9” “10”
12:42Olajyd[[“8” “9” “10”] [“2” “” “3”]]] :)
12:43oddcullyam i having a deja vu?
12:44Olajydoddcully :), hardly
12:44Olajyd:)
12:45Olajydoddcully, you remember the problem right, I’m told to solve it by creating a pair like this
12:53justin_smith,(rest (reductions (fn [prev cur] (map #(or (not-empty %) %2) cur prev)) [nil nil nil] [["1" "2" "3"]["4" "" "5"]["6" "" "7"]["8" "9" "10"]["2" "" "3"]]))
12:53clojurebot(("1" "2" "3") ("4" "2" "5") ("6" "2" "7") ("8" "9" "10") ("2" "9" "3"))
12:54justin_smithoh I think I misunderstood
12:57kwladykaOlajyd, i don't know what you want achive, why are there this ugly chars?
12:57justin_smithkwladyka: certain osx clients do that
12:57justin_smithkwladyka: "smart quotes"
12:57expezBronsa: any way to get tools.reader and specify the platform? e.g. read like I'm the cljs reader and then reader like I'm the clj reader?
12:58OlajydKwladyka, I tried avoiding this smart quotes but they just keep comint up
12:58Olajyd*coming
12:58kwladykaOlajyd, it makes it so unreadable :)
12:58akabanderTry using irssi in a console window?
12:59kwladykaOlajyd, anyway what do you want achieve if not what justin_smith show?
12:59akabanderYou need a non-GUI client that doesn't try to insert "smart quotes" (dumb feature).
13:00Bronsaexpez: you men for feature expressions?
13:00Bronsamean*
13:00expezBronsa: yes, dealing with cljc files in refactor-nrepl is proving to more tricky than I had hoped
13:01Olajydkwladyka, I started learning clojure like a month ago and my assignment for the day is `Write a function that Fill in an empty column from the last non-empty value` given a sample row like I gave earlier on
13:02kwladykaOlajyd, is it what justin_smith did?
13:03Olajydoddcully and some others gave a solution using `reductions` and I tendered it as a soluttion but, wasn’t accepted
13:03Olajydkwladyka, oh nope :)
13:04Bronsaexpez: there are a bunch of endpoints that you need to configure to read cljs sources
13:04kwladykaOlajyd, Is it from 4clojure.com ?
13:04Bronsaexpez: https://github.com/clojure/clojurescript/blob/master/src/main/clojure/cljs/analyzer.cljc#L2591 is a good example
13:04justin_smithoh wait
13:05Olajydso thing I need to make them as a pair like a tuple kind of
13:05justin_smith,(rest (reductions (fn [prev cur] (if (every? not-empty cur) cur prev)) [nil nil nil] [["1" "2" "3"]["4" "" "5"]["6" "" "7"]["8" "9" "10"]["2" "" "3"]]))
13:06justin_smith(["1" "2" "3"] ["1" "2" "3"] ["1" "2" "3"] ["8" "9" "10"] ["8" "9" "10"])
13:06clojurebot(["1" "2" "3"] ["1" "2" "3"] ["1" "2" "3"] ["8" "9" "10"] ["8" "9" "10"])
13:06justin_smithoops
13:08Olajydsuch that the first element in the pair vector (tuple), is the vector that is the last non epmty row (based on col 1) and the second pair vector is the normal row with empty or non-empty col :)
13:08BronsaOlajyd: how do you expect to learn clojure if you ask others to do your assignments though?
13:08luxbockI want to serialize a sorted-map with a custom comparison fn as EDN so that I can use it with both Clojure and CLJS, so I'm wrapping it in a record, giving it a print-method that reads it through its own constructor fn
13:09luxbockso now I'm re-implementing all the protocols/interfaces that Clojure maps use
13:09luxbockdoes this seem reasonable?
13:09OlajydI’ve tried an approach already Bronsa, I used an atom to keep track of previous state
13:11BronsaOlajyd: reduce already keeps track of previous state for you
13:11expezBronsa: That looks great. Are you keeping this behavior? If I do :features #{:cljs} with the regular reader I still get the clj branch if there are multiple branches.
13:11Bronsaexpez: by regular reader you mean LispReader.java?
13:11OlajydBesides, I want to knw how it can be done right, I could have used stackoverflow u knw, but I want to learn, right :)
13:11oddcullyluxbock: wouldn't that mean that you would have to eval the fn?
13:12expezBronsa: yes
13:12Bronsaexpez: if that's the case that would be a serious bug, seems unlikely tbh
13:13oddcullyluxbock: or in other words: could i manipulate the edn to make your code execute evil things?
13:13luxbockoddcully: what do you mean by eval the fn? my plan is to add a tag to data_readers.cljc so that it should work the same in Clojure and CLJS
13:13Bronsaexpez: oh wow you're right wtf
13:14Bronsawow
13:14Bronsa,(read-string {:read-cond :allow :features #{:cljs}} "#?(:cljs 1 :clj 2)")
13:14clojurebot1
13:14Bronsa,(read-string {:read-cond :allow :features #{:cljs}} "#?(:clj 1 :cljs 2)")
13:14clojurebot1
13:14Bronsathis is seriously broken
13:14Bronsapuredanger: ^
13:14expezBronsa: Could you please keep this as an optional behavior? The default is retarded for use in tooling.
13:14Bronsaexpez: no i mean LispReader is broken
13:14luxbockoddcully: I don't think it would be an issue
13:14Bronsaexpez: tools.reader implements the expected behaviour
13:15expezBronsa: They featured it, IIRC. The platform conditional is always present.
13:15luxbockthe data the function receives is always trusted
13:16expezBronsa: However, note that the Clojure reader will always inject the platform feature :clj as well. For platform-agnostic reading, see tools.reader.
13:16expezBronsa: http://clojure.org/reader#The%20Reader--Reader%20Conditionals
13:17Bronsawow
13:17puredangerThe reader in Clojure is not intended to be platform-generic
13:17BronsaI see
13:17puredangerTools.reader is
13:17BronsaI guess it kinda makes sense
13:18BronsaLispReader doesn't have the configurable endpoints necessary to correctly read cljs
13:18puredangerNor should it
13:20Bronsathe order-dependant behaviour might be confusing though
13:22puredangerIt's like cond - the first successful test is chosen
13:23puredangerThat's why it's reader cond-itionals
13:23Bronsapuredanger: yeah, I meant the cond-like behaviour + the implicit feature
13:24Bronsapuredanger: I think expliciting that :clj is an implicit :feature in the read/read-string docstring would help
13:24puredangerI agree the implicit feature is potentially confusing. The original version was not like that and I don't love it.
13:25blake_OK, so, I'm using Monger to read some data, and I'm using find-maps which is lazy. As I'm traversing the find-maps result, the lazy chunking kicks in, and one of the records in my block is causing an exception. I mentioned this last week, but I'm still unclear what to do about it. Not just here, but generally. How do I figure out what record, or perhaps more importantly, who do I catch the exception and proceed while only skipping the bad record?
13:25PupenoWith ring/compojure, how can I have an object that is not being used by more than one thread at a time but that it's being re-used over time? http://stackoverflow.com/questions/32255188/ensuring-single-threadness-of-an-object-with-ring-and-compojure
13:28expezpuredanger: what was the rationale for constraining the reader in this manner?
13:28blake_Pupeno: Wouldn't keeping them in atoms do the trick? Atoms are thread safe.
13:28blake_blake_: Although I guess that doesn't prevent one thread from sharing with another.
13:29Pupenoblake_: atoms are to share data between threads, the opposite of what I want to do.
13:29Pupenoblake_: a dynamic var is the closest to want I want, but I'm not sure *when* I should set it.
13:30Bronsaexpez: LispReader is strictly a clojure reader, it technically can't read cljs
13:30expezaha
13:30Bronsaexpez: main (probably only) issue is stuff that requires namespace awareness
13:30Bronsalike ::foo or `bar
13:30blake_Pupeno: How do you know when the thread is done with the engine?
13:31Bronsatools.reader has configurable endpoints for that, LispReader is hardcoded for clj
13:31Pupenoblake_: I don't and that's what I want, when the thread is re-used, I want the engine to be re-used.
13:32blake_Pupeno: Oh! Well, couldn't you just map the thread to an engine?
13:33Pupenoblake_: that's more or less what I want to achieve.
13:34blake_Pupeno: I guess I'm not getting what this would take beyond a regular map. (assoc engine-map thread engine)?
13:34blake_Maybe make engine-map an atom?
13:35blake_Why wouldn't that do it?
13:35Pupenoblake_: how do engines ever get removed when a thread is killed?
13:37blake_Pupeno: When you kill the thread, you take it out of the engine-map?
13:37PupenoI am not killing the threads, the threads are managed by Jetty or HTTPKit or whatever environment is running my app.
13:38PupenoI am not creating them either.
13:42blake_I feel like I'm missing a big piece here.
13:43PupenoJetty, HTTPKit, Aleph, whatever web server thingy will create threads, processes, re-use threads, whatever. I don't know. I have to ensure that no scriptengine is ever used by more than one thread at the same time and I want to re-use them because they are expensive and I'm happy to have one per thread so that locking is not a problem.
14:20blake_Pupeno: Maybe use get-thread-bindings?
14:21blake_No, I guess that wouldn't help.
14:21Pupeno:)
14:25amalloyPupeno: you want a thread-local probably
14:26amalloyyou can use java's ThreadLocal manually, or flatland/useful has a macro wrapping it
14:26Pupenoamalloy: what do you mean by that exactly?
14:26Pupenoamalloy: ah, ok.
14:37blake_So...yeah...exception caused somewhere in chunking and I'm trying to figure out how to trap/skip the errant record. Anyone?
15:33snowellSay I have an atom pointing to a collection [1 2 3]
15:33snowellAnd I want it to be [2 3 4]
15:33snowellIs there a way to swap! the map function there, or can I only do (reset a (map inc @a))?
15:34snowellswap! only seems to work if the function takes the current value as the first arg
15:34snowells/reset/reset!
15:34Bronsa,(def a (atom [1 2 3]))
15:34clojurebot#'sandbox/a
15:34Bronsa,(swap! a (partial mapv inc))
15:34clojurebot[2 3 4]
15:34snowellHoly crap. It's so beautiful
15:34snowell(inc Bronsa)
15:34lazybot⇒ 120
15:35snowellI never remember partial :D
15:35tatutI'm partial to the #(mapv inc %) form (excuse the pun)
15:36amalloysnowell: even if you never remember partial, you can always reorder arguments by just using an intermediary lambda as a middle man
15:36amalloy(which is what tatut is suggesting)
15:36snowellYeah, which I thought of doing
15:37snowellBut when swap! works it always just looks nicer
15:37tatut,(swap! a #(mapc inc %))
15:37clojurebot#error {\n :cause "Unable to resolve symbol: mapc in this context"\n :via\n [{:type clojure.lang.Compiler$CompilerException\n :message "java.lang.RuntimeException: Unable to resolve symbol: mapc 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: mapc in this co...
15:37tatut,(swap! a #(mapv inc %))
15:37clojurebot[3 4 5]
15:37tatuttypo
15:37snowellThanks everyone
15:37snowell(inc tatut)
15:37lazybot⇒ 2
15:39amalloysnowell: well yes, you absolutely must use swap!. i was not recommending you use reset!
15:52ectricso if I develop an app with luminus using +jetty, then use lein ring uberwar and throw it on tomcat (elastic beanstalk), how does that work? is there a jetty server running in tomcat? or if i used +immutant, an immutant server?
15:57justin_smithectric: jetty is a local replacement for what tomcat does
15:57justin_smithboth are containers that can run your war
15:58justin_smithjetty is used in-process - you don't even start a separate container, but it loads up your code the same way tomcat would when deploying
16:00ectricjustin_smith: sorry, i'm the whole java tomcat ecosystem is pretty foreign to me. so in that case, when i upload my war for my app to tomcat, it is still basically using the embedded jetty server?
16:00ectricjustin_smith: *new to the java ecosystem
16:00justin_smithectric: no, not at all
16:00ectricjustin_smith: so it is ignored, and tomcat is used
16:00justin_smithectric: locally, you put something in a plastic bag, on the server it goes in a canvas bag
16:00justin_smithbot hare just bags
16:00justin_smithectric: on the server, jetty isn't present
16:01justin_smithectric: tomcat and jetty are containers, the intention is that you can just pick one and it will work
16:01justin_smithyou don't want more than one, you just use the one that is convenient for a given environment
16:02justin_smithso on a server you want tomcat (log rotation, hot reload, hosting multiple apps, diagnostics, advanced configuration options) and locally you want jetty (simple, few options, few features, just enough to run your app)
16:02justin_smithor maybe you don't want tomcat, it's a choice
16:03expezIs there a blogpost around describing how to use the new cljs analyzer.api?
16:03ectricjustin_smith: ok, that makes a lot of sense thanks.. but like in my app core's -main function, i call a function that ultimately calls like jetty run server. is that somehow stripped out with lein ring uberwar?
16:03ttt_fffdoes clojure's 'schema' from prismatic provide anything like haskell's GADTS + typeclasses ?
16:03justin_smithectric: tomact never calls your main
16:04ectricjustin_smith: ahhh. what does it call/how does the thing get started?
16:04justin_smithectric: lein-ring generates the code that tomcat can call to launch your app
16:04justin_smithectric: based on your telling lein-ring what your handler is, etc.
16:05ectricjustin_smith: that was the piece I was missing! makes sense now.
16:05ectricjustin_smith: thanks a lot for the explanation
16:05justin_smithnp!
16:06ectricjustin_smith: is tomcat considered pretty good?
16:07justin_smithectric: it has some features people like, but it's also a bit of a behemoth
16:08ectricjustin_smith: gotcha
16:09justin_smithfor example I have used it sometimes just because it's what elastic beanstalk builds on, and it was convenient to use elastic beanstalk
16:12ectricya, that's why i'm using it. elastic beanstalk seemed like the easiest way to get my luminus app hosted - and it has been easy
16:25mikerodBronsa: seancorfield I have been hitting up against this complicated issue with AOT vs JIT and clj 1.7.0 changes
16:25mikerodI've tracked through all of the Jira history and google groups to be sure I'm up to speed
16:25mikerodI understand most of it besides this last point "it should not ship AOT versions of other libraries that folks might also be using via JIT "
16:26mikerodI understand it as the danger is having both AOT compiled lib class mixed with the lib coming in as just clj files
16:26mikerodHowever, wouldn't the compiler prefer loading the class files to the clj files if the class file has a modified time > clj file?
16:27mikerodI can't seem to see the way that I'd get a forced reload of the clj file to cause the conflict with the pre-existing AOT class files
16:28mikerodI understand the 1.7.0 choice of clj class loading to prefer the in-memory version. I just don't see how the JIT happens at all in the presence of the AOTed files
16:28puredangerare you using deftypes?
16:28mikerodpuredanger: yes this was a deftype one
16:28mikerodI'm hitting the "Caused by: java.lang.ClassCastException: schema.utils.SimpleVCell cannot be cast to schema.utils.PSimpleCell"
16:28mikerodthere was some people complaining about this one when the 1.7.0 stuff was coming along
16:29puredangerI believe the issue is with deftype constructors (which load via the new bytecode) vs other means of loading, which load via Class.forName() through the DynamicClassLoader which takes into account the cached classes
16:29mikerodbut I didn't see any concrete answers. It was highly related to the CLJ-1639 and CLJ-979 chain of Jiras though I'm fairly sure
16:29puredangerhttp://dev.clojure.org/jira/browse/CLJ-1741
16:30mikerodI've read this Jira and thought it was related as well.
16:30mikerodMy main confusion is how am I even getting a dynamic loader class along with the AOT/static loaded class if the namespace isn't being forcefully reloaded?
16:31mikerodI see that the modify time of the class files __init are all later than the schema clj files on the classpath
16:31mikerodso I can't see how the compiler would choose to recompile those files to cause this "duplicate" class definition for the deftype
16:32mikerodI understand the issue with `compile` not checking the `loaded-libs` too
16:33mikerodI'm not calling `compile` anywhere explicitly or something like that though. I'm actually kicking off the compilation chain via a `require`
16:33puredangerthere are multiple use cases (that present errors in similar ways) through either AOT or reloading
16:34mikerodhmm.. ok
16:35puredangersorry, I don't have any of this in my head so it's taking a bit to boot my brain :)
16:35mikerodI'm still baffled at how I can even get two versions of these deftype classes. It should only be compiled once. (brain hurts)
16:35mikerodNo problem. This is a complicated trail of issues to sort through indeed.
16:35hiredmanmikerod: many times these issues come down to code load order, if you import a deftype before requiring the namespace that generates it and that kind of thing
16:35puredangerwell like in CLJ-1741 you end up with two versions because a constructor constructs via one classloader and a class literal is loaded via a different one
16:36puredangerthe deftype constructor uses the new bytecode which uses the context classloader, which is typically not a DCL, so won't check the cache
16:37hiredmanthe loader order stuff will manifest as the project code failing to load if you don't aot
16:38puredangerthe changes in 1.7 make class loading more universal across many paths to always be cache-aware (but the new bytecode case falls outside that)
16:38puredangerso it's not even that a recompile is occurring, but just that two classloaders loaded the identical class (which the jvm treats as two different classes)
16:43puredangerhave you tried separating the deftype definition into a different namespace than where it is used? that seems to cut down on the most problematic scenarios
16:44mikerodpuredanger: At what point do two separate loaders load the class?
16:44mikerodpuredanger: no, I think I'm going to remove the AOT entirely because it seems dangerous. It was a lib we don't control - Prismatic schema
16:44puredangerinstantiating a deftype instance and loading a class literal
16:44mikerodI was just trying to get some understanding of this issue
16:44mikerodand I couldn't understand where 2 loaders are trying to load the same class
16:44mikerodthat is interesting
16:45mikerodI will try playing around with that to understand how those paths go
16:46mikerodMy particular case really is a fallout of CLJ-322 I think
16:46puredangeryes, that is the root cause of much pain
16:46mikerodthat AOT'ing your own stuff causes all your deps to be AOT'ed and included as well
16:46mikerodthat is a sneaky issue
16:46mikerodmakes AOT hard to work with
16:46puredangerthe solutions are widely varying if you follow that ticket and the related design pages
16:46mikerodespecially if I get this double-loader for a class issue with deftype :P
16:46puredangerI think clearly fully-transitive AOT is almost never what you want
16:47mikerodpuredanger: yeah, I haven't delved into that entire Jira yet, I intended to get to that next up
16:47puredangerit has tendrils. I have spent many hours reading through all of it and the solution is still not clear to me.
16:48puredangerin Clojure, the granularity of compile is a single ns but in your typical build it is "some or all of my project code"
16:48puredangerthose two levels have some impedance mismatch in goals
16:49puredangerit's tricky to describe to the low-level compile function: "just do this much, no more"
16:49Bronsamikerod: sorry, been a while since I hacked that part of Clojure, can't really help without a minimal reproducible case
16:49mikerodyeah, I can understand that leading to a sticky situation
16:49mikerodBronsa: fair enough, I certainly don't have one of those
16:50mikerodMy case sounds about the same as when core.typed included AOT version of core.cache
16:50mikerodand that was breaking when a lib used core.typed and had the non-AOT core.cache on the path
16:50mikerodthat's why I related it directly to that Jira and was curious
16:50Bronsathe unfortunate situation is that there is a disconnect between logic in the classloader, the compiler and the "compiling functions" in clojure.core
16:50mikerodI may have enough to go off of now to try to understand what the compiler is doing in my particular case
16:51Bronsathey handle compiling, loading and reloading in similar but slightly different ways that are not really compatible all the time
16:51puredangerI have compile to believe that having the output directory of the compile function on your input classpath is evil (despite that being stated as a requirement)
16:51mikerodyeah, I've been reading (and rereading) through a stack of Jiras around this a while to follow along with where things are
16:52Bronsaclojurebot: puredanger has compiled to believe
16:52clojurebotPardon?
16:52Bronsa:(
16:52puredangerheh, come to believe
16:52mikerodhaha
16:52Bronsapuredanger: I agree with that argument btw
16:52puredangerwhen compilation generates classes, it should have effects on the runtime state
16:52Bronsait shouldn't* ?
16:52puredangerbut its outputs should not affect the input classpath
16:53Bronsaah, right
16:53mikerodthat makes sense
16:53puredangerwhen multiple compiles have in a row in "wrong" orders, they currently trip each other up
16:54puredangerI went back and read all the irc history when Rich was putting this in and things he was trying to do at the time and the realities of where we are now are simply different
16:54Bronsapuredanger: seems like a simple solution would be to change the docs around that and fix the tooling then?
16:55puredangerthere are no simple solutions re AOT :)
16:55puredangerI think there are also needs to be a good solution to 322 which is likely to also affect tooling
16:56puredangerbut then I think there are still reload use cases with issues (like where this conversation started)
16:57puredangerthat needs more research. imho, I do not think we should add more tracking state to the runtime, which is the direction of many of the patches.
16:59puredangerI'm curious how things would change if, for example, deftype constructors didn't use "new", or if we set the context classloader to a different loader around the use of "new"
17:01Bronsapuredanger: we can't really change the classloader used by new
17:01puredangersure you can
17:01puredangerit'll use the context classloader
17:06Bronsapuredanger: it seems to me that once the classfile is loaded by the system classloader instead of DCL, `new` instructions will instantiate the classes resolved by that same classloader, no matter what the context classloader is
17:06puredangerat least I think it does :)
17:07mikerodI think this is outside of my understanding on how the new is used in the deftype now
17:07mikerodI thought the stack would just have whatever class reference you were going to be new'ing
17:08mikerodguess it is time for me to do more reading in that dept
17:10amalloymy understanding is the same as Bronsa's, but i am not really an expert on the topic
17:10puredangerI believe there is no reason that we cannot control the classloader used to load anything we're doing in Clojure
17:11Bronsapuredanger: say class C causes loading of class D
17:11Bronsaand we load C from a classfile
17:11Bronsawe have no way of having D be loaded from our DCL
17:11Bronsathe jvm will use whatever classloader it was used to load C to load D
17:11puredangeris C code we created the bytecode for?
17:12puredangerif so, then can't we create different bytecode?
17:12Bronsapuredanger: I'm assuming we're in a situation where we want to load C from disk and D from memory
17:13Bronsapuredanger: sure, we just can't use `new` instructions
17:13puredangerwell that's what I'm saying
17:13Bronsaah, missed that then :)
17:14BronsaI actually thought of trying that a while ago but I was worried about the performance implications of using Class/forName+newInstance vs new
17:17puredangerlike I said - needs research
17:17puredangerit might be faster than you think
17:22puredangeriirc there is a buried way to construct things for serialization too that's kind of sneaky
17:40sdegutisWhat are the benefits and drawbacks of putting :aot :all at the root of your project map in project.clj?
17:44sdegutisI imagine it would terribly mess with dynamic code reloading at runtime right?
17:45sdegutisBut are there other hidden disadvantages, such as vars not having metadata available at runtime?
19:24hiredmanob