2014-09-15
| 01:06 | danielcompton | Our long national nightmare is finally over https://github.com/technomancy/leiningen/issues/1629 |
| 01:30 | jarodzz | hi, guys |
| 01:30 | jarodzz | anyone has experience to add clojure into exisitng java project? |
| 01:48 | seancorfield | jarodzz we run Clojure embedded inside a Java runtime, an app running on Tomcat... what's your question? |
| 02:12 | kenrestivo | i just realized my (--> love for the threading operator) is a legacy | of | being |a | unix | shell | guy |
| 02:43 | augustl | kenrestivo: i/o for the win |
| 02:46 | kenrestivo | has anyone tried to create a standalone windows/mac executable from a clojure program? i looked at the .iss file of leiningen-win-installer for ideas, and it looks intimidating. |
| 02:46 | kenrestivo | also, just dealing with the oracle dependency as a separate install step might stop users from bothering. |
| 02:47 | kenrestivo | like, zoinks scoob: https://bitbucket.org/djpowell/leiningen-win-installer/src/9c971dd33439/leiningen-installer.iss?at=bitbucket-master |
| 02:49 | amalloy | kenrestivo: the oracle dependency? you're worried about users who don't have java installed? |
| 02:49 | kenrestivo | yes. |
| 02:50 | amalloy | well, good luck. no clever ideas from me |
| 02:52 | kenrestivo | haha, no prob. this may be an app i have to write in C and wxwindows or similar. but it'd sure be nicer to write in clojure/seesaw instead. |
| 03:00 | papachan | hi there |
| 03:01 | seancorfield | evenin' papachan |
| 03:01 | augustl | kenrestivo: you can redistribute openjdk afaik |
| 03:01 | augustl | not sure how well that works in practice |
| 03:01 | papachan | i am trying to make an assoc inside a function but i still cannot find a way out |
| 03:02 | kenrestivo | augustl: oh cool, thanks. should work fine actually. but there would still need to be all that hairy .iss checking to see if there's a working vm there already first. |
| 03:03 | augustl | you can of course also ignore that and always use your bundled openjdk runtime :) |
| 03:03 | papachan | https://code.stypi.com/papachan/test.clj |
| 03:03 | augustl | papachan: what's the code? |
| 03:03 | papachan | augustl, i just paste it |
| 03:04 | augustl | papachan: there's no call to "assoc" there |
| 03:04 | papachan | auguts no, because nothing works were working |
| 03:04 | papachan | so i print the same local hasmap |
| 03:04 | seancorfield | that code prints results - it doesn't return anything |
| 03:05 | augustl | papachan: what do you want/expect that code to do that it doesn't do now? |
| 03:05 | papachan | yeah |
| 03:05 | papachan | this code print the two lines there is in comment |
| 03:06 | papachan | for example it iterate over a hashmap |
| 03:06 | papachan | and put it in another hashmap structure |
| 03:06 | papachan | i need to merge each result into a new hashmap |
| 03:06 | seancorfield | papachan I think you're looking for the merge function? |
| 03:06 | papachan | i have tried womething |
| 03:09 | papachan | as i understand clojure way, it always return the merge result of each row, not the sum of all |
| 03:10 | papachan | m is a local hashmap so its stay immutable, my merge work for one row, but do not merge all the resulds |
| 03:10 | seancorfield | ah, so you want reduce |
| 03:10 | seancorfield | reduce is the clojure way of looping of things to make a new thing |
| 03:12 | seancorfield | the local m map would be the initial map you start with, and params would be the collection you reduce |
| 03:13 | seancorfield | and then you'd define a function to merge in each part of the collection to that initial map |
| 03:13 | papachan | i have tried something like this |
| 03:15 | papachan | (reduce (fn [m [k v]] (assoc m k v)) y x) |
| 03:21 | papachan | seancorfield yes i understand that way, but i cannot change the map structure with reduce and assoc, i havent find the way |
| 03:21 | papachan | i have tried with (reduce #(assoc % (keyword (str %2)) %2) y x) |
| 03:23 | seancorfield | papachan https://www.refheap.com/90268 |
| 03:23 | ollivera | Given the Authentication example below, how can I assign "conn" to a global var. I tried def, but (mg/authenticate db u p) returns a boolean. |
| 03:23 | ollivera | http://clojuremongodb.info/articles/connecting.html |
| 03:24 | podviaznikov | Hi, I'm trying to scrape cyrillic web page with enlive. Parsing seems to work but I can't see readable text in the console(both lighttable and REPL). Does anyone know if it's some issue with console or I need to specify encoding before enlive html parsing? |
| 03:27 | papachan | seancorfield it works. really cool. |
| 03:29 | zot | does clj have a way to print out structures in a way that they can be pasted back into the repl (a la python's %r format)? |
| 03:30 | amalloy | zot: that's the default print format. just put a ' in before you paste, to quote the data structure |
| 03:33 | zot | ok, then what i'm printing must not be pure map/vector/string :/ |
| 03:34 | zot | amalloy: tnx :) |
| 04:06 | kenrestivo | so if i wanted to, say, emit liquidsoap from clojure, is this still the best general approach to take? http://clojure-doc.org/articles/tutorials/growing_a_dsl_with_clojure.html |
| 04:07 | kenrestivo | (liquidsoap is itself a dsl, kind of ruby-like syntax, which was written in ocaml) |
| 04:08 | clgv | kenrestivo: you want general advice on best practices to create a DSL with clojure? |
| 04:08 | kenrestivo | that'd be a good start, yes |
| 04:08 | kenrestivo | i've seen lots of stuff in the past, i just don't know what's the current best thinking on the topic |
| 04:09 | clgv | well, usually you start writing functions that do what you want. when you encounter cases in your DSL where you need specifiy evaluation semantics you introduce a macro for that |
| 04:09 | clgv | specification can be done in pure clojure data (maps, vectors, sets) |
| 04:10 | kenrestivo | ok, that's generally what i've seen. i didn't know if there was any spiffy new way to do it nowadays, like "you'd use tools.analyze.foo" or similar |
| 04:10 | kenrestivo | doing it with simple functions and macros is just fine with me, if that's still the recommended way |
| 04:11 | clgv | no, the tools.analyzer stuff is mainly for wrinting clojure(script) compilers - though it can be used in tangantial topics as code analysis etc |
| 04:11 | clgv | *writing |
| 04:14 | clgv | kenrestivo: usually it hurts to do too much special. for example I used a special registry for a DSL just too switch back to clojure namespaces some months later |
| 04:15 | kenrestivo | ok, thanks |
| 05:12 | zot | ok, just found out the hard way that creating a java buf'd file writer in a let does *not* get it nicely flushed/closed. is there a graceful to handle this? the let stmt handles input from both stdin or from the command line, and uses bind, which makes with-open impractical. ideas? (code snippet coming...) |
| 05:14 | zot | https://gist.github.com/anonymous/e381f4df594421cbbf75 — without the .flush call, my result doesn't make it out :/ |
| 05:15 | Bronsa | zot: use with-open to automatically close the buffer |
| 05:15 | amalloy | zot: what makes you think with-open is impractical? it is easy to apply here |
| 05:15 | zot | naivety, clearly :) |
| 05:16 | amalloy | (with-open [out (...)] (binding [*out* out] ...)) |
| 05:16 | zot | but then it will close my stdout after the stmt, correct? |
| 05:17 | amalloy | no? |
| 05:17 | clojurebot | no is tufflax: there was a question somewhere in there, the answer |
| 05:17 | zot | in my head the jvm would have done a nice garbage collection-y thing on the object at the end, which would include flushing the buffers. |
| 05:18 | zot | amalloy: the descr from with-open suggests otherwise — "and a finally clause that calls (.close name) on each name in reverse order" |
| 05:18 | amalloy | zot: a correctly-written program can never depend on garbage collection for its correctness |
| 05:18 | zot | perhaps i misread it? |
| 05:18 | amalloy | indeed, it will close out, the temporary thing you created |
| 05:18 | amalloy | but not the stdout for your process |
| 05:20 | zot | if stdout is specified as the output, then it would also get closed; it probably doesn't matter here, but i dislike closing stdout, since i will almost certainly later put print stmts, etc., there, and forget that it's dead :/ |
| 05:21 | amalloy | huh? you are totally focused on imaginary side effects of a thing that is not happening |
| 05:23 | zot | https://gist.github.com/anonymous/346827c515696975e94a - for me, only "line 1" is printed, presumably due to stdout now being closed |
| 05:24 | amalloy | yes, good lord, don't write that |
| 05:24 | amalloy | nobody said to write that |
| 05:24 | zot | but that's my "imaginary" case |
| 05:24 | zot | in the let stmt of my code, out can be *out* as well. |
| 05:25 | zot | hence my side effect |
| 05:25 | amalloy | i see. that was an easy-to-miss subtlety |
| 05:26 | amalloy | then you will need to flush, or use println, which flushes |
| 05:26 | zot | now that we've got that out of the way … any great ideas? :) |
| 05:27 | zot | yeah, i figured out what the problem was when i used println, but prefer to be explicit with flush since it's required. |
| 05:27 | zot | but technically the file still isn't closed, so the argument about relying on GC side effects still carries some philosophical weight |
| 05:29 | amalloy | yeah, if you want to have different behavior for the stdout vs file cases, you will have to do more than just bind *out* |
| 06:35 | lazylambda | guys, I have a question |
| 06:36 | lazylambda | let forms in clojure aren't lambdas like scheme and common lisp, right? |
| 06:37 | clgv | no, they are not. are they in CL? |
| 06:38 | clgv | but maybe you interpret your question differently. can you be more specific? |
| 06:38 | lazylambda | yea, (let ((a 1) (b 2)) (+ a b)) is just syntactic sugar for ((lambda (a b) (+ a b)) 1 2) |
| 06:38 | lazylambda | in scheme and common lisp |
| 06:39 | lazylambda | in clojure, the semantics are different |
| 06:40 | clgv | no in clojure it would look like the following java snippet: final long a = 1; final long b = 2; return a + b; |
| 06:40 | lazylambda | exactly |
| 06:40 | lazylambda | I was just making sure |
| 06:40 | clgv | when you use a java decompiler you'll see that pattern |
| 06:41 | lazylambda | I was just going through SICP with clojure, and the clojure let was behaving differently than in scheme and CL |
| 06:42 | clgv | there is another distinction clojure's `let` is more like `let*` in CL |
| 06:43 | lazylambda | you are correct, that didn't hit me |
| 06:45 | Bronsa | lazylambda: I don't think any cl/scheme impl actually implements let in terms of lambda |
| 06:46 | bja | Bronsa, chicken scheme might, but how it implements it and what happens after compilation don't seem to bear any resemblance to each other |
| 06:46 | lazylambda | @Bronse it does, you'll find that explained in SICP and in Paul Graham's Ansi common lisp..it makes sense if you translate one into the other |
| 06:47 | lazylambda | @Bronsa it does, you'll find that explained in SICP and in Paul Graham's Ansi common lisp..it makes sense if you translate one into the other |
| 06:48 | lazylambda | Bronsa: I suppose implementations are free to do what they want though, but semantically they are both equivalent |
| 06:48 | Bronsa | lazylambda: no, all they say is that (let ((a 1)) a) is equivalent to ((lambda (a) a) 1), but in reality they are not implemented in terms of one another |
| 06:50 | clgv | Bronsa: that's what I suspected |
| 06:59 | lazylambda | Bronsa: I think you're right, I just looked it up |
| 07:06 | lazylambda | I am new to clojure, folks. What open source projects would you recommend for a new comer? |
| 07:09 | rweir | to learn idiomatic clojure form? |
| 07:12 | hyPiRion | I would say that playing around with whatever you're interested in is good |
| 07:12 | hyPiRion | But 4clojure is generally nice to do to learn clojure |
| 07:13 | clgv | lazylambda: yeah try out 4clojrue |
| 07:13 | mskoud | Can i get a list of fields from a record? (like python's dir function) |
| 07:14 | lazylambda | thanks, I already started solving some problems on 4clojure. |
| 07:14 | lazylambda | I am also working on this bug in refheap |
| 07:15 | hyPiRion | lazylambda: ah, nice |
| 07:15 | lazylambda | I'd like to get into core.logic as well, but I want to finish reading the reasoned schemer first |
| 07:16 | rweir | mskoud, (keys) |
| 07:16 | lazylambda | Are there any open source AI projects done in clojure? |
| 07:16 | mskoud | ah : (map #(.getName %) (.getFields Site)) |
| 07:17 | mskoud | ok. keys is nice if i have an instance. |
| 07:18 | corecode_ | lazylambda: i think the term AI is not used anymore |
| 07:18 | corecode_ | now it's machine learning, etc. |
| 07:21 | tachibana | it's beatiful ;] |
| 07:22 | lazylambda | corecode_: lame :P.. I am more interested in rule based systems, but yea, machine learning is the hot thing today |
| 07:22 | tachibana | r u the lamda that is truly lazy?? |
| 07:24 | clgv | corecode_: it's just not "cool" anymore - but it is still used and distinct from machine learning ;) |
| 07:25 | clgv | tachibana: yeah you have to call him to get an answer ;) |
| 07:25 | lazylambda | I think symbolic AI is more interesting than the statistical stuff |
| 07:26 | hyPiRion | lazylambda: I think there's some work with core.logic out there |
| 07:26 | tachibana | stumped me with that one |
| 07:27 | tachibana | who's core |
| 07:27 | tachibana | different times call for different measures |
| 07:30 | lazylambda | hyPiRion: Nice, I'll look out for that. Thanks. |
| 07:30 | daniel___ | anyone got a thinkpad E540 and can vouch for it? |
| 07:32 | clgv | daniel___: you need someone you can sue if it ends up being crap? :P |
| 07:32 | daniel___ | yeah clgv |
| 07:33 | hyPiRion | lazylambda: I wanted to work on the core.logic version of https://github.com/webyrd/relational-parsing-with-derivatives – but I didn't get time. It's not AI, but it's certainly useful core.logic material |
| 07:33 | daniel___ | pls provide your address and contact details |
| 07:33 | clgv | good look searching ;) |
| 07:33 | clgv | *luck |
| 07:33 | hyPiRion | I know there's other stuff out there, but unfortunately I'm not that into the core.logic work yet |
| 07:33 | daniel___ | im not american, dont just sue people willy nilly |
| 07:39 | CookedGryphon | Which of the automatic test refreshing lein plugins actually works for normal clojure.test? |
| 07:40 | CookedGryphon | Midje doesn't show me the output of my non-midje tests, just says pass or fail, test-refresh fails, quickie always says everything passed, I've tried a few others too |
| 07:42 | clgv | CookedGryphon: isn't there "lein autotest"? |
| 07:48 | CookedGryphon | clgv: link? the lein-autotest I found on github looks old (last updated 4 years ago and still using lein 1) |
| 07:48 | lazylambda | hyPiRion: Nice, I'll check that out |
| 07:48 | CookedGryphon | clgv: and doesn't seem to run anything... |
| 07:52 | CookedGryphon | and cider-test-mode doesn't work, borks out with a syntax error... |
| 07:52 | clgv | CookedGryphon: damn ok, I just remembered that one |
| 07:52 | CookedGryphon | I think I'm stuck going back to the terminal manually |
| 07:53 | clgv | doesnt expectations have an autorunner? |
| 07:53 | CookedGryphon | well yeah, but I'm not using the expectations test framework |
| 07:54 | clgv | CookedGryphon: I thought it might integrate with deftest - but I am not sure, you'd have to check |
| 07:55 | CookedGryphon | It probably does, but it still feels like overkill to pull in an entirely different test framework... |
| 07:55 | CookedGryphon | surely there must be a plain clojure.test autorunner which works |
| 07:55 | clgv | CookedGryphon: otherwise you could steal from the other autorunners to write one for deftest |
| 07:57 | clgv | CookedGryphon: according to the readme lein midje should run clojure.test tests |
| 07:59 | CookedGryphon | yeah, it does |
| 07:59 | CookedGryphon | but it was losing the output of my test.check and just showing me pass/fail status |
| 07:59 | CookedGryphon | which isn't useful for actually fixing the test |
| 07:59 | clgv | hwat output? error messages on failure? |
| 07:59 | CookedGryphon | *but* I've just realised taht it was printing it, just elsewhere |
| 08:00 | CookedGryphon | yeah, the actual information about what failed and how |
| 08:00 | clgv | probably the reporting part does not integrate well` |
| 08:00 | CookedGryphon | yeah, but i've just realised if I'm only dealing with one failing test at a time, the output is manageable |
| 08:01 | CookedGryphon | so I'm happy enough for now |
| 08:01 | clgv | but there is definitely room for improvement |
| 08:14 | agarman | https://github.com/CareLogistics/somni <- it's yet another Ring routing lib. |
| 08:17 | clgv | those grow like grass lately ;) |
| 08:27 | agarman | yeah |
| 08:28 | agarman | it's unfortunate. as hard as we tried, compojure, bidi, gudu, liberator all left us writing code we didnt' like |
| 08:34 | zot | is there a psuedo-standard place for test fixtures/inputs? foo/test/resources? |
| 08:35 | clgv | zot: "project-root/test" is the convention in lein, but you can change it in the project.clj |
| 08:36 | clgv | ah you meant input data |
| 08:36 | zot | my code is in there; but one of my tests is more end-to-end-ish and needs external inputs |
| 08:36 | zot | beat me to it |
| 08:36 | hyPiRion | dev-resources |
| 08:36 | clgv | exactly ^^ |
| 08:37 | clgv | I wouldnt mix code and resources in general |
| 09:00 | stompyj | bbloom: there? |
| 09:42 | CookedGryphon | you know how most things in clojure are easily printable? Why oh why do exceptions not list locals?! I have an exception here saying I passed the wrong thing, chances are if I saw what that one thing was I'd twig immediately what I've mixed up |
| 09:42 | CookedGryphon | but as it is I need to reconstruct the situation leading up to this call in the repl now |
| 09:42 | justin_smith | CookedGryphon: there are tools that let you investigate locals when stack traces happen |
| 09:43 | CookedGryphon | yeah, but I don't want to faff about with custom tooling |
| 09:44 | CookedGryphon | 60% of the time, just having a few locals printed in the stack trace, limited to 20 chars or so, would be enough to tell me exactly what the issue is |
| 09:44 | justin_smith | How would it know which stack frame to show locals for? |
| 09:45 | CookedGryphon | the one that exploded, the top one |
| 09:45 | CookedGryphon | if you're writing semi-reasonable clojure code, everything you're interested in will be closed into that frame |
| 09:45 | justin_smith | then you'll get some locals inside clojure.core |
| 09:45 | justin_smith | (with most stack traces I see at least) |
| 09:46 | CookedGryphon | no you wouldn't |
| 09:46 | justin_smith | the top frame, when I see exceptions, is usually quite a few levels of indirection away from any code I wrote |
| 09:47 | CookedGryphon | yeah, but the value that caused it to explode is still there |
| 09:48 | justin_smith | and it is usually nil |
| 09:48 | CookedGryphon | for example if you passed 2 into something which tried to use it as a seq |
| 09:48 | CookedGryphon | that's different |
| 09:48 | CookedGryphon | nil is teh one case where it already gives you the value you passed in |
| 09:48 | CookedGryphon | and it's highly useful |
| 09:48 | CookedGryphon | imagine if instead of saying can't do anything with nil, it just said "There's a problem with the value you gave me" |
| 09:48 | CookedGryphon | because that's the situation we have with every value other than nil |
| 09:49 | bbloom | stompyj: what's up? |
| 10:04 | boodle | hi, I'm looking to change a vector as follows.. (looking for elegence): https://www.refheap.com/90271 |
| 10:10 | cityspirit | boodle: try (mapcat identity coll) |
| 10:13 | sveri | Hi, I am using midje to count function calls with the provided function, now, I have a case where one function argument is a vector of elements and I want to make sure that function is called with the right number of elements in that factor like this: (provided (func-call arg1 [elem1 elem2]) => anything :times 1). Is it possible to apply some predicates or something like this? (provided (func-call arg1 [(> % 1)]) => anything :times 1) |
| 10:14 | boodle | cityspirit: brilliant! Thank you (off to study mapcat!) |
| 10:14 | tim_ | sveri: if your functions are pure, then why do you need to count how many times they are invoked? |
| 10:14 | clgv | boodle: or easier (apply concat coll) |
| 10:14 | boodle | clgv: I figured there was an 'apply' way of doing it |
| 10:15 | clgv | boodle: mapcat does not makes sense since only the "cat" referring to "conact" is used ;) |
| 10:15 | clgv | *concat |
| 10:15 | tbaldridge | severi: the much better approach (IMO) is to mock out your side-effecting modules, then test the inputs and outputs to the system. Put an atom in the mocks if needed to validate that they are called with the correct data |
| 10:15 | sveri | tbaldridge: Basically I want to test if the right calls to the right functions are made, and sometimes not all functions are pure, I guess |
| 10:16 | TimMc | boodle: By any chance are you generating these vectors from a for macro? |
| 10:16 | tbaldridge | sveri: IMO the way midje encourages you to (provided...) calls is an abomination. That's not the way it should be done </rant> |
| 10:16 | boodle | TimMc: honeysql, so I believe yes.. for where stmts |
| 10:17 | tbaldridge | sveri: one way (the way I prefer) to look at testing is this: What happens inside my code is of no concern of the tests. As long as the right value is returned and the right side-effects happen, the code is correct. |
| 10:18 | TimMc | So, instead of (apply concat (for [v (thing)] ...)), what you can do is (for [v (thing), x ...] x) |
| 10:18 | boodle | TimMc: excellent, ty! |
| 10:18 | tbaldridge | so test the outputs and mock the side-effects, and you're set. Otherwise if you change the internals of your code, you'll have to update all the tests that make incorrect assumptions as to how the code under test is constructed. |
| 10:18 | TimMc | and check out the other bindings and control options in the for macro |
| 10:20 | boodle | TimMC, sure, I always think (unfortunately) in terms of 'map' first rather than things like 'for' for generating seqs/colls |
| 10:21 | sveri | tbaldridge: this sounds like a valid statement, however, I just have a method that has two side effects (first: write incoming data into database, second grab some changed database data and schedule some events. Then, what would the output of such a function be? How do I test that this function successfully calls the two sideeffecting functions with the correct arguemnts? |
| 10:23 | clgv | sveri: do you mock the database with an sqlite database or similar? |
| 10:23 | sveri | clgv: I use datomic and it's in memory database functionality |
| 10:23 | clgv | ah ok |
| 10:23 | tbaldridge | sveri: then you're set! just create the DB at the start of the test, run your code, then run a query against the DB. |
| 10:24 | justin_smith | sveri: when possible, it helps to separate logic from side effects - make stateless functions that do all the logic, and then make the part that does side effects a simple conjoining of the logic plus the side effecting code |
| 10:26 | sveri | tbaldridge: well, for the first case (writing data to database) that is ok and I have tests for this, but the seconde one is harder, hm, the longer I think about it, the original problem I had was indeed a type problem, I passed a string instead of a UUID, and that lead to the error that no runtime exception was thrown, but even, no data in database was found |
| 10:27 | sveri | Maybe it's better to do a type assertion on params in that case |
| 10:27 | justin_smith | sveri: I think prismatic/schema may help here too |
| 10:28 | sveri | justin_smith: Yea, I finally have a reason to look deeper at it |
| 10:28 | sveri | thanks everybody for taking time to listening :-) |
| 10:28 | tbaldridge | sveri: are you sure the Datomic error wasn't swallowed by something? I've had Datomic throw type errors many times. |
| 10:29 | sveri | tbaldridge: Well, not 100%, but I think so, I never saw any error, neither during manual tests nor during automated testsin this case |
| 10:49 | tbaldridge | sveri: btw, you have an even better way of testing if you're using Datomic. Have your function return pure data, don't call transact inside the function at all |
| 10:54 | jtackett | hey has anyone done any clojure work with voice to text |
| 10:54 | jtackett | or speech recognition |
| 10:54 | zot | can you run lein on another directly (ie, from a make system, i can do "cd ../foo; lein run …" but wondered if i can do it without the cd indirection |
| 10:55 | mdrogalis | jtackett: Sounds like a good place to shell out to Java libs. But I haven't, no. |
| 10:55 | zot | s/another/another directory/ |
| 10:55 | jtackett | mdrogalis: I think you’re probably right, just hoping there is a clojure library/wrapper for it |
| 10:56 | justin_smith | zot: if you have an uberjar, you can run java from anywhere and point the classpath to the uberjar |
| 10:56 | zot | justin_smith: that way i knew, but was curious about it from a 'live' dir, without having to gen |
| 10:56 | mdrogalis | jtackett: Definitely :) |
| 11:17 | Jaood_ | b |
| 11:18 | jlongster | hey guys, transducers provide a way to to make a custom data type that is reducible and automatically get all the transforms. but I don't see a protocol for constructing my custom data type. does it need to implement `conj` somehow? |
| 11:19 | jlongster | or are you supposed to just natively take an transducer and my data type runs it and returns a collection of the same type as itself? |
| 11:22 | lvh | jlongster: CollFold, CollReduce |
| 11:22 | lvh | jlongster: https://github.com/clojure/clojure/blob/master/src/clj/clojure/core/protocols.clj#L13 |
| 11:22 | jlongster | lvh: `reduce` only implements how to take apart the data and iterate over it. it doesn't care about how you piece it back together into a specific type |
| 11:22 | lvh | you get Iterable for free though |
| 11:23 | jlongster | the function I pass to `reduce` will manually create something like a vector using `conj` |
| 11:24 | lvh | jlongster: ehh? that sounds different from what you were just saying about creating a custom reducible datatype |
| 11:25 | jlongster | lvh: I said I understand that part of it. I don't understand the other end. You can `into` to "run" a transducer and create a new type, but it uses `conj` so can only create native data types |
| 11:25 | jlongster | if I create a new data type, what is the pattern for providing something like `into`? |
| 11:30 | lvh | jlongster: Okay, so, to be clear: you're not interested in getting your data structure to be foldable/reducable, you're interested in getting into to dump items into your data structure? |
| 11:31 | jlongster | lvh: yes! and full disclosure, I'm just studying and am not trying to do something specific. |
| 11:32 | dnolen_ | jlongster: this is why transduce takes a transformer `xform` and `f`, `f` builds the next result |
| 11:32 | lvh | jlongster: So, "conjable" is IPersistentCollection |
| 11:32 | dnolen_ | it's also why transduce really requires an initial value, `f` must produce it or you must give `init` |
| 11:33 | lvh | but dnolen_'s answer is the enlightening one here, I presume :) |
| 11:33 | jlongster | dnolen_: yeah, I didn't know if there was a way to have the simplicity of `into`. if I want to just `map` over my structure and not think about reduce |
| 11:33 | dnolen_ | jlongster: transducers have nothing to do w/ conj, you can use map/filter now to build arrays if you like in CLJS |
| 11:33 | jlongster | lvh: what's `conjable`? |
| 11:34 | jlongster | dnolen_: oh yeah, I realize that. I was just looking to see if there was a way to do something like `into` (which assumes how it's reduced and put back to together) |
| 11:34 | dnolen_ | jlongster: into is just really just `f` = `conj` and `init` = empty data structure |
| 11:34 | dnolen_ | transduce with those arguments supplied |
| 11:35 | dnolen_ | not exactly much more verbose |
| 11:35 | dnolen_ | especially if `f` can supply init |
| 11:36 | jlongster | dnolen_: well, (transduce (map inc) conj [] [1 2 3 4)) is more verbose than (map inc [1 2 3 4]). now assume I'm not working with a vector, but with a custom type |
| 11:37 | dnolen_ | well first off (map inc [1 2 3 4]) doesn't even do what you want :) |
| 11:37 | dnolen_ | (vec (map inc [1 2 3 4])) |
| 11:37 | dnolen_ | or (into [] (map inc [1 2 3 4])) |
| 11:38 | dnolen_ | that's what you're comparing transduce to |
| 11:38 | jlongster | dnolen_: still writing clojure abstractly (haven't written much real code), sorry :) |
| 11:38 | justin_smith | $source mapv |
| 11:39 | jlongster | dnolen_: I see. map returns a lazy-seq when the collection is there |
| 11:39 | dnolen_ | jlongster: yep |
| 11:39 | dnolen_ | jlongster: but, as you probably already know, into is now defined in terms of transduce now |
| 11:40 | jlongster | yeah! but I'd like that short form to also because to create custom data types somehow |
| 11:40 | jlongster | so I'm working on transducers.js. It's pretty awesome. I get everything but this is the last piece |
| 11:41 | dnolen_ | jlongster: there's not really any good way to magically do that at least in a dynamically typed context, not w/o a the collection supplying an answer to something like empty |
| 11:41 | dnolen_ | note all of this is really orthogonal to transducers |
| 11:41 | SagiCZ1 | ~? |
| 11:41 | dnolen_ | since transducers are designed specifically to not have to deal w/ collections |
| 11:41 | clojurebot | excusez-moi |
| 11:41 | dnolen_ | otherwise the core.async transducer stuff would not work |
| 11:41 | jlongster | dnolen_: yeah, this has nothing to do with transducers. I'm trying to figure out what convenience functions to provide for stitching values back together |
| 11:41 | jlongster | that's all |
| 11:43 | jlongster | you wouldn't normally use `transduce`, but rather `into` because it's shorter |
| 11:43 | dnolen_ | jlongster: but you're not really asking about `into` right? |
| 11:45 | jlongster | dnolen_: I guess not exactly. I know how it works, but you can't use it if using custom data types. If I'm using immutable-js with transducers, I'd rather not always have to use `transduce` |
| 11:45 | jlongster | but maybe I should try that first |
| 11:45 | dnolen_ | jlongster: in ClojureScript this is non-problem because of protocols |
| 11:45 | dnolen_ | jlongster: you can make a custom data type implement ICollection, IEmptyable - done |
| 11:46 | jlongster | oooooh there it is. That means you implement `conj` for your structure. yep |
| 11:46 | jlongster | exactly what I was looking for |
| 11:47 | jlongster | yeah protocols are awesome, I hate JS's lack of interfaces |
| 11:48 | jlongster | dnolen_: btw my transducer.js already beats lodash is many benchmarks, haha |
| 11:48 | jlongster | *in many |
| 11:48 | dnolen_ | jlongster: nice not suprising. I expect transducer to crush anything that people have yet tried in JS |
| 11:49 | jlongster | dnolen_: it's absolutely ridiculous. great performance and one single API works with everything. you guys are smart. |
| 11:50 | tbaldridge | jlongster: Rich is the smart one, we are simply his oracles here on earth. |
| 11:51 | jlongster | tbaldridge: haha |
| 11:51 | mdrogalis | Big red, run. :| |
| 11:56 | stompyj | does @aphyr ever hang out here? |
| 11:56 | justin_smith | stompyj: he is very active on twitter |
| 11:58 | stompyj | justin_smith: thx, I’ll ping him on there |
| 12:01 | perplexa | hi, when i have a map like { :kw1 { :kw2 { :kw3 "somevar" } } }, what is the preferred way to access "somevar"? i think i've seen something more elegant than (:kw3 (:kw2 (:kw1 {...}))) but can't remember anymore |
| 12:01 | jbaiter | who would have thought that aphyr is into bondage... |
| 12:02 | mdrogalis | jbaiter: That awkward moment when an industry leading database thinker posts bdsm pictures to Twitter. |
| 12:02 | mdrogalis | perplexa: get-in |
| 12:02 | perplexa | ah yeah thx! |
| 12:03 | mdrogalis | Np! |
| 12:04 | raspasov | perplexa: also (-> my-map :kw1 :kw2 :kw3) |
| 12:04 | raspasov | aka thread-first macro |
| 12:09 | perplexa | raspasov: get-in is the preferred way, isn't it? |
| 12:11 | raspasov | it might be, someone with more experience might want to chime in - the thread-first macro basically does a macro re-write of pretty much exactly what you posted (:kw3 (:kw2 (:kw1 {...}))) |
| 12:12 | perplexa | thanks :) |
| 12:12 | raspasov | np :) |
| 12:12 | noonian | get-in is nicer when you have a collection of nested maps like that since you can do (map (partial get-in [:k1 :k2 :k3]) my-maps) |
| 12:13 | raspasov | as long as your keys are keywords, I believe both offer safety guarantees in the sense it won't throw exception of a key is missing and return nil instead |
| 12:13 | raspasov | if a key* |
| 12:14 | noonian | doh my example was wrong heh, can't use partial like that since it expects the map as the first arg :P |
| 12:16 | justin_smith | (map (comp :kw3 :kw2 :kw1) c) |
| 12:19 | raspasov | justin_smith: nice :) |
| 12:27 | justin_smith | ,(letfn [(rot [f & args] (apply f (last args) (butlast args)))] (map (partial rot get-in [:a :b :c]) [{:a {:b {:c 0}}} {:a {:b {:c 2}}}])) |
| 12:27 | clojurebot | (0 2) |
| 12:27 | TimMc | $seen aphyr |
| 12:28 | justin_smith | TimMc: lazybot is still out |
| 12:28 | TimMc | :-( |
| 12:32 | arrdem | cbp: o/ |
| 12:33 | cbp | arrdem: sup |
| 12:42 | hoverbear | Anyone ever had this issue before with clj-http? Cannot cast DefaultHttpClient to CloseableHttpClient https://gist.githubusercontent.com/Hoverbear/f9715961a5cd8ea19cdb/raw/150944c1efeaee72231595fa353313cffd5d5800/gistfile1.clj |
| 12:47 | perplexa | raspasov: so, the thread first macro fails for (-> config :kw1 (keyword "kw2") :kw3), whereas get-in works :) |
| 12:48 | perplexa | surprisingly works, though when i assign (keyword "kw2") to another variable first, though. |
| 12:48 | perplexa | at least to me that's surprising :P |
| 12:48 | perplexa | otherwise i get: ClassCastException clojure.lang.PersistentArrayMap cannot be cast to java.lang.String clojure.core/keyword (core.clj:575) |
| 12:49 | quile | well, isn’t the problem that (keyword "kw2") is being rewritten by the macro? |
| 12:49 | justin_smith | perplexa: ((keyword "kw2")) would also work |
| 12:50 | perplexa | indeed it does |
| 12:50 | justin_smith | perplexa: welcome to the weird side of macros |
| 12:50 | perplexa | haha |
| 12:50 | justin_smith | (it gets much weirder) |
| 12:50 | perplexa | yeah i've seem some of them ;x |
| 12:51 | perplexa | clojure must be the most unintuitive thing to learn \o/ |
| 12:51 | perplexa | it's fun tho |
| 12:51 | justin_smith | perplexa: the number of rules and special cases to remember is actually fairly low, it's just not the same rules and special cases all the "normal" languages have is all |
| 12:52 | perplexa | sometimes i end up catching myself writing something like x * y and then wonder why it doesn't work :D |
| 12:53 | perplexa | moments of epic facepalm |
| 12:53 | SagiCZ1 | perplexa: happens to me all the time |
| 12:53 | arrdem | $google expresso |
| 12:54 | cbp | ~lazybot |
| 12:54 | clojurebot | lazybot is echo ~lazybot |
| 12:54 | justin_smith | $google where is ma lazybot, bring back ma lazybot dammit |
| 12:54 | arrdem | expresso's good for when you need infix math... but it's definitely not as nice as I'd like |
| 12:54 | SagiCZ1 | perplexa: but what gets me everytime are the idiotic nonsensical exceptions.. for example Class not found when you pass int instead of double into some Math function.. i HATE that |
| 12:54 | arrdem | Raynes: UR BOT IZ TRASH AND U R 2 |
| 12:54 | SagiCZ1 | ,(Math/sqrt 5) |
| 12:54 | clojurebot | 2.23606797749979 |
| 12:54 | Raynes | I don't think anyone ever just says "lazybot is down" anymore. |
| 12:54 | SagiCZ1 | ,(Math/sqrt (int 5)) |
| 12:54 | clojurebot | 2.23606797749979 |
| 12:54 | SagiCZ1 | damn it |
| 12:55 | perplexa | :D |
| 12:55 | arrdem | Raynes: but that's no fun... |
| 12:55 | SagiCZ1 | perplexa: ok i guess it just doesnt work in my project xD |
| 12:55 | SagiCZ1 | ,(Math/sqrt 5 5) |
| 12:55 | clojurebot | #<CompilerException java.lang.IllegalArgumentException: No matching method: sqrt, compiling:(NO_SOURCE_PATH:0:0)> |
| 12:56 | SagiCZ1 | that kinda makes sense.. ok i will shut up now |
| 12:56 | perplexa | soooo, which do i want? (-> config :aggregations ((keyword aggregation)) :sink-schema) vs (get-in config [:aggregations (keyword aggregation) :sink-schema]) |
| 12:56 | perplexa | they're both kinda nice :P |
| 12:57 | cbp | i think the latter is easier to understand |
| 12:57 | perplexa | so i go with the former? :D |
| 12:57 | justin_smith | ((comp :sink-schema (keyword aggregation) :aggregations) config) |
| 12:57 | noonian | perplexa: i like the latter, agree with cbp |
| 12:57 | perplexa | me too, actually. |
| 12:57 | perplexa | also need to look up what comp does :P |
| 12:58 | noonian | stands for compose |
| 12:58 | cbp | makes you an egghead |
| 12:58 | TimMc | Raynes: What, you don't have a paging alert on lazybot's status? |
| 12:58 | noonian | ((comp f g) 7) == f(g(7)) in math syntax |
| 12:59 | justin_smith | I like comp because it returns a function, so you can easily bind it to a more meaningful name and call that |
| 12:59 | noonian | yeah, i like using it like that, same with partial |
| 12:59 | justin_smith | (let [get-schema (comp :sink-schema (keyword aggregation) :aggregations)] (map get-schema configs)) |
| 12:59 | noonian | and it makes your programs 'cuter' |
| 13:00 | justin_smith | noonian: yeah, gotta keep up with the kawaii metrics |
| 13:01 | TimMc | hiredman: Moving `lein compile` from encrypted disk fs to a ramfs took real/user timing from ~70/30 to ~15/30. So that seems confirmed. |
| 13:01 | noonian | justin_smith: always introducing me to new memes :P |
| 13:02 | perplexa | thx justin_smith / noonian |
| 13:02 | perplexa | learned something new again today |
| 13:02 | perplexa | comp is damn mind twisting, tho |
| 13:03 | arrdem | eh? the only remotely odd thing about comp is its argument order... |
| 13:03 | perplexa | well it's reversed ;p |
| 13:03 | arrdem | right that's what's confusing about it :P |
| 13:05 | justin_smith | noonian: thanks to this exchange, my usage of comp will now be accompanied by the mental image shrieking teenage japanese cartoons with heart bubbles and eyes larger than their cranial capacity |
| 13:09 | dmitrygusev | just knew there's Clojure Russia community on G+, please join: https://plus.google.com/u/0/communities/114227952963737516047 |
| 13:09 | perplexa | thanks for all the advice, guys |
| 13:51 | Grazzy_ | Hola! |
| 13:53 | shoepie | Grazzy_: sup |
| 13:54 | Grazzy_ | shoepie: looking for new interesting chans |
| 13:55 | justin_smith | Grazzy_: if you want to learn more about the Clojure programming language, this is a very interesting chan |
| 13:55 | Grazzy_ | I want to learn as much as possible |
| 13:55 | Grazzy_ | I was told to come here |
| 13:55 | Grazzy_ | Can you tell me a bit about it? |
| 13:57 | justin_smith | It's a langauge in the lisp-1 family that stresses immutibility and tractible concurrency |
| 13:58 | xemdetia | Grazzy_, have you seen all the Rich videos? |
| 13:58 | xemdetia | it answers a lot of the why |
| 13:59 | Grazzy_ | nope |
| 13:59 | noonian | yeah, i would highly recommend the 2008 video introducing clojure from infoq |
| 13:59 | noonian | Grazzy_: http://www.infoq.com/presentations/hickey-clojure |
| 14:00 | noonian | and just be prepared for things to be very different from what you are used to at first if you have never seen a lisp before or done functional programming |
| 14:00 | Grazzy_ | noonian: Thanks |
| 14:00 | noonian | np |
| 14:00 | xemdetia | If anything it should make you more intrigued :) |
| 14:00 | Grazzy_ | Oh now i get it |
| 14:01 | Grazzy_ | I messed around with it a while back |
| 14:01 | Grazzy_ | Lisp is great |
| 14:01 | Grazzy_ | So hard though |
| 14:01 | Grazzy_ | Whats the application of this language in the bigger picture? |
| 14:02 | justin_smith | Grazzy_: easy to use concurrency |
| 14:02 | justin_smith | (with performance) |
| 14:02 | noonian | for me it has become my goto language for anything that doesn't need to startup fast or run on embedded devices |
| 14:02 | tbaldridge | Grazzy_: assuming you mean "what can Clojure be used for", pretty much anything. Perhaps except shell scripting. |
| 14:02 | Grazzy_ | Nice |
| 14:03 | Grazzy_ | Ill look into it |
| 14:03 | Grazzy_ | This looks great |
| 14:03 | Bronsa | tools.analyzer now has a pass scheduler :) https://github.com/clojure/tools.analyzer.jvm/commit/4183ba79ef47ba57de3af46aac1d318fa1a0cd8a |
| 14:03 | xemdetia | Yeah the only thing I would mention that you may not have come across Grazzy_ is lein |
| 14:04 | Grazzy_ | How big the community and support structure i.e stack over flow and fourm posts |
| 14:05 | tuft | Grazzy_: not too big and not too small in my experience |
| 14:05 | noonian | in my subjective opinion, there is a very active, helpful, and enthusiastic community |
| 14:05 | justin_smith | this channel and stackoverflow are pretty active |
| 14:06 | Grazzy_ | Yuh yuh |
| 14:06 | Grazzy_ | im pumped |
| 14:08 | Grazzy_ | clear |
| 14:08 | Grazzy_ | Man this is great. Lisp that i dont understand mixed with something i know |
| 14:08 | Grazzy_ | :D |
| 14:09 | Grazzy_ | How many of these mixed breed languages are out there |
| 14:09 | tuft | Grazzy_: yes, it's an excellent gateway lisp =) |
| 14:11 | xemdetia | Grazzy_, I would look at some of the other languages that cropped up on the JVM |
| 14:11 | Grazzy_ | Ok |
| 14:11 | Grazzy_ | Im so glad i started using IRC |
| 14:12 | xemdetia | It's mostly the fact that you can write in a new and interesting language and still have access to what you need from JVM which makes languages like clojure more practical then it otherwise would be |
| 14:12 | Grazzy_ | I wish i was born 10 years earlyer and lived in the prime of the internet growth and culture |
| 14:12 | xemdetia | Grazzy_, IRC existed more than 10 years ago :) |
| 14:12 | Grazzy_ | Yea |
| 14:13 | Grazzy_ | But 10 years is what i wanted |
| 14:13 | Grazzy_ | *want |
| 14:13 | tbaldridge | Grazzy_: but yes, there are other languages that mix a OOP platform with some other language. F# and Factor are two others that come to mind. But Clojure is probably the best :-P |
| 14:13 | Grazzy_ | sweet |
| 14:14 | noonian | Clojure was the answer to my quest for a practical lisp |
| 14:14 | xemdetia | and Grazzy_ I wouldn't worry about when you got started- what's interesting now is interesting because it solves problems of the time |
| 14:14 | xemdetia | just make cool stuff |
| 14:14 | Grazzy_ | For sure! i love the technology that am able to grow up on. There is so much interesting things to learn |
| 14:15 | Grazzy_ | There is so much i have no idea what my technological passion truly is |
| 14:18 | tuft | Grazzy_: the good pockets of irc are much the same as a decade ago =) |
| 14:18 | tuft | s/as a/as/ |
| 14:21 | ToxicFrog | Re: practical lisp: similarly for me, Clojure is the only lisp I've actually gotten real-world work done in. |
| 14:21 | ToxicFrog | I liked Scheme but I never really did anything with it. |
| 14:23 | xemdetia | scheme is fun, and gambit is very slick but the fact that normally with a lisp or scheme you had to build your entire library base from scratch make them nonstarters |
| 14:24 | noonian | plus they all support different libs and module systems so it is hard to write portable code |
| 14:31 | yocapybara | hi guys, I'm in cider, and I find I'm looking for a command to evaluate everything in my buffer, but in the REPL buffer so I can then mess around with the code. Am I really looking for a wrong thing? I keep finding I have to copy or C-c M-p each form into the repl, so I wonder if I'm just plain doing things oddly |
| 14:31 | ToxicFrog | xemdetia, noonian: yeah, that was kind of my impression, and well if I want a lightweight language with no library support I already have Lua for that~ |
| 14:43 | technomancy | ToxicFrog: Scheme is way older than Lua |
| 14:43 | noonian | i still use scheme when i want a repl that loads quickly for small computations |
| 14:43 | ToxicFrog | technomancy: yes, but I learned Lua first |
| 14:44 | xemdetia | embedding Lua is still much nicer then scheme |
| 14:44 | xemdetia | tinyscheme isn't awful |
| 14:44 | xemdetia | just Lua is easier |
| 14:44 | technomancy | ToxicFrog: oh, I read that as "we already have lua" like as a civilization or something |
| 14:45 | ToxicFrog | Yeah, no, it was that I personally knew Lua well before I looked at Scheme |
| 14:56 | snrmwg | hello, does anyone have good ideas for CRUD method names? i thought about something like api namesapces, each domain goes in a namespace, but function names like 'read', 'load' (and i think 'update' at clojure 1.7) are already defined in clojure.core. method names like 'my.api.domain/read-domain' look somehow redundant to me. |
| 14:57 | noonian | you can tell clojure to not refer to the core functions you want to define yourself if you want |
| 14:58 | noonian | in your ns form (:refer-clojure :exclude [read load]) |
| 14:58 | noonian | i'm still experimenting myself with good api ns organization |
| 14:59 | snrmwg | cool. didn't know that feature, i will give it a try. |
| 14:59 | snrmwg | is it also possible to refer the core functions with an alias? just in case i would need one of them? |
| 15:00 | xemdetia | You should be able to import it directly again, right? |
| 15:00 | xemdetia | or the longname |
| 15:01 | xemdetia | (these are guesses) |
| 15:01 | snrmwg | ok, just never thought about importing something from core :) but why not, it's just a namespace as any other |
| 15:02 | yogsototh | Hi! I am trying to use friend interactive-form, while the demo works the same workflows doesn't set any cookie. How could I start to debug this? |
| 15:03 | sritchie | yogsototh: do you have session middleware in place? |
| 15:03 | sritchie | yogsototh: it’s the session middleawre that sets the cookie, not friend |
| 15:03 | yogsototh | ok thanks! |
| 15:06 | yogsototh | sritchie: thanks! It works. I didn't know how I could discovered this myself. |
| 15:07 | sritchie | I think he mentions it on the README |
| 15:07 | sritchie | it’s pretty buried though: |
| 15:07 | sritchie | https://github.com/cemerick/friend#authentication |
| 15:07 | sritchie | see “Note that Friend itself"... |
| 16:20 | kschrader | anybody know how to jump to test definitions in the new version of Cider? it used to be C-c C-t, but now that says "No test report buffer" |
| 16:20 | AeroNotix | kschrader: never update CIDER if you can help it |
| 16:21 | kschrader | yeah, too late for that... |
| 16:21 | AeroNotix | kschrader: if you just upgraded "just because" then I'd advise you to downgrade if you have real work to do |
| 16:21 | AeroNotix | it's so broken on their latest release that it's horrible |
| 16:21 | AeroNotix | your .emacs.d should be in VCS |
| 16:21 | AeroNotix | if not, time to start :) |
| 16:21 | kschrader | yeah, it is, I was just hoping for an answer :) |
| 16:22 | justin_smith | kschrader: every command is available by name via M-x, and if it has a keyboard shortcut, emacs will show you the shortcut in the minibuffer after running the command |
| 16:23 | justin_smith | it should be called something like cider-jump-to-definition |
| 16:24 | justin_smith | I think the canonical keybinding has always been M-. |
| 16:25 | kschrader | yeah, that's not what I'm looking for |
| 16:25 | maravillas | kschrader: C-c C-j, I believe |
| 16:25 | maravillas | if you're looking to jump from foo.clj to foo_test.clj, e.g. |
| 16:25 | justin_smith | kschrader: ahh, sorry, I missed the word "test" in your question, sorry |
| 16:26 | kschrader | maravillas: That's what I'm trying to find |
| 16:26 | kschrader | but it doesn't seem to work anymore |
| 16:26 | stompyj | the first rule of CIDER club is never update CIDER |
| 16:26 | maravillas | M-x clj-jump-to-other-file ? |
| 16:26 | kenrestivo | first rule of cider club is use nrepl.el :-P |
| 16:26 | kenrestivo | i've been avoiding cider for years, so far so good. |
| 16:27 | kschrader | ah, it's M-x clojure-jump-to-test now |
| 16:27 | stompyj | (inc kenrestivo) |
| 16:27 | lazybot | ⇒ 1 |
| 16:27 | stompyj | I’m on the cursive clojure train |
| 16:40 | jlongster | how do I install Clojure 1.7 with lein? |
| 16:43 | technomancy | jlongster: just edit project.clj |
| 16:44 | jlongster | technomancy: I tried that, but got https://gist.github.com/jlongster/4524b4552a1f98aac516 |
| 16:44 | technomancy | oh, sorry... you mean the snapshot? |
| 16:45 | jlongster | yeah |
| 16:45 | gphilippart | hi, how do I add a map to a vector ? For example I have {:a :b :c :c},, how do I get [{:a :b :c :d}] (conj and into won't) ? |
| 16:46 | technomancy | jlongster: it's in the sonatype snapshots repository |
| 16:46 | seancorfield | jlongster: "1.7.0-alpha2" or "1.7.0-master-SNAPSHOT" (for the latter you'll need to add the sonatype snapshots repo) |
| 16:46 | seancorfield | you can use the alpha from maven without adding extra repos tho' |
| 16:46 | jlongster | oh, thanks |
| 16:46 | seancorfield | we're running alpha2 in production... |
| 16:47 | snrmwg | gphilippart: (conj [] {:a :b :c :c}) |
| 16:49 | gphilippart | hm, yeah right. |
| 16:51 | noonian | ,(into [] [{:a :b :c :c}]) |
| 16:51 | clojurebot | [{:c :c, :a :b}] |
| 16:52 | noonian | ,(vector {:a :b :c :c}) |
| 16:52 | clojurebot | [{:c :c, :a :b}] |
| 16:53 | justin_smith | ,,(assoc-in (vector {:a :b :c :c}) [0 :c] :d) ; pedantic |
| 16:53 | clojurebot | [{:c :d, :a :b}] |
| 16:54 | noonian | :D |
| 16:54 | gphilippart | the issue I'm facing is when using clj-http.client/get, sometime it returns a vector of maps, and sometimes it returns just a map. I'd like to add both these types of results into a vector and return it with one expr. Is it possible ? |
| 16:55 | justin_smith | wow, I didn't think client/get was so fucked up as to randomly return different datatypes |
| 16:56 | noonian | ,(let [get-result [{:status 200}]] (if (vector? get-result) get-result (vector get-result))) |
| 16:56 | clojurebot | [{:status 200}] |
| 16:56 | noonian | i just had this problem in python |
| 16:56 | dakrone | gphilippart: get should never return a vector of maps, it should always be just a map, do you have code that backs up what you're seeing? |
| 16:56 | gphilippart | it doesn't do that randomly, I'm calling github's various api. /users will yield a vector of maps. /users/rhickey will yield a single map. |
| 16:56 | dakrone | ahh yea, that's not clj-http, it's github's API |
| 16:56 | noonian | xmltodict uses lists if there are more than one child nodes and a single one otherwise, really annoying imo |
| 16:57 | justin_smith | gphilippart: so if you know what shape the data has by endpoint, why not have a different adaptor function as needed for each endpoint? |
| 16:57 | noonian | ^ this |
| 16:58 | justin_smith | phew, good to know client/get is vindicated, I did think it was better than that |
| 16:59 | gphilippart | I'd like a function that gets any resource. It recurses on the 'next' link in the header ( https://developer.github.com/guides/traversing-with-pagination/). |
| 17:01 | CisZZZa | Hello |
| 17:03 | danielcompton | gphilippart: not sure if you've seen https://github.com/Raynes/tentacles? I haven't checked to see if it keeps the shape the same or not |
| 17:46 | seangrove | $seen bbloom |
| 17:46 | lazybot | bbloom was last seen talking on #clojure 3 days ago. |
| 17:52 | justin_smith | seangrove: in this case it wouldbe more appropriate to ask bbloom how recently he saw lazybot - he was around earlier today |
| 18:03 | seangrove | justin_smith: I guess lazybot isn't quite as perceptive as one might hope... |
| 18:11 | amalloy | is there some issue with lazybot's $seen? |
| 18:16 | justin_smith | lazybot has not been online consistently |
| 18:16 | justin_smith | he had a bunch of downtime this weekend |
| 18:19 | amalloy | lazybot: you're fired |
| 18:26 | noonian | lazybot should pull and parse rayne's logs on startup and backfill his or her or it's $seen data |
| 18:26 | amalloy | noonian: lazybot produces Raynes's logs. unless you mean the ones on his pc? |
| 18:26 | noonian | oh lol |
| 18:27 | noonian | i didn't know that |
| 18:27 | amalloy | lazybot lives on the server Raynes and i run, and produces the logs at logs.lazybot.org |
| 18:27 | Raynes | I can assure you, the logs on my machine are far worse than lazybot's. |
| 18:27 | Raynes | Especially given that I'm pretty sure I don't log. |
| 18:27 | Raynes | :p |
| 18:27 | amalloy | yeah, i would have guessed that too |
| 18:28 | Raynes | But yeah, lazybot has been going down a ton in the last week or so. |
| 18:28 | tac_ | ,conj |
| 18:28 | clojurebot | #<core$conj clojure.core$conj@15d87c> |
| 18:28 | noonian | naughty bot |
| 18:28 | tac_ | Can you get a docstring from a function name? |
| 18:29 | noonian | tac_: you can get the meta data off the function's var |
| 18:29 | amalloy | from a function *name*? yes, just call doc. from the function itself, no |
| 18:29 | tac_ | ,doc "conj" |
| 18:29 | clojurebot | #<CompilerException java.lang.RuntimeException: Can't take value of a macro: #'clojure.repl/doc, compiling:(NO_SOURCE_PATH:0:0)> |
| 18:29 | tac_ | ,(doc "conj") |
| 18:29 | clojurebot | #<CompilerException java.lang.ClassCastException: java.lang.String cannot be cast to clojure.lang.Symbol, compiling:(NO_SOURCE_FILE:0:0)> |
| 18:29 | noonian | ,(doc conj) |
| 18:29 | clojurebot | "([coll x] [coll x & xs]); conj[oin]. Returns a new collection with the xs 'added'. (conj nil item) returns (item). The 'addition' may happen at different 'places' depending on the concrete type." |
| 18:30 | tac_ | ,doc |
| 18:30 | clojurebot | #<CompilerException java.lang.RuntimeException: Can't take value of a macro: #'clojure.repl/doc, compiling:(NO_SOURCE_PATH:0:0)> |
| 18:30 | tac_ | hmm |
| 18:31 | noonian | ,(-> 'clojure.core/conj find-var meta :doc) |
| 18:31 | clojurebot | "conj[oin]. Returns a new collection with the xs\n 'added'. (conj nil item) returns (item). The 'addition' may\n happen at different 'places' depending on the concrete type." |
| 18:31 | noonian | ,(doc doc) |
| 18:31 | clojurebot | "([name]); Prints documentation for a var or special form given its name" |
| 18:31 | noonian | ,(source doc) |
| 18:31 | clojurebot | Source not found\n |
| 18:31 | noonian | ,(macroexpand '(doc doc)) |
| 18:31 | clojurebot | "([name]); Prints documentation for a var or special form given its name" |
| 18:31 | tac_ | ,(source conj) |
| 18:31 | clojurebot | Source not found\n |
| 18:32 | noonian | ,(macroexpand-1 '(doc doc)) |
| 18:32 | clojurebot | "([name]); Prints documentation for a var or special form given its name" |
| 18:33 | noonian | hmm, i wonder why clojurebot does that, I get this in the repl |
| 18:33 | noonian | ((var clojure.repl/print-doc) (clojure.core/meta (var doc))) |
| 18:34 | noonian | ,*clojure-version* |
| 18:34 | clojurebot | {:interim true, :major 1, :minor 7, :incremental 0, :qualifier "master"} |
| 18:35 | xemdetia | I'm just waiting for the day where I can do CI over IRC |
| 18:35 | noonian | i think that day has arrived |
| 18:36 | noonian | we do ci over hipchat, i'm sure you could hook it up to irc without much trouble |
| 18:37 | xemdetia | I was more talking about me personally |
| 18:37 | Bronsa | ,(class @@#'doc) |
| 18:37 | clojurebot | clojure.core$eval445$fn__446$my_doc__447 |
| 18:37 | Bronsa | noncom: ^ that's why |
| 18:38 | Bronsa | clojuredoc redefines clojure.repl/doc |
| 18:38 | noonian | ah |
| 18:38 | Bronsa | ,@#'doc |
| 18:38 | clojurebot | #'clojure.core/my-doc |
| 18:38 | noonian | Bronsa: i'm sure noncom was interested also :P |
| 18:39 | Bronsa | this is probably better |
| 18:39 | Bronsa | noonian: ops |
| 18:40 | tac_ | ,(doc reduce) |
| 18:40 | clojurebot | "([f coll] [f val coll]); f should be a function of 2 arguments. If val is not supplied, returns the result of applying f to the first 2 items in coll, then applying f to that result and the 3rd item, etc. If coll contains no items, f must accept no arguments as well, and reduce returns the result of calling f with no arguments. If coll has only 1 item, it is returned and f is not called. If val i... |
| 18:45 | shd | Does anyone know "gloss" library? https://github.com/ztellman/gloss Is it possible to read compiled frame size instead of entering it manually? Sorry for such a newbie question but i'm newbie indeed and i'm trying to learn by practice... |
| 18:46 | shd | i would figure it out myself but it's very hard for me to read this code yet |
| 18:56 | noonian | shd: i'd look at the wiki: https://github.com/ztellman/gloss/wiki/Introduction |
| 18:56 | shd | noonian: of course read it, did you found answer to my question there? maybe i missed it.. |
| 18:56 | noonian | imo manipulating raw bytes is not the easiest way to get a feel for a language unless its something a little closer to c :P |
| 18:59 | shd | noonian: you might be right, but i'd like to use clojure in my hobby project and since it doesn't interface with C ABI that well i need to rewrite some basic stuff in it |
| 19:00 | noonian | shd: i'm not sure, but i think you need to call compile-frame to create a codec, and then should be able to call decode with that codec and your raw frame and it should decode it |
| 19:00 | noonian | raw frame meaning a byte stream |
| 19:01 | shd | noonian: thanks, but i understand how to make a frames and decode them, it's just annoying to write [buf (byte-array 16) ...] manually, i don't really see this need |
| 19:02 | noonian | shd: i might be more help if i had a better understanding of what you are trying to do. Are you trying to serialize clojure data structures as bytes or read them back or both? |
| 19:02 | tac_ | ,(doc ->>) |
| 19:02 | clojurebot | "([x & forms]); Threads the expr through the forms. Inserts x as the last item in the first form, making a list of it if it is not a list already. If there are more forms, inserts the first form as the last item in second form, etc." |
| 19:03 | tac_ | does that just mean that (->> x f g) = (g (f x))? |
| 19:04 | noonian | tac_: yes, but it's a little more complicated when your fns take more than 1 arg |
| 19:05 | shd | noonian: i'm trying to read binary TO clojure - basically parse a file |
| 19:05 | noonian | (->> x (f 8) g) = (g (f 8 x)) |
| 19:06 | noonian | shd: right, so i guess i don't understand why you are creating a byte-array manually then, since you already have binary data to read |
| 19:06 | shd | when i define a frame i'm declaring arguments with their length as well, it's annoying having to type them in (byte-array count) again, i believe there is easy workaround for that |
| 19:07 | shd | noonian: that would be great to read directly from buffer - i were not able to do it yet :P |
| 19:07 | noonian | shd: i probably can't be much help since I have zero experience reading binary formats in clojure |
| 19:07 | shd | noonian: right, thanks for trying anyway |
| 19:08 | noonian | shd: np, don't give up on clojure even if you can't figure this thing out! |
| 19:09 | justin_smith | shd: looking at the docs, what about using "repeated"? |
| 19:10 | shd | justin_smith: frames vary between each other, as i understand repeated is for same types of data |
| 19:12 | shd | i.e. byte + ushort = 3, then i read uint + uint = 8, every time i need to add this numbers in my head while i should be able to read them from frame definition i.e. sizeof() |
| 19:13 | justin_smith | shd: The author, ztellman, hangs out here, maybe he is around for answering questions |
| 19:14 | shd | justin_smith: thanks, if i wont find any solution i'll be definitely haunting him :P |
| 19:16 | amalloy | i don't understand why you're adding these numbers together in your head either. you shouldn't need to know them at all |
| 19:17 | tac_ | noonian: right. |
| 19:19 | shd | amalloy: do you mean i shouldn't read through the byte-array or i should read them from their definitions? |
| 19:19 | shd | not really logical what i said, but i hope you grasp the point |
| 19:20 | amalloy | you should define a single gloss frame that is capable of reading the entire thing from the buffer at once. don't make a million sub-frames and feed them sub-arrays or something weird like that |
| 19:21 | shd | amalloy: yes, i'm trying to reach that point, but it's easier to solve small problems than parse whole file at once |
| 19:23 | shd | amalloy: major problem is: i don't couldn't find a way to define struct{ int type_id, union{ string a, byte b, int c } }... actually union isn't correct too, because this attributes might not exist at all |
| 19:23 | shd | so i hoped to solve this problem in my own function |
| 19:24 | justin_smith | so there is no defined frame type, it's just free form tagged unions? |
| 19:26 | shd | justin_smith: everything mixed with each-other, but you're right - not everything is known at the time i declare frames |
| 19:27 | amalloy | justin_smith: the C tradition of the 70s: just write structs directly as binary |
| 19:29 | Guest47278 | Perhaps a stupidly vague/broad question, guys. Does experience suggest that Clojure is a language that takes a *long* time to learn? Coming from, say, a Ruby background with rudimentary FP knowledge |
| 19:29 | Guest47278 | I'm comparing primarily to Scala - which really seems to qualify, to me, as a language that takes a whole lotta time. |
| 19:30 | justin_smith | Guest47278: clojure is nowhere near the leage of scala or c++ in terms of complexity |
| 19:34 | seancorfield | Guest47278: The real learning curve is the Functional Programming paradigm, not the language itself. |
| 19:34 | Guest47278 | seancorfield: I certainly recognize that - but I also recognize that Scala is a highly complex language |
| 19:34 | seancorfield | Clojure is a pretty simple language, with a relatively small core library (compared to many other languages' libraries). |
| 19:35 | Jaood_ | yeah, the core only has like 600 functions :P |
| 19:35 | seancorfield | Yes, there's a lot of syntax and semantics to learn in Scala - but you can plough on writing OOP code in Scala if that's your background, you're not "forced" to learn FP. |
| 19:38 | seancorfield | Jaood_: you think 600 is a lot? have you looked at the number of methods in Ruby 2 for example? :) |
| 19:38 | numberten | is there a core function for changing the value of a key in a map? |
| 19:38 | justin_smith | numberten: there is update-in |
| 19:38 | amalloy | numberten: are you looking for assoc? |
| 19:39 | justin_smith | ,(update-in {:a 0 :b 1} [:a] inc) |
| 19:39 | clojurebot | {:b 1, :a 1} |
| 19:39 | seancorfield | Jaood_: I could about 1,700 functions here http://www.ruby-doc.org/core-2.1.2/ |
| 19:39 | numberten | the value of a key |
| 19:39 | seancorfield | s/could/count/ |
| 19:39 | akkad | are there any primers for CL -> clojure? |
| 19:39 | numberten | (foo {:a 10} [:a :b]) => {:b 10} |
| 19:39 | numberten | something more like that |
| 19:40 | numberten | specifically for nested keys, so like assoc-in |
| 19:40 | Guest47278 | seancorfield: Ruby 2 doesn't have that many methods, does it..? It's my dayjob, I never knew :) |
| 19:40 | amalloy | numberten: clojure.set/rename-keys |
| 19:41 | amalloy | Guest47278: in all the classes in all the standard lib? gotta be about a trillion |
| 19:41 | justin_smith | yeah, likely update-in plus rename-keys for the nested situation |
| 19:41 | Guest47278 | amalloy: standard lib != core though |
| 19:41 | seancorfield | Guest47278: I just looked it up out of curiosity... I'd say most languages have a lot more than 600 methods/functions in their core (language plus auto-imported classes)... |
| 19:41 | numberten | alright |
| 19:41 | numberten | didn't think to use update-in alongside rename-keys, thanks |
| 19:42 | Guest47278 | Ruby's methods do seem to have a knack for being extremely powerful, even more so when put together, though |
| 19:42 | Guest47278 | Referencing docs for ruby methods never seems a prohibitive deal |
| 19:42 | seancorfield | Guest47278: indeed... and a lot of Ruby folks seem to love Clojure for its dynamic power too... |
| 19:43 | Guest47278 | Partially due to its awesome docs, as well, I'm sure. It's amazing what the stylesheet on a language's docs do for the language. |
| 19:43 | seancorfield | Personally I don't like Ruby's syntax - but that sort of thing is very subjective. |
| 19:43 | seancorfield | I love being able to get docs on functions in the REPL (since it's just metadata on the fn itself) |
| 19:43 | justin_smith | I tend to find many of the things that are considered "friendly" or "usable" in ruby-land to be annoying |
| 19:44 | Guest47278 | justin_smith: example? (for my understanding) |
| 19:45 | Guest47278 | seancorfield: it's possible to do that with Ruby too (Pry) - but I'm not here to evangelize ruby :) |
| 19:45 | Guest47278 | In fact, i'm actually here to discover my exit strategy |
| 19:45 | Jaood_ | seancorfield: that's not fair, some methods are inherited showing them more than once on the list (for each class), ruby also likes to give the same method multiple names :/ |
| 19:45 | justin_smith | Guest47278: ubiquitous usage of ansi colors (often ignoring what I am actually doing with the tool's output) |
| 19:46 | Guest47278 | justin_smith: hey that's not rubylang! |
| 19:46 | justin_smith | OK - sure |
| 19:48 | Guest47278 | do you guys find clojures lack of types to be prohibitive? |
| 19:49 | Guest47278 | the inability to create abstraction in the same way |
| 19:49 | justin_smith | we have types, they are just late-bound |
| 19:49 | justin_smith | ,(1 1) ; type error |
| 19:49 | clojurebot | #<ClassCastException java.lang.ClassCastException: java.lang.Long cannot be cast to clojure.lang.IFn> |
| 19:49 | Guest47278 | justin_smith: can you create your own |
| 19:49 | justin_smith | yeah, deftype or defrecord are the easiest ways |
| 19:50 | justin_smith | the main focus is developing against interfaces (for java interop) or protocols |
| 19:51 | Guest47278 | justin_smith: is there a clear route on getting a firm grip on clojure in a short period of time? |
| 19:51 | Guest47278 | justin_smith: i know in my lifetime, to learn what i've learned in the languages i know, they were extremely long and winding paths, stepping through many turds on the way |
| 19:51 | justin_smith | Guest47278: really depends on where the gaps in your experience are - do you have experience with coding with immutible data? lisp syntax? |
| 19:51 | Guest47278 | I want something quick & direct now :) |
| 19:52 | Jaood_ | Guest47278: get a book |
| 19:52 | Guest47278 | justin_smith: immutable data, yes - lisp syntax, not a great deal. Although I've done Little Schemer, for instance. |
| 19:52 | Guest47278 | (People definitely describe their degrees of experience with orders of magnitudes differences in optimism :) |
| 19:53 | seancorfield | Jaood_: my experience with Ruby is that it seems to like offering lots of different ways of doing the same thing - which expands the surface area of what you need to learn... but I think measuring the "size" of a language's function base is a bit pointless and misleading so I was merely reacting to the complaint that clojure.core is "big" (I don't consider it so). |
| 19:53 | Guest47278 | Is there a "best" book on clojure? |
| 19:53 | justin_smith | ~book |
| 19:53 | seancorfield | Guest47278: you'll get different answers from different people |
| 19:53 | clojurebot | book is books |
| 19:53 | justin_smith | ~books |
| 19:53 | clojurebot | books is http://clojurebook.com/ http://joyofclojure.com/ |
| 19:54 | Guest47278 | The one thing I hate about whenever I revisit FP, is I find I'm reading the same crap about FP over and over again |
| 19:54 | seancorfield | Guest47278: my preference/recommendation is the o'reilly book first and joy of clojure second |
| 19:54 | seancorfield | so, yeah, same books justin_smith listed |
| 19:54 | Guest47278 | awesome, thanks. |
| 19:54 | justin_smith | seancorfield: I credit whoever made the factoid |
| 19:55 | Jaood_ | seancorfield: yeah, I was not being serious, you don't really need all that functions to start programming in clojure since most are just abstractions and can be easily be pick up with time |
| 19:55 | justin_smith | Guest47278: reading the same crap about FP because you forgot in the meantime, or because you can't find more advanced material? |
| 19:56 | Guest47278 | justin_smith: more because I can't find the right stage. It either all seems too easy, or just way out of my league and mathematically crazy. |
| 19:58 | justin_smith | so maybe you are at the stage where what you want to learn is math? |
| 20:00 | Guest47278 | justin_smith: well, I can't link any of this mathematical crap to practice, yet. So I wouldn't know where to start, or whether I'd want to |
| 20:01 | Guest47278 | I think a gulf between basic FP and advanced FP concepts definitely exists and is wide |
| 20:02 | justin_smith | I think there is a big gap between knowing how closures and immutible data and tail recursion can be used to structure an app, and actually being able to build something in a mostly-functional programming style. And that is not a question of reading more about fp, or learning more math. It's a question of reading more real working code, and writing apps, and redesigning them. There is no substitute for practice. |
| 20:03 | Guest47278 | justin_smith: I've totally found that to be the case. I've come to realise that I spent many years living a lie - learning a whole lot about theoreticals, when actually building stuff is king. |
| 20:04 | justin_smith | a bit of theory can save you from big mistakes (the kind of mistakes that waste cumulative years of your life) - but the answer to moving forward often isn't more theory |
| 20:11 | Guest47278 | justin_smith: a lot of theory can also help tremendously with job interviews. I know of people that have talked their way into high positions - but become notorious for being actually incapable, besides good speech - once incumbent.. |
| 20:11 | Guest47278 | Too little, too late, of course! |
| 20:11 | raspasov | Guest47278: totally, building stuff == king for me as well; with just enough theory without getting bogged down by it |
| 20:12 | raspasov | yea, practical knowledge != good interview skills :) |
| 20:15 | raspasov | I would even argue that it's even more about how you structure your side-effects, I/O etc operations in your code that ultimately determines the amount of potential bugs your code has, and not strong/weak typing, etc; of course I have zero research to prove that :) |
| 20:16 | Guest47278 | raspasov: I'd generally agree, although you could say that assertion is vague enough to be a truism |
| 20:17 | Guest47278 | raspasov: I've seen functional people program in OO languages like Ruby, trying to do it in a functional way, ignoring OO principles. That ends up coming off worse though |
| 20:17 | Guest47278 | even if, technically, you could say it has less side-effects etc. |
| 20:17 | raspasov | :) |
| 20:18 | raspasov | yea, but does one good example make it a truism? aka basic unit tests, or type checking? |
| 20:18 | raspasov | i.e. is the fact that object is of type X, actually make your program correct, is this a "good enough" check? I think it's "basic" check |
| 20:19 | raspasov | basically, there's no substitute for thinking and reasoning about your program |
| 20:19 | Guest47278 | I feel like there is a gap between static & dynamic analysis that needs bridging |
| 20:19 | raspasov | a perfect checker would be an AI :D |
| 20:19 | Guest47278 | ^ |
| 20:19 | raspasov | lol |
| 20:20 | Guest47278 | A more feasible short-term bridge would be something that essentially animates a model of your code, based upon static analysis - allowing the human to dynamically analyse the code |
| 20:20 | papachan | seangrove thank you for your help last night, i have finally put in production my code |
| 20:23 | raspasov | there's also this testing tool for Clojure if you haven't seen it https://github.com/clojure/test.check; a good video intro to the concept https://www.youtube.com/watch?v=JMhNINPo__g |
| 20:31 | seangrove | papachan: Are you sure it was me? |
| 20:32 | papachan | seangrove oh sorry tab select you instead of seancorfield |
| 20:33 | seancorfield | Too many Seans :) |
| 20:33 | seangrove | No worries, wanted to make sure the right Sean got the thanks ;) |
| 20:33 | seancorfield | I used to have IRC highlight "sean" but seangrove gets a lot more responses that I do so I took that off :) |
| 20:34 | seancorfield | glad you got things working papachan - how much Clojure do you have in production now? |
| 20:36 | papachan | seancorfield not so much but my conversion from params to session cookie works finally |
| 20:37 | seancorfield | Cool... |
| 20:37 | seancorfield | Well, I'm out of here for the day. May pop in later, but I have to be up at 5am to catch my flight to The Strange Loop. Hope to see some of you there? |
| 20:39 | seangrove | seancorfield: That's a conference I need to make time to go see next year - hope you enjoy it! |
| 20:40 | seancorfield | This will be my third year - it was awesome in 2011 & 2013 (I was in England in 2012, unfortunately). |
| 20:40 | seancorfield | And I already have the dates in my calendar for 2015 :) |
| 21:53 | andyf | Is there 'standard' terminology to name the relationship between namespaces where one has a name that is an extension of another, e.g. namespace 'foo.bar.baz' is a ___ of namespace 'foo.bar' |
| 21:54 | andyf | And perhaps a related question, is there such a terminology for Java packages? |
| 21:55 | Grazy | Hello all! |
| 21:57 | amalloy | andyf: in java i'd call it a subpackage. i don't know what it is in clojure |
| 22:02 | justin_smith | and in both java and clojure that concatenative nesting means something to a human reader, but really doesn't affect how the language does things (there aren't different rules for using foo.bar.baz from foo.bar as opposed to using foo.baz) |
| 22:36 | TimMc | justin_smith: Java (and probably the JVM) has a notion of "sealed packages", which I assume refers to prefixes -- but I could easily be wrong on this, since I've never cared to look into it. |
| 22:47 | justin_smith | TimMc: that may be the case actually - it looks like subpackage inherit certain classloader settings of their parents too |
| 22:47 | justin_smith | but in practice, these things don't effect my code much |
| 23:06 | Jaood_ | mutual recursion apart, are forward declarations used much in the wild? |
| 23:09 | justin_smith | Jaood_: I sometimes use them to make reading a namespace top to bottom make more sense |
| 23:14 | Jaood_ | justin_smith: I see, haven't seen much code do that, I guess its a matter of taste then |
| 23:14 | Jaood_ | justin_smith: the high-level functions are just mostly at the bottom |
| 23:20 | justin_smith | right, it was an aesthetic choice |
| 23:34 | Jaood_ | b |