2014-09-11
| 00:01 | wildnux | is this the idiomatic way of applying a function to every elements in a nested list? |
| 00:01 | wildnux | (map #(apply * %) [[1 2 3] [4 5 6]]) |
| 00:01 | wildnux | this works, are there any other better way to achieve this? |
| 00:01 | justin_smith | ,(map * [1 2 3] [4 5 6]) |
| 00:01 | clojurebot | (4 10 18) |
| 00:02 | justin_smith | ,(apply map * [[1 2 3] [4 5 6]]) |
| 00:02 | clojurebot | (4 10 18) |
| 00:03 | justin_smith | or wait - you want (* 1 2 3) and (* 4 5 6) |
| 00:03 | wildnux | justin_smith: I want function to apply to each each element of the outer list (apply funtion to nested list) |
| 00:03 | wildnux | justin_smith: so that it should give (6 120) |
| 00:03 | justin_smith | right, so #(apply * %) is the best option |
| 00:03 | wildnux | ok |
| 00:03 | wildnux | ,(map #(apply * %) [[1 2 3] [4 5 6]]) |
| 00:03 | clojurebot | (6 120) |
| 00:04 | justin_smith | though #(reduce * %) would also give the right answer |
| 00:05 | wildnux | now, if i wanted to get the max of the resulting elements i could do |
| 00:05 | wildnux | ,(max (map #(apply * %) [[1 2 3] [4 5 6]]) |
| 00:05 | clojurebot | #<RuntimeException java.lang.RuntimeException: EOF while reading> |
| 00:05 | wildnux | ,(max (map #(apply * %) [[1 2 3] [4 5 6]])) |
| 00:05 | clojurebot | (6 120) |
| 00:05 | justin_smith | I think you want apply max |
| 00:05 | wildnux | ,(reduce max (map #(apply * %) [[1 2 3] [4 5 6]])) |
| 00:05 | clojurebot | 120 |
| 00:05 | justin_smith | yeah, apply max and reduce max would both work |
| 00:06 | wildnux | i could do that, now, my question is how do i get that list [4 5 6] because of which 120 (max) was returned |
| 00:06 | justin_smith | ,(apply max (map #(apply * %) [[1 2 3] [4 5 6]])) |
| 00:06 | clojurebot | 120 |
| 00:06 | wildnux | is there a way to get that list which has max product? |
| 00:06 | justin_smith | max-key |
| 00:07 | justin_smith | ,(max-key #(apply * %) [1 2 3] [4 5 6]) |
| 00:07 | clojurebot | [4 5 6] |
| 00:07 | justin_smith | and again, if the args are all in one list, you can use apply, of course |
| 00:08 | justin_smith | ,(apply max-key #(apply * %) [[1 2 3] [4 5 6]]) |
| 00:08 | clojurebot | [4 5 6] |
| 00:08 | justin_smith | clojure is magical |
| 00:08 | wildnux | justin_smith: awesome :) |
| 00:08 | wildnux | this is sooo cool |
| 00:09 | wildnux | justin_smith: extending this, is there a funtion which takes any function instead of 'max' in max-key? |
| 00:09 | justin_smith | (first (sort-by f l)) |
| 00:09 | justin_smith | l being a sequence |
| 00:10 | wildnux | aah ok |
| 00:11 | justin_smith | and f should give the most qualified item the lowest score |
| 00:11 | justin_smith | otherwise you have to walk the whole sequence at the end |
| 00:11 | justin_smith | you could also optimize that with a reduce |
| 00:11 | justin_smith | (in order not to build a collection you don't really need) |
| 00:14 | justin_smith | ,(reduce (fn [[score mx] e] (let [s2 (count e)] (if (> s2 score) [s2 e] [score mx]))) [0 nil] ["hello" "this" "is" "sort by count"]) |
| 00:14 | clojurebot | [13 "sort by count"] |
| 00:15 | justin_smith | appropriate if you don't want to call your f more than once per item, and don't want to build the whole ordered collection |
| 02:01 | dorkmafia | i copied my directory over to another computer then tried to run lein repl on it and now i'm getting this error: Exception in thread "main" java.lang.UnsupportedClassVersionError: org/jivesoftware/smack/Roster : Unsupported major.minor version 51.0 |
| 02:01 | amalloy | dorkmafia: your version of java is too old |
| 02:01 | dorkmafia | oh yes |
| 02:01 | amalloy | i forget what 51 means, but i think it means you need 7 and have 6- |
| 02:01 | dorkmafia | thank u |
| 02:01 | dorkmafia | yup |
| 02:02 | dorkmafia | makes sense i forgot about that |
| 02:03 | dorkmafia | do i need the jre and jdk? or just the jdk? |
| 02:04 | beamso | jdk |
| 02:07 | dorkmafia | so I'm wrapping this xmpp lib and a lot of things require me to pass the connection to my functions I get the connection when the user logs in is a way for me to store in a def? |
| 02:08 | dorkmafia | there* |
| 02:09 | beamso | you could store the connection in an atom |
| 02:14 | dorkmafia | oh cool how would i do that? :B |
| 02:15 | beamso | something like (def conn (atom <however you established your connection>)) |
| 02:15 | beamso | http://clojure.org/atoms |
| 02:18 | dorkmafia | ok cool thanks i'll check it out |
| 02:28 | yedi_ | i'm making a metronome webapp, so timing is hugely important. it seems that there is some lag when using timeout. e.g: https://gist.github.com/yedi/1abcdf0d8675fd532eca |
| 02:29 | yedi_ | there seems to 2-3 milliseconds of lag when using timeout (it jumps up to about 6-7 ms of lag in my actual application) |
| 02:29 | yedi_ | is there anyway to nullify or account for this lag? or is there a better way to handle timing in clojurescript? |
| 02:30 | beamso | javascript isn't threaded |
| 02:30 | yedi_ | right |
| 02:31 | beamso | i think even if it was threaded you would see the timeout being longer than the exact 1000 that you're looking for |
| 02:31 | yedi_ | know of a better way? |
| 02:33 | yedi_ | i guess i could try to test / calculate the lag and then adjust the timing based off of that. but it seems like that could get messy / won't be perfect either |
| 02:39 | beamso | i found this : http://www.sitepoint.com/creating-accurate-timers-in-javascript/ |
| 02:40 | beamso | basically they are running a shorter timeout and adjusting by the difference in intended and actual timeout they encounter |
| 02:47 | piranha | beamso: in reality you don't even need to adjust anything, just check what time is it now. Plus it may be worth it having a setTimeout instead of setInterval so you can try to ask for a shorter delay if you need that |
| 02:47 | piranha | on the other hand, you can just have very short (1-5ms) interval and not worry about it, I guess |
| 02:47 | piranha | but that still could backfire if the system is a bit overloaded :( |
| 02:47 | beamso | okay |
| 02:48 | piranha | ah, that's what they are doing (adjusting the timer) - didn't read till the end |
| 02:49 | piranha | beamso: plus I see you're using async channels, and I think it could a bit of it's own overhead |
| 02:49 | piranha | maybe it's worth to to stick with primitives in your case... |
| 02:49 | beamso | i should be using async channels, but i need to learn about them. |
| 02:49 | beamso | it was yedi_'s gist |
| 02:50 | piranha | beamso: I need to drink coffee before I look into a clojure channel, I'm sorry :) |
| 02:50 | piranha | yedi_: ^ |
| 02:51 | beamso | not a problem. |
| 02:52 | yedi_ | ah thanks guys |
| 02:52 | yedi_ | i'll try using primitives before just going with the 'figure out the time difference and change timeout accordingly approach) |
| 02:52 | yedi_ | though i just love using core.async for everything |
| 02:52 | yedi_ | makes me feel nice n fuzzy inside |
| 02:53 | piranha | it does :) |
| 02:53 | piranha | but in this case you want to get least amount of layers between a cpu and your code, and you've got js already :) |
| 02:54 | piranha | no need to add core.async on top for it to be not exactly real time :) |
| 04:36 | magopian | can someone please point me at some docs on the "volatile!" function? can't find any :/ |
| 04:55 | maxthoursie | magopian: https://github.com/clojure/clojure/blob/42f68bc7688db3a24565dfcdc1cba92dd8a99159/src/clj/clojure/core.clj#L2390 |
| 04:55 | maxthoursie | it's not exactly verbose though :) |
| 04:56 | magopian | ah :) |
| 04:56 | magopian | so what's a volatile? :) |
| 04:56 | maxthoursie | * volatiles - there are a new set of functions (volatile!, vswap!, vreset!, volatile?) to create and use volatile "boxes" to hold state in stateful transducers. Volatiles are faster than atoms but give up atomicity guarantees so should only be used with thread isolation. |
| 04:57 | maxthoursie | (from changes.md) |
| 04:57 | magopian | ok, so it's linked with transducers, that's why i see those come up from time to time (i'm trying to get my head around transducers, but still having issues atm) |
| 04:58 | maxthoursie | if I understand correctly it's just a wrapper around javas volatile |
| 04:58 | maxthoursie | they were added as they were beneficial for the implementation of transducers |
| 04:59 | magopian | ok ;) |
| 04:59 | magopian | thanks a lot for the answe r;) |
| 04:59 | maxthoursie | np |
| 05:36 | CookedGryphon | How would I write a core async buffering strategy which does a distinct-by :id just for things in the buffer but keeping order |
| 05:36 | CookedGryphon | so I have a number of overlapping events, each of which have an id |
| 05:37 | CookedGryphon | and for each event i might receive an undetermined number of updates |
| 05:37 | CookedGryphon | I want to apply backpressure, but only keeping the latest event for each ID, as each event also contains all the historical data (persistent data structures rule) |
| 05:38 | CookedGryphon | for extra credit, some way of controlling whether the order is maintained as first-id-in, or latest-id-updated |
| 05:39 | CookedGryphon | any ideas? My best so far was to create a chan per ID with a sliding buffer 1 and then merge them all, but keeping track of all that when the event ids are unlimited and constantly increasing is tricky |
| 05:45 | gws | CookedGryphon: you could write your own buffer that implemented your strategy (maybe using a set for testing membership?) - see this for inspiration https://github.com/clojure/core.async/blob/master/src/main/clojure/clojure/core/async/impl/buffers.clj |
| 05:49 | CookedGryphon | gws: that looks like exactly what I need, thanks a lot! |
| 05:51 | lvh | I have a list of different arguments; I want to check if (apply f args) is equal to the same constant for each of them |
| 05:52 | lvh | can I coerce core.test's "are" macro into doing that? |
| 05:57 | gws | ,(apply = 42 (map (partial apply +) [[21 21] [21 21]])) |
| 05:57 | clojurebot | true |
| 05:57 | gws | ,(apply = 42 (map (partial apply +) [[21 21] [21 22]])) |
| 05:57 | clojurebot | false |
| 05:58 | gws | lvh: would that do what you want? |
| 05:58 | lvh | gws: hm, maybe yes |
| 05:58 | lvh | I didn't realize apply had an & colls part in the signature |
| 06:01 | lvh | err, or more accurately that = was variadic I guess |
| 06:02 | gws | yep! and > and < and so on |
| 06:02 | gws | ,(> 5 4 3 2 1) |
| 06:02 | clojurebot | true |
| 06:03 | gws | ,(> 5 4 3 2 2) |
| 06:03 | clojurebot | false |
| 06:03 | gws | ,(>= 5 4 3 2 2) |
| 06:03 | clojurebot | true |
| 06:04 | lvh | ack, this unfortunately doesn't help me because these are byte arrays |
| 06:05 | lvh | (so = doesn't work :() |
| 06:06 | lvh | I guess what I really want is (apply are ...), except of course that doesn't really work (I think) because are's a macro? |
| 06:08 | lvh | every? true? it is |
| 06:26 | piranha | anybody using prismatic.schema here? I'm not sure what's the best way to express "for some values of :filter, :user_id should be specified" in {:filter (s/enum ...), :user_id s/Int} |
| 06:29 | sm0ke | piranha: look at s/pred |
| 06:29 | sm0ke | you can define a function there |
| 06:30 | piranha | sm0ke: but pred only gets it's own value to check, right? in this case how do I express "true if other value is something"? |
| 06:31 | piranha | ah, it could be much more complex than that |
| 06:31 | piranha | it's just pred is greatly simplified |
| 06:31 | piranha | ok, I'll try to look into that |
| 06:32 | piranha | I actually made it work through s/either, but then error reporting becomes really obscure :\ |
| 07:13 | babygau | https://www.refheap.com/ce7f89cbca4992e046c8dc50c |
| 08:11 | rurumate | Hello #clojure, I want to find all (nonempty) subsequences of given sequence a. So for example, (sublists [1 2 3]) should evaluate to '((1) (2) (3) (1 2) (1 3) (2 3) (1 2 3)). I know (comp set #(map sort %) powerset) can do it, but it seems wasteful to calculate the full powerset and then throw away all the lists that are just permutations of the same sorted list. |
| 08:17 | clgv | rurumate: then just write a recursive function that directly computes the set of all unordered combinations |
| 08:18 | clgv | rurumate: I dont know how your powerset function is implemented, but you can probably steal the general idea from it |
| 08:35 | jkj | http://stackoverflow.com/questions/22959804/inserting-postgresql-arrays-with-clojure/25786990#25786990 |
| 08:49 | Kamuela | Is clojure relational/logic programming? |
| 08:49 | clgv | Kamuela: no, not the core language itself. but there is a library called core.logic that allows logic programming under clojure |
| 08:51 | Kamuela | clgv, That seems to be what I'm using with this tutorial |
| 08:56 | clgv | Kamuela: ok, so you are actually learning two things at once |
| 08:57 | Kamuela | clgv, the tutorial purports itself as an introduction to logical programming |
| 08:57 | clgv | Kamuela: yeah thats ok when they use core.logic |
| 08:57 | clgv | Kamuela: Clojure itself is mostly functional programming, though there are imperative constructs for side-effects as well |
| 09:05 | rurumate | list powerset, seems workey: https://www.refheap.com/90094 |
| 09:06 | clgv | rurumate: recursive concat may blow your stack for large `xs` |
| 09:08 | clgv | rurumate: ah and non-tail recursion as well |
| 09:13 | Kamuela | clgv, what do you think of core.logic for AI? |
| 09:17 | clgv | Kamuela: I did not use core.logic, yet |
| 09:18 | clgv | Kamuela: I only read about it |
| 09:18 | rurumate | clgv: yes it would be nicer with lazy seq |
| 09:19 | rurumate | clgv: what exactly do you mean "recursive concat"? |
| 09:20 | clgv | rurumate: when you wrap concats in each other |
| 09:21 | rurumate | hmm yes seems like that's the case there |
| 09:27 | lvh | reiddraper: Hi! I'm playing with test.check for the first time. Thanks for building it. |
| 09:28 | lvh | reiddraper: I was wondering if there's a better way to get length-n byte arrays rather than (gen/fmap byte-array (gen/vector gen/byte n)) |
| 09:28 | lvh | Doesn't seem like I can use "bytes" for it. Also, if that would be a good thing to contribute to test.check :) |
| 09:32 | clgv | lvh: what is the problem with that? the possible overhead due to vector construction? |
| 09:33 | lvh | clgv: no, no problem with that, except that there's already a gen/bytes that *almost* does what I want |
| 09:33 | lvh | clgv: and gen/vector, a pretty close cousin, can be parametrized by length |
| 09:34 | clgv | lvh: but it's exactly the same structure |
| 09:35 | lvh | clgv: Yes, I created that thing by copying bytes' implementation |
| 09:35 | lvh | clgv: I'm trying to figure out if there are clever ways to constrain the generator's output |
| 09:35 | clgv | lvh: I think you could externally control its size |
| 09:35 | lvh | reading some of the code it looks like maybe there's something like that |
| 09:35 | lvh | by clever I mean "not generating a bunch of arrays and throwing away the ones that aren'te xactly 16 bytes long) |
| 09:36 | clgv | lvh: the probably that arity impl needs to be added^^ |
| 09:37 | lvh | clgv: that's what I would guess but unfrtunately right now bytes isn't even supposed to be called, it's just a constant |
| 09:39 | clgv | lvh: thats no problem. it can be easily converted to a function with both arities |
| 09:40 | lvh | clgv: wtihout breaking backwards compatibility? really? |
| 09:40 | lvh | clgv: you teach it to be a regular value and then override its IFn behavior or something? |
| 09:40 | AeroNotix | I want to run a jetty/ring handler on port 0 (random port) how would I then retrieve the port number it is using? This is for tests. |
| 09:41 | clgv | lvh: well, were is written that you are not allowed to break backwards compatibility for improvements? imho you only need to communicate that there are breaking changes |
| 09:41 | lvh | clgv: oh, okay; yeah, sure -- I guess that's an implicit question for reiddraper :) |
| 09:42 | mikerod | If we have something like: (LocalDate. 1) called, which constructor does Clojure call? LocalDate(Object) or LocalDate(long) |
| 09:42 | mikerod | I know clj numeric literals are boxed Long by default |
| 09:43 | mikerod | but does the Compiler automatically cast it as primitive to call the LocalDate(long) in case like this? Perhaps this is a dumb question, but I'm a bit unclear how this part works. |
| 09:52 | clgv | mikerod: set warn-on-reflection on true and see what it tells you |
| 10:10 | mikerod | clgv: I have that set and it doesn't say anything |
| 10:12 | lvh | is https://github.com/paraseba/lein-reload still the thing I use if I want my tests to be constantly run? |
| 10:13 | pjstadig | lvh: https://github.com/jakemcc/lein-test-refresh is actively maintained |
| 10:15 | lvh | pjstadig: thanks! |
| 10:15 | clgv | mikerod: I'd vote for LocalDate(long) when you pass the primitive long - you can check via a decompiler. |
| 10:16 | mikerod | clgv: Do you mean when I specifically "ask" for a primitive though? Yes, I think I'll go to the decompiler for this one. |
| 10:17 | bbloom | Bronsa: did you ever get around to looking in to jvm mechanisms for chaperons etc? |
| 10:26 | clgv | bbloom: what is a chaperon? |
| 10:27 | bbloom | clgv: racket stuff for meta-object protocol voodoo for checking contracts and other things dynamically via object proxies |
| 10:27 | clgv | bbloom: uh ok. |
| 10:28 | bbloom | clgv: http://docs.racket-lang.org/reference/chaperones.html |
| 10:33 | ToxicFrog | So, with core.typed, I'm having two weird issues. I haven't added any type annotations yet, just enabled checking for a few namespaces in preparation. |
| 10:33 | ToxicFrog | The first issue is that ns spellcast.core has (require '[taoensso.timbre :as log]) and then calls some things as log/foo ..., and this produces a 'no such namespace: log' message. |
| 10:34 | ToxicFrog | I also get a 'not checking spellcast.game: tagged :collect-only' -- but there's no such tag. |
| 10:36 | jlongster | what is the use case for the transformation function in `transduce` taking in the final result of the transformation? https://github.com/clojure/clojure/blob/master/src/clj/clojure/core.clj#L6521 |
| 10:37 | dnolen_ | jlongster: it's the completion step |
| 10:37 | tbaldridge | jlongster: consider starting with (transient x) and ending with (persistent! x) |
| 10:38 | dnolen_ | jlongster: you imagine also imagine reducing over a resource like a file and closing it in the completion step |
| 10:38 | jlongster | dnolen_: tbaldridge: huh, interesting. thanks. I can see that |
| 10:38 | bounb | anyone got a copy of rhickey's chunked sequences talk? |
| 10:39 | ToxicFrog | Hmm. refer :all and (use) are just scope hacks, right? They don't actually change the contents of the current namespace? |
| 10:44 | llasram | ToxicFrog: The opposite actually. All `refer`ing (include `:all`) modifies the `refer'ing namespace to map the name symbols to the target vars |
| 10:45 | ToxicFrog | llasram: huh. So if ns A refers, say, clojure.core.typed/ann, and ns B requires A, B can then call A/ann? |
| 10:51 | llasram | ToxicFrog: I believe that is actually the case, yes |
| 10:51 | CookedGryphon | only if they fully qualify it though |
| 10:52 | llasram | Most tooling (and stdlib functions?) ignores vars which don't belong to the namespace refering them, but the namespace itself refers to the var |
| 10:55 | llasram | Oh, nevermind -- I'm confused. Half of what I said is true, but namespaces differentiate between "interning" and "refering" |
| 10:55 | llasram | Well, kind of. |
| 10:56 | llasram | No, they don't. Ok, so you can't say A/ann, but only because there's a check on lookup of `ann` in `A` to verify that the namespace of the var found for `ann` is the same namespace |
| 10:58 | llasram | https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/Namespace.java#L195-L200 |
| 10:59 | llasram | But the actual mechanics of what is stored in the namespace are identical for vars which "belong" to the namespace vs referred from others |
| 11:00 | justin_smith | llasram: woah, a validating sanity check, in Clojure? astounding news |
| 11:00 | justin_smith | I kid because I love |
| 11:01 | ToxicFrog | llasram: aah. Honestly that kind of seems like the worst of both worlds~ |
| 11:10 | mikerod | Does anyone know where the notation used in the Java specs is defined? Such as what <: means? |
| 11:10 | mikerod | I don't see it anywhere, it just starts being used... |
| 11:10 | mikerod | or << |
| 11:10 | mikerod | I think I have a guess what they are meaning, but it'd be nice to have clarification |
| 11:11 | clgv | mikerod: reserved names or something like that? |
| 11:12 | justin_smith | mikerod: is it documented somewhere around here? http://docs.oracle.com/javase/8/docs/api/ |
| 11:12 | clgv | mikerod: http://docstore.mik.ua/orelly/java-ent/jnut/ch02_05.htm |
| 11:14 | justin_smith | mikerod: do you have a link to a page using this notation you are unsure of? |
| 11:33 | mikerod | clgv: justin_smith ok to clarify, I'm not referring to Java language syntax |
| 11:34 | mikerod | I'm referring to notation used to describe the Java specs |
| 11:34 | mikerod | justin_smith: example: http://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.12.2.2 |
| 11:35 | mikerod | Notation like "Ai << Fi (1 ≤ i ≤ n) " |
| 11:35 | mikerod | what is "<<" |
| 11:35 | mikerod | Or "Ai <: Si " |
| 11:35 | mikerod | What is "<:" |
| 11:35 | mikerod | I do not see a page in the specs that introduce what these notations mean. |
| 11:35 | mikerod | So apparently they have some more global meaning, but I don't know where that is defined. |
| 11:36 | justin_smith | ≤ is the mathematical less than or equal to |
| 11:36 | mikerod | Even better: " Ul <: Bl[R1=U1,...,Rp=Up]" I'm not 100% sure I know what the square brackets are here "[" "]" |
| 11:36 | justin_smith | is that what you mean by <: |
| 11:36 | justin_smith | maybe it displays differently in my browser |
| 11:36 | justin_smith | oh never mind, now I see it |
| 11:37 | mikerod | Yeah it is a less-than and a colon |
| 11:37 | mikerod | I don't think I have a browser issue, it seems like it intended to mean something |
| 11:37 | justin_smith | yeah, I found it |
| 11:37 | mikerod | it is about being a subtype of another type I'm sure |
| 11:37 | justin_smith | I just asked a mathematician friend, on the off chance he would recognize it from somewhere... |
| 11:37 | mikerod | but I see nothing specific about this notation and it used throughout the specs |
| 11:38 | mikerod | and google searching for this notation is not so good :P |
| 11:38 | justin_smith | right |
| 11:39 | justin_smith | I bet it means something like inherits from / subtyping |
| 11:39 | mikerod | yeah, I'd like to know the difference between "<:" and "<<" |
| 11:39 | justin_smith | or derives |
| 11:39 | mikerod | and some specifics on this bracketed "Bl[R1=U1 <etc>]" notation |
| 11:40 | mikerod | I just think it is frustrating and would have expected it to be defined somewhere :P |
| 11:40 | justin_smith | mikerod: click the footnotes! |
| 11:40 | justin_smith | there are hypertext footnotes on the rules that explain the notation |
| 11:40 | mikerod | There was even http://docs.oracle.com/javase/specs/jls/se7/html/jls-1.html#jls-1.3 but no good |
| 11:40 | mikerod | oh |
| 11:41 | justin_smith | "U << V indicates that type U is convertible to type V by method invocation conversion" |
| 11:41 | mikerod | I don't see what to click on |
| 11:41 | justin_smith | ". We write T <: S to indicate that that the subtype relation holds between types T and S." |
| 11:41 | justin_smith | there are footnote links near each item |
| 11:42 | mikerod | ah |
| 11:42 | mikerod | http://docs.oracle.com/javase/specs/jls/se7/html/jls-4.html#jls-4.10 |
| 11:42 | mikerod | like that |
| 11:42 | justin_smith | mikerod: also, you can control-f here https://en.wikipedia.org/wiki/List_of_mathematical_symbols for things like <: |
| 11:42 | mikerod | justin_smith: awesome |
| 11:42 | justin_smith | though that does not have << |
| 11:42 | mikerod | problem solved hah |
| 11:43 | justin_smith | oh it has ≪ instead - thanks unicode! |
| 11:43 | mikerod | ,(inc justin_smith) |
| 11:43 | clojurebot | #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: justin_smith in this context, compiling:(NO_SOURCE_PATH:0:0)> |
| 11:43 | justin_smith | you may not want the , there :) |
| 11:43 | mikerod | (inc justin_smith) |
| 11:44 | lazybot | ⇒ 76 |
| 11:44 | mikerod | oh, I didn't realize taht's how that one worked haha |
| 11:44 | justin_smith | it's a pseudo-clojure bot command |
| 11:44 | mikerod | I see |
| 11:46 | mikerod | Well now the Java specs are much more fun to read. |
| 11:46 | justin_smith | as in "not 100% bewildering"? |
| 12:44 | izirku | hi all! is there a predicate to check if something is an atom |
| 12:45 | justin_smith | atom? |
| 12:45 | justin_smith | oh, I thought that existed, I guess not! |
| 12:45 | llasram | ,(instance? clojure.lang.Atom (atom 0)) |
| 12:45 | clojurebot | true |
| 12:45 | justin_smith | there you go |
| 12:46 | izirku | aha! you just saved my life! |
| 12:46 | TimMc | phew |
| 12:46 | TimMc | I'm glad you didn't die. |
| 12:47 | izirku | coming from CL, it's still a bit foreign, but I'm adjusting. Thank you all once again! |
| 12:48 | justin_smith | izirku: nb this is not "atom" in the sense cl calls something atomic |
| 12:48 | justin_smith | izirku: but I assume you allready knew that |
| 12:49 | izirku | justin_smith: yes, I know, I just needed a check if I needej to (deref place) in my macro if it's an atom :) |
| 12:49 | llasram | Scary |
| 12:49 | tadni_` | On a related note, what does Clojure call small the equivialant of a stereoptypical "Lisp Atom"? |
| 12:50 | noonian | it would be nice if there was an atomic? fn, but it doesnt come up as much since clojure collections are immutable whereas it mattered more in cl and scheme since they were mutable |
| 12:50 | technomancy | tadni_`: I think "atom" means different things in lisp depending on how far back you go |
| 12:50 | technomancy | it used to be a synonym for symbol iirc? erlang uses that terminology. |
| 12:51 | technomancy | but I think the term you're looking for is scalar |
| 12:51 | noonian | i like the little schemers definition |
| 12:51 | technomancy | (meaning not compound) |
| 12:51 | noonian | yeah |
| 12:51 | justin_smith | technomancy: so numbers and other primitives were not atomic? |
| 12:51 | tadni_ | technomancy: I've always known it as a term for things that are indivisible. |
| 12:52 | tadni_ | Numbers, strings, some single charecters like "*". |
| 12:53 | justin_smith | but numbers and strings are divisible into bits and chars... |
| 12:53 | bbloom | atomic or scalar is a matter of perspective :-) |
| 12:53 | tadni_ | justin_smith: Well yeah, not my metrics though really. |
| 12:54 | tadni_ | Kinda just what lisps, or at least Emacs Lisp intro quantifies. |
| 12:54 | technomancy | justin_smith: depends how far back you go iirc |
| 12:55 | dagda1_ | what does this type of expression mean (into {} *1) |
| 12:56 | dagda1_ | it is in the docs for map http://clojuredocs.org/clojure_core/1.2.0/clojure.core/map |
| 12:57 | hiredman | *1 is bound to the result of the last expression in the repl |
| 12:57 | technomancy | justin_smith: this seems to consider numbers and atoms distinct: http://www.softwarepreservation.org/projects/LISP/book/Weismann_LISP1.5_Primer_1967.pdf |
| 12:57 | TimMc | izirku: You can also check if something is an IDeref |
| 12:58 | TimMc | izirku: Why does your macro care if something is an atom? |
| 12:58 | izirku | TimMc: IDeref? |
| 12:58 | justin_smith | dagda1_: look at (doc into) |
| 12:59 | justin_smith | *1 means "the last result evaluated in the repl session" |
| 12:59 | dagda1_ | justin_smith: k |
| 13:00 | izirku | TimMc: it's a PeopleSoft specific DSL wrapper on top of Korma. When I have an WHERE setid IN (...) .. |
| 13:00 | TimMc | &(map (partial instance? clojure.lang.IDeref) [(atom 0) (future 5) (promise) (var +) (delay 4) :abc]) |
| 13:00 | lazybot | java.lang.SecurityException: You tripped the alarm! future-call is bad! |
| 13:00 | TimMc | ,(map (partial instance? clojure.lang.IDeref) [(atom 0) (future 5) (promise) (var +) (delay 4) :abc]) |
| 13:00 | clojurebot | #<SecurityException java.lang.SecurityException: no threads please> |
| 13:00 | TimMc | anyway |
| 13:00 | noonian | yeah, *1 only means something in the repl, its not normal clojure magic syntax |
| 13:00 | noonian | ,(+ 2 4) |
| 13:00 | clojurebot | 6 |
| 13:00 | noonian | ,*1 |
| 13:00 | clojurebot | #<Unbound Unbound: #'clojure.core/*1> |
| 13:00 | justin_smith | noonian: *1 does not work with clojurebot, each command is a new repl |
| 13:00 | izirku | TimMc: my values for IN are stored in an atom, I'm had to make sure I do deref it |
| 13:00 | noonian | i see |
| 13:01 | noonian | &(+ 1 1) |
| 13:01 | lazybot | ⇒ 2 |
| 13:01 | noonian | &*1 |
| 13:01 | lazybot | ⇒ #<Unbound Unbound: #'clojure.core/*1> |
| 13:01 | justin_smith | so "the last value returned by the repl" is unbound |
| 13:01 | noonian | shrug |
| 13:01 | justin_smith | yeah, it's inconvenient |
| 13:01 | justin_smith | ,(do 1 *1) |
| 13:01 | clojurebot | #<Unbound Unbound: #'clojure.core/*1> |
| 13:01 | izirku | TimMc: it works now. Thanks for the IDeref explanation, will come in handy! |
| 13:01 | TimMc | izirku: Oh, this is for the code the macro emits, not the macro's own processing. |
| 13:03 | izirku | TimMc: yes, you are right on target :) |
| 13:07 | yedi | is there a built-in data structure for / what's the best way to create a sliding queue with a size limit. (where new elements pop off old ones when the limit has been reached) |
| 13:08 | yedi | could just create a function for appending to a list, that also pops out the other end but I was wondering if there was a more elegant way |
| 13:13 | justin_smith | yedi: so a dequeue? |
| 13:13 | yedi | lemme google |
| 13:13 | justin_smith | https://github.com/pjstadig/deque-clojure |
| 13:13 | justin_smith | a deque is a queue that supports efficient addition or removal from either end |
| 13:14 | hiredman | there is no built in immutable sliding queue, there is a queue, and building a sliding queue from that can be as simple as checking the size and poping when you add an item if the "size" would overflow your bounds |
| 13:15 | noonian | core async channels can use sliding buffers, i'm not sure what your use case is but that might be more appropriate if you're comfortable with core async |
| 13:15 | bbloom | core async's buffers are mutable |
| 13:15 | hiredman | right |
| 13:15 | hiredman | not values |
| 13:19 | noonian | yep, but yedi didn't say anything about what he wanted it for |
| 13:19 | yedi | i need to record a bunch of things in real time, but I only will ever care about the last 10 things recorded |
| 13:20 | hiredman | well, he asked about built in data structures, and those are all values |
| 13:20 | yedi | ty hiredman, that's what i'll go with most likely |
| 13:22 | justin_smith | I keep forgetting about clojure.lang.PersistentQueue - it would be nice to have a literal syntax for it |
| 13:22 | justin_smith | maybe #[] |
| 13:22 | justin_smith | seems a natural fit |
| 13:23 | technomancy | $google clojure queuefish |
| 13:23 | lazybot | [fogus: So long, and thanks for all the :-)-] http://blog.fogus.me/2012/07/27/so-long-and-thanks-for-all-the-queue-fish/ |
| 13:23 | hiredman | queue fish! |
| 13:25 | justin_smith | https://groups.google.com/forum/#!topic/clojure-dev/GQqus5Wycno a convo about queue-fish |
| 13:27 | stuartsierra | http://dev.clojure.org/jira/browse/CLJ-1078 and http://dev.clojure.org/jira/browse/CLJ-976 |
| 13:31 | justin_smith | I think queues are good enough for something like #[] instead of #queue [] |
| 13:35 | bbloom | justin_smith: i've needed an immutable queue a handful of times at most, and not once did i ever need a non-empty literal queue |
| 13:35 | bbloom | justin_smith: seems pointless to dedicate syntax to that |
| 13:38 | technomancy | #q/ueue [] ; <- technically namespaced |
| 13:39 | hiredman | #q/u |
| 13:39 | hiredman | bbloom: it would be nice to at least have a function that returns an empty one |
| 13:41 | bbloom | hiredman: yup |
| 13:42 | hiredman | (by which I mean, that is a good point about the non-empty бизнес |
| 13:42 | hiredman | ) |
| 13:49 | dorkmafia | (defn foo [bar] ... ) (defn foo [baz] ... ) is this allowed in clojure two methods with the same name but different inputs? |
| 13:49 | jcsims | no - there's no way for the runtime to differentiate between them |
| 13:50 | dbasch | dorkmafia: if you want polymorphism, take a look at multimethods |
| 13:51 | dorkmafia | cool is there a way to talk to python from clojure? (I should probably google it) |
| 13:53 | justin_smith | dorkmafia: what are your constraints? can you talk to it via the network? can it be the version of python that runs in the jvm? |
| 13:54 | dorkmafia | which version of python runs in the jvm? 2.7? |
| 13:54 | justin_smith | http://www.jython.org/ |
| 13:54 | dorkmafia | they will both run on the same box |
| 13:55 | justin_smith | yeah, looks like they have a 2.7 |
| 13:55 | dorkmafia | cool beans |
| 13:55 | justin_smith | well, with the jvm version it would be in the same process, and won't be able to use C bindings (with all the advantages and disadvantages that these imply) |
| 13:56 | justin_smith | (or maybe some C bindings, but it would be via jni or something similar) |
| 13:56 | justin_smith | *could be in the same process |
| 13:56 | justin_smith | I just picked that as an example as that is the tightest you could bind the two that I know of |
| 13:56 | justin_smith | while talking on a socket is a very loose binding between the two |
| 13:57 | dorkmafia | well i was just going to try and get skype4py working since the skype4java that I tried before had issues |
| 13:58 | technomancy | dorkmafia: hylang.org might be better for that |
| 13:58 | technomancy | I have had luck in the past communicating with skype over dbus |
| 13:58 | technomancy | fsvo "luck" |
| 13:59 | dorkmafia | heh |
| 13:59 | technomancy | as much as anyone with the misfortune of having to use skype for nontrivial things can be said to have luck, I mean |
| 14:06 | stw | I'm using a future to run a third party java library with a timeout, when it times out because the 3rd party library fails the memory and cpu usage remain, what is the best way to isolate this third party call in clojure or to kill it off if it times out? I've looked everywhere, tried future-cancel to no avail |
| 14:07 | justin_smith | stw: what about putting the in its own vm, and shutting that process down as needed? |
| 14:08 | stw | I was thinking about that, wasn't sure if there was a more idiomatic solution |
| 14:08 | stw | in another language I would certainly fork a process for it |
| 14:08 | vanila | hi |
| 14:09 | SegFaultAX | Unfortunately that's a /really/ heavyweight solution. |
| 14:09 | vanila | I've been looking at nanopass frameworkf for making compilers |
| 14:09 | vanila | just wondering if anyone knows other modern compiler building tools? |
| 14:09 | stw | SegFaultAX: yes, any other ideas? |
| 14:10 | SegFaultAX | stw: Is the library still maintained? Is it open source? |
| 14:12 | stw | SegFaultAX: open source yes, maintained, doesn't look like it - contacted the author a while back to see if he was interested in making changes for me, but he wrote back that he's moved on |
| 14:12 | SegFaultAX | I'm wondering if it's practical to patch the library to make it behave better or even support timeouts natively for whatever it's doing. |
| 14:12 | SegFaultAX | stw: Well if its OSS, you could just fork it and make the changes yourself. Is that a reasonable solution? |
| 14:12 | stw | Yes, that's a good thought, I may need to wrap the 3rd party method call |
| 14:13 | SegFaultAX | Out of curiosity, what library is it? |
| 14:13 | stw | SegFaultAX: yes, thats a good idea and I've already made some customizations to it, it's daisydiff https://code.google.com/p/daisydiff/ |
| 14:14 | SegFaultAX | Whoa, that's pretty cool. |
| 14:14 | dorkmafia | technomancy: yah skype is horrid |
| 14:14 | stw | SegFaultAX: works well most of the time, gets hung up on some inputs |
| 14:15 | technomancy | dorkmafia: at my last job it was used for multi-user chat ಠ_ಠ |
| 14:15 | technomancy | like, text chat |
| 14:15 | dorkmafia | yes thats what we use it for toO! |
| 14:15 | dorkmafia | cause who cares about security! |
| 14:16 | technomancy | my condolances |
| 14:16 | technomancy | https://github.com/dakrone/skyyy this is a thing |
| 14:16 | SegFaultAX | stw: Neat, what kinds of edge cases have you found? |
| 14:17 | SegFaultAX | technomancy: You still at Heroku? |
| 14:18 | stw | SegFaultAX: in the limited time I've been using it, tables don't work out so well, adds a lot of new lines, but for the most part pretty good |
| 14:18 | technomancy | SegFaultAX: yeap |
| 14:18 | SegFaultAX | stw: Does it do some kind of semantic evaluation of the DOM? |
| 14:18 | SegFaultAX | technomancy: It's all IRC there, yea? |
| 14:18 | stw | SegFaultAX: we pre-process the html before processing with this |
| 14:19 | technomancy | SegFaultAX: sadly no; we are on hipchat. but it can be bridged to IRC without too much fuss. |
| 14:19 | bbloom | technomancy: what, no chatter? ;-) |
| 14:19 | SegFaultAX | We also use HipChat. The most recent UI update is just all kinds of terrible. :( |
| 14:19 | technomancy | bbloom: haha, we are lucky enough to be fairly insulated from that |
| 14:20 | technomancy | SegFaultAX: I wouldn't know; I use bitlbee =) |
| 14:20 | technomancy | SegFaultAX: can't recommend it strongly enough http://www.phase2technology.com/blog/using-hipchat-through-an-irc-client-with-bitlbee/ |
| 14:21 | SegFaultAX | technomancy: Awesome, thanks! |
| 14:22 | catern | technomancy: that's very neat |
| 14:22 | technomancy | it gets the job done |
| 14:22 | stw | SegFaultAX: somewhat, it parses the dom and compares inline nodes from what I've looked at |
| 14:22 | catern | technomancy: i mean the skyyy thing |
| 14:23 | technomancy | oh... well, same =) |
| 14:23 | catern | fills me with internal conflict though, because it would allow nice command line usage of Skype |
| 14:23 | catern | and... I don't know how to do command line usage of XMPP/Jingle, which I prefer |
| 14:23 | SegFaultAX | stw: Seems like a cool project! |
| 14:24 | ToxicFrog | How does lein handle it when you require two libs that each require a different version of a third library? |
| 14:24 | technomancy | catern: bitlbee is nice for that |
| 14:24 | catern | technomancy: I mean the video chat part |
| 14:24 | technomancy | oh gotcha |
| 14:24 | technomancy | catern: I have just discovered http://talky.io which works reasonably well for small conversations |
| 14:25 | technomancy | all webrtc'd up |
| 14:25 | catern | meh |
| 14:25 | catern | i'm willing to inconvenience people by forcing them to make XMPP accounts :) |
| 14:25 | technomancy | ToxicFrog: whichever one is highest up the dependency graph wins |
| 14:25 | technomancy | catern: depends how badly you want to talk to them I guess |
| 14:26 | ToxicFrog | technomancy: aaaaaaaaaaaaaaa |
| 14:26 | catern | yeah, if I don't force them to make XMPP accounts I just use Google Hangouts or Skype |
| 14:27 | technomancy | catern: talky.io is nice because you can just hand out a short URL, no need for any account setup |
| 14:27 | justin_smith | how hard would it be to make the repl show a stack trace of the running thread when you use an interrupt to stop an evaluation in the repl? |
| 14:27 | AeroNotix | after running a midje test in a cider session I get a: IllegalArgumentException Wrong number of args passed to keyword: :irrelevant-return-value clojure.lang.Keyword.throwArity (Keyword.java:92) |
| 14:27 | technomancy | Hangout invitations still confuse the heck out of me and I use them almost every day |
| 14:27 | justin_smith | AeroNotix: use (pst) to see a fuller stack trace |
| 14:28 | justin_smith | see where you are calling :errelevant-return-value with 0, or more than two, args |
| 14:28 | AeroNotix | justin_smith: it's in midje code... |
| 14:28 | justin_smith | (of course :irrelevant-return-value likely came back from some function you called) |
| 14:28 | ToxicFrog | Hmm. Ok, I thought that core.typed and clj-http wanting different versions of tool.reader was causing the crashes, but apparently not. |
| 14:29 | justin_smith | My point is, see where it intersects with your code. My guess would be you are executing something it hands back to you. Or midge is fucked and you should use clojure.test. |
| 14:29 | AeroNotix | justin_smith: now I get it -- the midje syntax is a bit non-lispy |
| 14:30 | ToxicFrog | Argh. I just want to use core.typed, but I don't even know where to start figuring out what it's conflicting with. |
| 14:32 | justin_smith | AeroNotix: midje is "lispy" in the bizarro sense that rubyists call things lispy |
| 14:32 | AeroNotix | justin_smith: :) |
| 14:34 | bbloom | lispiness aside, midje is just plain harder to use than assertions |
| 14:34 | technomancy | "lispy" -> offers you enough power to do really crazy things |
| 14:34 | bbloom | hell, clojure.test is harder to use than regular assertions |
| 14:34 | noonian | i never understood ruby people calling ruby a lisp |
| 14:34 | AeroNotix | bbloom: I've started using midje, seems to integrate with CIDER/Emacs better |
| 14:35 | bbloom | AeroNotix: i find that non-trivial classes of assertions require me to look at the (poor) docs with 100% frequency |
| 14:35 | justin_smith | AeroNotix: core.test integrates with clojure better - the tests are functions, you call them and they tell you if they failed |
| 14:35 | dbasch | noonian: for the same reason people prepend "smart" to any product name |
| 14:36 | justin_smith | it's the same way Avril Lavine identifies as punk - it makes her and her fans feel cool, and the punks are all like "wat" |
| 14:36 | AeroNotix | Smart Water |
| 14:37 | justin_smith | I actually really like dumb products - I love having a phone that doesn't know what a cloud is, or how to upload my shit to one. |
| 14:37 | technomancy | I'm getting close to having a smarter keyboard than phone. |
| 14:38 | technomancy | probably just need to drop my nokia on concrete a few times |
| 14:38 | justin_smith | heh - I'm just waiting until the atreus app store comes out |
| 14:38 | technomancy | (just finished my ARM port last night) |
| 14:38 | justin_smith | very nice |
| 14:39 | justin_smith | like - make dvorjack available as a free download, but with no shift key - then allow shift as an "in app purchase" on a per-keypress basis |
| 14:39 | justin_smith | then rake in the dough |
| 14:42 | catern | whaat |
| 14:42 | catern | ctrl-m is enter and ctrl-i is tab |
| 14:42 | technomancy | mind_blown.gif |
| 14:42 | catern | i already knew ctrl-[ is escape |
| 14:42 | catern | where can I find more of these |
| 14:43 | catern | helpful things |
| 14:43 | justin_smith | catern: and ctrl-j is return (distinct from enter) |
| 14:43 | ToxicFrog | catern: man ascii |
| 14:43 | catern | ToxicFrog: huh? |
| 14:43 | justin_smith | and control-space is the null byte |
| 14:43 | ToxicFrog | catern: the capital letters on the right correspond to the control codes on the left when ctrl is pressed |
| 14:43 | justin_smith | catern: there is a unix command called "man" |
| 14:43 | justin_smith | catern: the man page for ascii has a bunch of nice info |
| 14:44 | catern | justin_smith: yeah, but I don't see any of these ctrl-[ ctrl-m ctrl-i things in it |
| 14:44 | ToxicFrog | 14:43 < ToxicFrog> catern: the capital letters on the right correspond to the control codes on the left when ctrl is pressed |
| 14:44 | catern | ah |
| 14:45 | ToxicFrog | catern: e.g. 015 13 0D CR '\r' (carriage ret) 115 77 4D M <-- ctrl-M corresponds to CR, carriage return |
| 14:45 | catern | mind blown |
| 14:46 | technomancy | yeah, control codes are sent just by flipping a bit on regular ascii codes |
| 14:46 | justin_smith | catern: for example, I am sure you already knew Ctrl-D was EOT |
| 14:47 | catern | justin_smith: everything begins to make sense |
| 14:47 | ToxicFrog | justin_smith: to be fair it could plausibly also have been ETX or EM |
| 14:48 | justin_smith | fair enough |
| 14:48 | catern | do ctrl-c or or ctrl-\ fit in this at all? |
| 14:48 | dbasch | catern: back in the day computers only had the ascii charset. My TI99 used the values > 127 for graphics (e.g. horizontal line, vertical line, angles) |
| 14:48 | catern | given that they send signals |
| 14:49 | cbp | ctr-c is etx |
| 14:49 | catern | yes |
| 14:49 | catern | etx doesn't seem very sigint-ish |
| 14:49 | dbasch | catern: that depends on the shell |
| 14:49 | justin_smith | catern: your terminal translates the keycode into a signal to the currently running process |
| 14:49 | cbp | also known as 'break' |
| 14:50 | catern | dbasch: justin_smith: is it the shell or the terminal? |
| 14:50 | ToxicFrog | Yeah, I think it's just ctrl-C for Cancel |
| 14:50 | justin_smith | catern: the terminal - the keycodes work even when you exec (which makes the shell exit) |
| 14:50 | justin_smith | and it works even if the shell is not running when the keycode is sent |
| 14:50 | catern | justin_smith: so wait, emacs understands C-c keybindings by *running a signal handler*? |
| 14:50 | dbasch | catern: the terminal driver |
| 14:51 | justin_smith | the terminal runs the signal handler |
| 14:51 | justin_smith | err |
| 14:51 | justin_smith | n/m |
| 14:51 | justin_smith | yeah, it uses a singal handler I think :) |
| 14:51 | justin_smith | in the console |
| 14:51 | catern | weird |
| 14:51 | catern | it works, though |
| 14:51 | justin_smith | it works :) |
| 14:52 | technomancy | reading about terminals is like reading about mime encoding |
| 14:52 | technomancy | it simply increases your wonderment and awe at the fact that anything ever works |
| 14:53 | bbloom | frickin' terminals... |
| 14:55 | justin_smith | "fucking terminals, how do they work? I don't want to talk to a computer scientist, motherfuckers lying, making me pissed" |
| 14:56 | johnwalker | technomancy: what did core.typed do to you ? :( |
| 14:56 | johnwalker | woops, wrong completion |
| 14:56 | johnwalker | ToxicFrog: what did core.typed do to you ? |
| 14:59 | catern | wait so |
| 14:59 | catern | why do both Ctrl-m and Ctrl-M send CR? |
| 15:00 | ToxicFrog | johnwalker: when I lein typed check, it does this: https://gist.github.com/anonymous/c37a772c1c470b7b1812 |
| 15:00 | bbloom | ,(- (int \A) (int \a)) |
| 15:00 | clojurebot | -32 |
| 15:00 | ToxicFrog | At first I thought this was because clj-http and core.typed wanted different versions of tools.reader, but if I drop the clj-http dependency or force them both to use the same version it still happens. |
| 15:00 | bbloom | ,(- (int \a) (int \A)) ; heh, positive |
| 15:00 | clojurebot | 32 |
| 15:01 | justin_smith | catern: the control bit and the shift bit interact oddly - I forget the details |
| 15:01 | catern | aaaieeeeeeeee |
| 15:01 | justin_smith | catern: there is no such thing as C-m - it becomes C-M |
| 15:01 | catern | AIEEEEEEEEE |
| 15:01 | johnwalker | ToxicFrog: the easiest way to check is to move the core.typed dependency before anything else in your :dependencies |
| 15:01 | bbloom | ,(char 45) |
| 15:01 | clojurebot | \- |
| 15:01 | amalloy | justin_smith: is it perhaps as simple as, when there's a control bit set, everything but the bottom five bits are masked off? |
| 15:01 | bbloom | *shrug* |
| 15:01 | technomancy | dang, catern's been gazing into the abyss again |
| 15:01 | ToxicFrog | catern: historically, ctrl zeroes the two high bits, which includes the bit that shift sets |
| 15:02 | justin_smith | amalloy: hrm - I dunno, that sounds plausible? |
| 15:02 | johnwalker | whether there's some sort of dependencies collision. i don't have a clue why thats happening though |
| 15:02 | amalloy | sounds like basically what ToxicFrog is saying, and i imagine he knows better than i do |
| 15:02 | ToxicFrog | johnwalker: it already is. |
| 15:02 | ToxicFrog | johnwalker: and lein deps :tree is clean. |
| 15:02 | catern | technomancy: i've learned things mere mortals are not meant to know, delved to abstraction levels that hide ancient horrors, and it has driven me mad |
| 15:02 | ToxicFrog | (since removing clj-http, that is) |
| 15:03 | amalloy | speaking of ascii control codes, a while ago i started typing C-j instead of RET while editing source buffers. it's easier, really - i don't have to reach over with a pinky |
| 15:03 | catern | okay, got any reading on this subject? there's that one really long article about terminals I've seen in passing, but I haven't read it or bookmarked it.. |
| 15:03 | amalloy | plus then in the repl you can use C-j to insert a newline, and RET to send a finished expression |
| 15:03 | technomancy | amalloy: it also should auto-indent out of the box |
| 15:04 | technomancy | whereas you have to configure RET to do newline-and-indent |
| 15:04 | amalloy | technomancy: i'm on such an old version of clojure-mode that RET still does, i think |
| 15:04 | amalloy | maybe i upgraded and then reconfigured it to the old behavior |
| 15:04 | technomancy | amalloy: yeah, someone complained about that (rightly, I think) and now it works the same as everyone else |
| 15:04 | amalloy | yeah, i agree it was right to make that change |
| 15:04 | technomancy | I haven't really got in the habit of preferring C-j, maybe one of these days |
| 15:05 | technomancy | I only got using C-i because I was able to remove the TAB keycap from my ergodox |
| 15:06 | ToxicFrog | johnwalker: yeah, that's the thing, I was thinking "ok, dependencies collision, I'll just remove deps until it goes away and then figure out how to fix things", but I pared it down to just clojure and core.typed and it still happened. But I know that core.typed 0.2.68 and clojure 1.6.0 are compatible because I'm using them in another project without crashing. |
| 15:13 | ToxicFrog | johnwalker: blew away ./target and it started working. I guess it wasn't rebuilding something it should have been? |
| 15:14 | johnwalker | ToxicFrog: wow that is bizarre |
| 15:14 | amalloy | AOT compilation. not even once |
| 15:14 | ToxicFrog | I'm not even using AOT for anything but uberjar. |
| 15:15 | johnwalker | i'm glad you fixed the issue though |
| 15:17 | ToxicFrog | Now, my types are all completely hosed after a year of updates without bothering to typecheck anything, but I know how to fix that~ |
| 15:19 | johnwalker | grep -v ann ? |
| 15:25 | ToxicFrog | Ok, new core.typed question! |
| 15:26 | ToxicFrog | I have a function that's basically (defn register-foo! [& xs] (def foo (into foo xs))) |
| 15:26 | ToxicFrog | I gave it signature [Any * -> Nothing] |
| 15:27 | ToxicFrog | But apparently it actually has signature [Any * -> (Var (Vec Any) (Vec Any))] |
| 15:27 | ToxicFrog | Which kind of makes sense if I read (Var old-type new-type) as being the type of def |
| 15:27 | ToxicFrog | Except Var doesn't exist in core.typed, so I can't use it as part of the signature! |
| 15:31 | amalloy | justin_smith: i just saw your comments on http://stackoverflow.com/questions/25793668/why-is-my-clojure-code-running-so-slowly. it's funny, i didn't actually intend for the powers-of-two sequence to be especially inefficient as part of the problem; i didn't really imagine anyone realizing a finite-but-too-large piece of it |
| 15:31 | justin_smith | heh, here i thought it was an excellent design choice in constructing the puzzle :) |
| 15:31 | ToxicFrog | Hmm, ok, it actually wants either (Var1 T) or (Var2 Tw Tr) even though the error message reports it on Var |
| 15:32 | amalloy | sometimes i did create intentionally-large inputs so that you'd have to think about performance, but most of the time i just wanted any correct solution to work |
| 15:33 | amalloy | it's an interesting problem. looking back at it now i'm not even sure if the solution i wrote years ago is actually efficient or not: https://www.refheap.com/90119 |
| 15:34 | amalloy | it seems inefficient because it goes over every seq but the first multiple times, but...can you do better? i don't know that you can |
| 15:37 | justin_smith | amalloy: https://www.refheap.com/90120 mine, does a bunch of sorting, so is likely slower |
| 15:37 | amalloy | certainly my in-lists? is a bad reimplementation of every? |
| 15:37 | ToxicFrog | Seriously tempted to just :refer :all when I use core.typed now, remembering which things need t/ and which don't is a pain |
| 15:38 | amalloy | justin_smith: well, there are certainly inputs for which yours is faster |
| 15:39 | amalloy | well, maybe not. i dunno. performance is hard |
| 15:39 | justin_smith | benching them now |
| 15:40 | justin_smith | use criterium, it's a library, it's a space heater, it solves random clojure trivia |
| 15:43 | amalloy | justin_smith: i was going to suggest using test.check to generate evil input sequences, but...since it just has to be N sorted collections, there's really nothing exciting it could do |
| 15:45 | justin_smith | as long as the solution is smart enough not to be over eager in reading any inputs |
| 15:45 | justin_smith | and that final test is good on that count |
| 15:46 | justin_smith | https://www.refheap.com/90122 looks like mine was significantly faster (> ms µs ns) |
| 15:47 | justin_smith | I dunno - is it worth benchmarking again predefining the functions? |
| 15:47 | justin_smith | may as well |
| 15:48 | amalloy | justin_smith: don't predefine them, just let them outside: (letfn [...] (bench ...)) |
| 15:48 | amalloy | but no, i don't think it matters at all |
| 15:52 | amalloy | justin_smith: you can improve yours quite a bit, actually, by not sorting and by possibly advancing multiple inputs at once: https://www.refheap.com/0142f12d90d7cef1ac56a0222 |
| 15:53 | dbasch | justin_smith: here's mine fwiw https://www.refheap.com/90124 |
| 15:54 | dbasch | which has obvious improvements |
| 15:54 | amalloy | dbasch: ah, using max is cute, although you can use drop-while instead of next, as in my recent suggestion |
| 15:54 | dorkmafia | how do you create a new instance of a java class from clojure? (ClassName. (arg1) (arg2)) ? |
| 15:54 | dbasch | (I mean can be improved obviously) |
| 15:54 | amalloy | and, just for style points: (let [[mi ma] (apply (juxt min max) ...)] ...) |
| 15:54 | justin_smith | dbasch: interesting |
| 15:54 | dbasch | amalloy: that's what I meant, I look at it now and I could have done it less redundantly |
| 15:55 | tadni_ | So, I'm glad to see that "Clojure From The Ground Up" should be more or less done by Janurary. |
| 15:55 | dbasch | juxt wasn't on my radar at that point |
| 15:55 | amalloy | yeah, (apply (juxt min max) ...) is a trick that still confuses me |
| 15:55 | amalloy | like, i know it works, but my head hurts if i think it through |
| 15:57 | amalloy | i love that these 4clojure problems are still interesting years later, knowing much more about the language |
| 15:57 | justin_smith | yeah, it's pretty cool |
| 15:59 | justin_smith | amalloy: dbasch: I wouldn't have guessed so, but mine is still fastest - though dbasch's version is close https://www.refheap.com/90125 |
| 16:00 | amalloy | justin_smith: it'll depend on the inputs for sure |
| 16:00 | justin_smith | yeah, just using the "tricky" input |
| 16:00 | justin_smith | dbash's would excell with a longer input list |
| 16:00 | amalloy | and either yours or dbasch's would be improved by using drop-while instead of rest |
| 16:00 | justin_smith | true that |
| 16:02 | Bronsa | bbloom: re: hours ago -- no I haven't :) |
| 16:02 | Bronsa | also I just learned that src/foo/bar/baz/ is the same as src/foo.bar.baz for the jvm. I'm kinda tempted to mkdir clojure.tools.analyzer |
| 16:02 | bbloom | Bronsa: heh, just for less work when cd-ing? |
| 16:02 | justin_smith | oh, wow, that's a weird thing |
| 16:03 | Bronsa | bbloom: I have to tab like 6 times to find the first clj file on my tools.* libraries |
| 16:03 | technomancy | I wonder if that's imlementation-specific |
| 16:03 | bbloom | Bronsa: i was super excited when github released the deep-jump links thingt |
| 16:04 | Bronsa | bbloom: me too! |
| 16:04 | technomancy | I remember reading some crazy thing about how dashes in class names are actually supported by openjdk, just not the JVM spec |
| 16:04 | Bronsa | bbloom: my actual comment on #clojure-offtopic "the first github UI change I approve" |
| 16:04 | joobus | how do I call Integer/parseInt from my code? I can call from the repl, but in my code I get a compile error. |
| 16:04 | justin_smith | bbloom: Bronsa: maybe we need deep-jump-find-file |
| 16:04 | Bronsa | technomancy: dunno, I actually saw this on the openjdk source tree |
| 16:05 | amalloy | justin_smith: ido-mode has a setting for that somewhere |
| 16:05 | technomancy | Bronsa: the five users of Clojure on IBM's JDK will yell at you |
| 16:05 | justin_smith | joobus: are you using it as if it were a first class function? it isn't one |
| 16:06 | joobus | justin_smith: I guess I am. (map Integer/parseInt blah) |
| 16:06 | justin_smith | #(Integer/parseInt %) is one |
| 16:06 | joobus | ok |
| 16:06 | justin_smith | joobus: this is all because clojure functions are objects, not methods on some object |
| 16:06 | joobus | I guess that makes sense. i searched and found parseInt is a static method of java.lang.Integer |
| 16:07 | joobus | just didn't know how to handle that |
| 16:07 | joobus | thanks justin |
| 16:07 | technomancy | I don't really get why Clojure doesn't auto-memfn or its static equivalent |
| 16:07 | justin_smith | yeah, the idea is that an arg to a clojure function can be an object or primitive, but it can't be a method, they are not first class |
| 16:08 | technomancy | are there ambiguous contexts in which it can't be determined? |
| 16:08 | justin_smith | technomancy: it would be another bit of magic, I support being skeptical of magic |
| 16:09 | Bronsa | technomancy: that would almost always require runtime reflection |
| 16:09 | technomancy | justin_smith: I don't see how it's magic. how else would you interpret (map .toString objs)? |
| 16:09 | Bronsa | technomancy: compare Object foo(Object); Object foo(Object, Object); |
| 16:10 | Bronsa | how could you statically determine which one you're using when compiling (map Class/foo ..) ? |
| 16:10 | bbloom | (doc memfn) |
| 16:10 | clojurebot | "([name & args]); Expands into code that creates a fn that expects to be passed an object and any args and calls the named instance method on the object passing the args. Use when you want to treat a Java method as a first-class fn. name may be type-hinted with the method receiver's type in order to avoid reflective calls." |
| 16:10 | bbloom | note that you have to provide type hints |
| 16:10 | technomancy | Bronsa: I don't mind runtime reflection |
| 16:11 | bbloom | technomancy: the problem isn't that it requires reflection, it's that the reflection doesn't occur until later |
| 16:11 | Bronsa | technomancy: I do |
| 16:11 | bbloom | i guess that the compiler would warn on reflection when auto-memfn-ing |
| 16:11 | Bronsa | bbloom: I don't understand the distinction you're trying to make |
| 16:12 | technomancy | there's lots of stuff like that in clojure already; it seems like the line is drawn at a somewhat arbitrary spot |
| 16:12 | bbloom | Bronsa: sorry, i didn't fully think that thougth out. i guess that's also true of fn too |
| 16:12 | bbloom | ignore me :-P |
| 16:13 | Bronsa | technomancy: for instance-methods it wouldn't even be a matter of only "it would require reflection" -- you wouldn't even know what arities are available |
| 16:14 | tadni_ | justin_smith: Yeah, Clojure from the Ground up -- the more I looked into it, appears to be more an introduction to the lang more-so a general compsci introduction. |
| 16:14 | technomancy | yet memfn exists |
| 16:14 | Bronsa | what would it do? turn .foo into (fn ([x] (.foo x)) ([x y] (. x y)) ..)? |
| 16:14 | Bronsa | technomancy: you have to provide the argc to memfn, that's the point |
| 16:14 | joobus | w00t! I've solved 4 project euler problems in clojure. I'm feeling slightly less noobish... |
| 16:14 | amalloy | technomancy: well, memfn is for a specific, single arity |
| 16:15 | AeroNotix | I'm seeing a http-kit/get call being blocked (where it should always return a promise). Any ideas why that would be? |
| 16:15 | amalloy | you can expand into a million different arities, as Bronsa points out, but it's not super-clean |
| 16:15 | technomancy | Bronsa: you actually don't? |
| 16:16 | justin_smith | tadni_: did you mean disillusioned? or does it disenfranchise you from some right you would otherwise have? |
| 16:16 | joobus | justin_smith: lol |
| 16:16 | justin_smith | "this tutorial is opressing me" |
| 16:16 | johnny_mck | Greetings! I haz questions if anyone cares to answer some? (mostly about programming in a functional style...) |
| 16:16 | dorkmafia | is this the correct syntax for creating a java class from clojure and passing constructor args (ClassName. (arg1) (arg2)) ? |
| 16:16 | amalloy | technomancy: yes you do. (memfn add) only accepts exactly one argument; (memfn add x) accepts exactly two... |
| 16:17 | tadni_ | justin_smith: Well, if I were to follow the thinking in the "who is this guide for" and I was non-cis, or non-white and was using another guide ... then maybe. :^P |
| 16:17 | technomancy | huh... I've never used the second arity of memfn |
| 16:17 | tadni_ | I'm saying, it's not really a general compsci text as much as a general introduction to clojure. |
| 16:17 | Bronsa | technomancy: you've only used on no-arg methods then :) |
| 16:17 | justin_smith | tadni_: true |
| 16:18 | justin_smith | johnny_mck: we grant permission to ask questions freely |
| 16:18 | joobus | johnny_mck: you should just ask and see if someone responds. that's what the pro noobs like myself do. |
| 16:18 | amalloy | justin_smith: unless it's about the new iphone |
| 16:18 | justin_smith | heh |
| 16:18 | justin_smith | yeah, maybe I should have qualified that |
| 16:24 | TEttinger | dorkmafia: ##(java.util.HashMap. 64) |
| 16:24 | lazybot | ⇒ #<HashMap {}> |
| 16:24 | TEttinger | dorkmafia: ##(java.util.HashMap. (64)) |
| 16:24 | lazybot | java.lang.ClassCastException: java.lang.Long cannot be cast to clojure.lang.IFn |
| 16:25 | TEttinger | 64 is a constructor arg to that java class that is the initial capacity, IIRC |
| 16:26 | justin_smith | there's that javascript compiler that removes lines of code until everything compiles, we should do something similar with clojure, and removing parens |
| 16:27 | TEttinger | I think there could be some ambiguity. |
| 16:27 | TEttinger | ,(map identity [+ 1 2 3]) |
| 16:27 | clojurebot | (#<core$_PLUS_ clojure.core$_PLUS_@15773de> 1 2 3) |
| 16:27 | AeroNotix | I'm seeing a http-kit/get call being blocked (where it should always return a promise). Any ideas why that would be? |
| 16:27 | TEttinger | ,(map identity [(+ 1 2 3)]) |
| 16:27 | clojurebot | (6) |
| 16:28 | amalloy | justin_smith: the readme for wtfjs is sublime |
| 16:29 | justin_smith | indeed |
| 16:50 | defn | dnolen_: Whaddya know about probabilistic programming? I want to dig in and am curious if you have suggestions on papers, resources, etc. |
| 16:50 | dnolen_ | defn: not much I just surveyed some literature at one point, Church is a good jumping off point |
| 16:51 | dnolen_ | defn: http://projects.csail.mit.edu/church/wiki/Church |
| 16:51 | defn | dnolen_: Some fascinating stuff. |
| 16:52 | defn | Yeah I found the church lang. So many recent papers and research topics involved that I'm feeling overwhelmed. |
| 16:52 | defn | Probmods.org was a good intro, but I need to see more in practice. Anyway, thanks again. |
| 16:53 | defn | Oh, and mcmc has been done in clojure. If you're interested dnolen_ |
| 16:53 | defn | https://github.com/farr/mcmc-clojure |
| 16:53 | dnolen_ | defn: interesting though old and not maintained |
| 16:54 | defn | Yeah :/. Looks like I need to take a page out of the dnolen book and write clojure.core.prob |
| 16:57 | bbloom | defn: go for it! |
| 16:58 | jdkealy | Hello, I have been trying to use the AMI startup script for Dynamo DB and AWS. I have gotten the startup script to launch a new instance, but it stops and restarts itself with the following error: ./startup.sh: line 26: kill: (1768) - No such process, /dev/fd/11: line 1: /sbin/plymouthd: No such file or directory ... has anyone here encountered anything like this before ? |
| 16:58 | arrdem | defn: there's an implementation of distributions kicking around somewhere from contrib that may be interesting material as well although that's more probability modeling than a probabalistic structure |
| 16:58 | defn | jdkealy: I believe there is a #datomic channel |
| 16:58 | jdkealy | sorry about that! I thought i was in #datomic :/ |
| 16:58 | defn | Np |
| 16:59 | defn | arrdem: I'll have a look. I think I know the one you're referring to. Been a long while since I went through contrib |
| 16:59 | defn | Thanks! |
| 17:00 | arrdem | defn: there's an old implementation of a distribution monad. It doesn't make a whole lot of sense as a monad, but the distribution structure has served me well in a tabletop game project. |
| 17:08 | dbasch | arrdem: wow, it hasn't been touched for 5 years https://github.com/richhickey/clojure-contrib/tree/master/src/main/clojure/clojure/contrib/probabilities |
| 17:08 | arrdem | dbasch: yep |
| 17:08 | arrdem | dbasch: oh do you still have that clojure vs clojurescript link? |
| 17:09 | dbasch | arrdem: this? https://github.com/clojure/clojurescript/wiki/Differences-from-Clojure |
| 17:10 | arrdem | dbasch: I found that... I seem to recall you mentioning some post about expressions that didn't behave the same. |
| 17:13 | dbasch | trying to find it |
| 17:14 | sdegutis | Quick, what's a good name for an app that does your chores for you? |
| 17:14 | andyf_ | sdegutis: littleBrother ? |
| 17:15 | dbasch | sdegutis: siri :P |
| 17:15 | sdegutis | Something that won't invoke trademark infringement? :P |
| 17:15 | justin_smith | sdegutis: apprentice |
| 17:15 | justin_smith | it even has app in the name |
| 17:17 | sdegutis | Thanks everyone! |
| 17:17 | noonian | man, i'm going to be pondering that all day now |
| 17:21 | sdegutis | Oh maybe old maid? Or steward? |
| 17:21 | sdegutis | s/old// |
| 17:23 | noonian | i was thinking robo-maid or something |
| 17:23 | noonian | or no-chore no-more-chore |
| 17:23 | sdegutis | :D |
| 17:23 | sdegutis | Certainly not Golem. |
| 17:24 | technomancy | yeah, you wouldn't want folks thinking it was written in google go |
| 17:24 | sdegutis | Or that it's from LotR. |
| 17:24 | AeroNotix | I'm seeing a http-kit/get call being blocked (where it should always return a promise). Any ideas why that would be? |
| 17:24 | justin_smith | GoLem: a generator of high concept sci fi, written in google go |
| 17:25 | sdegutis | technomancy: I wrote an 80-line script in Go the other day, which downloaded some .tar.gz archives from the net, extracted them in-memory, and output contents of files matching a pattern. |
| 17:25 | cbp | sounds like a clojure 5 liner |
| 17:25 | sdegutis | technomancy: A few hours later, I replaced it with a 4-line Bash script. |
| 17:25 | technomancy | nice |
| 17:25 | sdegutis | I have never found a good use for Go that I haven't rewritten in something better. |
| 17:26 | ieure | Go is great if you enjoy writing "if (err != nil)" every other line. |
| 17:26 | sdegutis | :) |
| 17:27 | ieure | As someone who needs to write extremely correct software, Go sends me screaming. |
| 17:27 | technomancy | hey, when I was in school, you didn't have to get 100% on every test |
| 17:27 | technomancy | even if you got just like 90% it was no big deal |
| 17:28 | mdrogalis | Gonna put that on my resume. "I write sorta good code. Good enough anyways" |
| 17:28 | ieure | Hah. |
| 17:28 | mdrogalis | ieure: What industry do you work in? |
| 17:28 | sdegutis | <3 |
| 17:28 | ieure | mdrogalis, Banking. |
| 17:28 | sdegutis | I was gonna guess "financial" |
| 17:28 | mdrogalis | Unit testing on your own bank account. Don't mess up too much, now. |
| 17:28 | AeroNotix | ieure: so what language do you use then? |
| 17:29 | justin_smith | mdrogalis: nah, you just add a test fixture that resets the balance :P |
| 17:29 | ieure | AeroNotix, Depends. We're a JVM shop, but write Java, Scala, Clojure, and JRuby. |
| 17:29 | sdegutis | <3 Java |
| 17:29 | ieure | Depending on what the thing is. |
| 17:29 | AeroNotix | ieure: and you think you can write more correct programs in Java than in Go? |
| 17:29 | sdegutis | Such nice. So language. |
| 17:29 | TEttinger | JRuby seems like the thing to not use for correctness |
| 17:29 | AeroNotix | sdegutis: are you kidding? |
| 17:30 | sdegutis | Who doesn't love Java? |
| 17:30 | sdegutis | (Besides hipsters.) |
| 17:30 | mdrogalis | justin_smith: "Gave myself some padding by adding a few zeros this week." |
| 17:30 | ieure | AeroNotix, I believe it is easier to write correct programs in Java than Go. |
| 17:30 | technomancy | Java: at least it has exceptions |
| 17:30 | AeroNotix | ieure: could it be that you're just more familiar with it? |
| 17:30 | ieure | AeroNotix, No. |
| 17:30 | AeroNotix | oh ok. Case closed. |
| 17:30 | mdrogalis | Hahah. |
| 17:31 | sdegutis | At the end of the day, there's nothing really wrong with Java, it's perfectly suitable for writing any kind of serious app in. Clojure is just the icing on the cake. |
| 17:31 | TEttinger | sdegutis, designed for average coders, by average coders? |
| 17:31 | TEttinger | Oak, anyway |
| 17:31 | AeroNotix | sdegutis: that's not a very nuanced opinion. |
| 17:32 | arrdem | TEttinger: read the CVs of the Java language committee and lets hear you say that again |
| 17:32 | TEttinger | I was kidding |
| 17:32 | sdegutis | AeroNotix: uhh |
| 17:32 | sdegutis | TEttinger: uhh |
| 17:32 | mdrogalis | Not sure how you can appreciate Clojure without realizing what's wrong with Java. D: |
| 17:32 | TEttinger | I know they got some very experienced devs on that team |
| 17:33 | TEttinger | and it is interesting how Java got by with less serious design flaws at an early stage than most other large languages |
| 17:33 | TimMc | Pity about the type system, though. |
| 17:33 | TEttinger | they had to do a big rewrite for generics, and they still aren't great |
| 17:33 | sdegutis | mdrogalis: There are quirks in every language, and that's kind of why I have a job actually, because writing software is kind of hard. |
| 17:33 | ieure | Java Generics are really terrible. |
| 17:33 | ieure | Is typed Clojure usable yet? |
| 17:34 | ieure | It seems very promising. |
| 17:34 | sdegutis | I could try and write Haskell all day but the tools I use now work fine. |
| 17:34 | TEttinger | I have wondered the same, ieure. it seems to be, though I haven't tried it. |
| 17:35 | ieure | I've been appreciating static typechecking more since I started writing systems that have to correctly deal with millions of dollars of other peoples' money. |
| 17:35 | TEttinger | the main thing I use clojure for right now is one-liners of very dense code. |
| 17:35 | TEttinger | ##(clojure.string/join" "(repeatedly 2000(fn [](apply str(concat[(rand-nth ["rh""s""z""t""k""ch""n""th""m""p""b""l""g""phth"])](take(+ 2(* 2(rand-int 2)))(interleave(repeatedly #(rand-nth ["a""a""o""e""i""o""au""oi""ou""eo"]))(repeatedly #(rand-nth ["s""p""t""ch""n""m""b""g""st""rst""rt""sp""rk""f""x""sh""ng"]))))[(rand-nth ["os""is""us""um""eum""ium""iam""us""um""es""anes""eros""or""ophon""on""otron"])]))))) |
| 17:35 | lazybot | ⇒ "rhauchaumor peobus rhamor pourkoistum teongeochium phthongoushor theonarstis zeofor phthaungeorstotron girtoirtanes pospeoshiam chepum toumon loitocheros zixophon lamon sabousotron gespium toxortis soirtenor laspum chomum paurteopis zeofepus moigum thortousheum togo... https://www.refheap.com/90131 |
| 17:35 | justin_smith | ieure: there is also prismatic/schema |
| 17:35 | sdegutis | In fact, I'm betting on the fact that people are overly picky about languages, and I'm embedding 4 different scripting languages into my upcoming commercial app. |
| 17:36 | dbasch | TEttinger: future you would like to have a word with present you |
| 17:36 | sdegutis | They can choose between Ruby, Java, Python, or Lua. |
| 17:36 | ieure | justin_smith, Looks interesting. |
| 17:36 | arrdem | dbasch: lol |
| 17:36 | sdegutis | er, JavaScript |
| 17:36 | TEttinger | dbasch: the reduced need for spaces helps with these one-liners fitting in 400 or so characters |
| 17:37 | amalloy | and imagine the savings on commas |
| 17:38 | dbasch | amalloy: I like my machine code to have more ones than zeros because it saves ink when printing them out in binary |
| 17:40 | TEttinger | I'm currently almost exclusively writing C# for a rapidly-expanding-in-code-size renderer for voxel models. I'm hoping to use the rendered stuff from clojure using play-clj when I get closer to done. |
| 17:43 | dbasch | arrdem: I found this in my browser history, it only goes back 90 days https://gist.github.com/alandipert/2346460 |
| 17:44 | arrdem | dbasch: thanks for looking |
| 17:51 | sdegutis | lol, Proletarian |
| 17:59 | TEttinger | ,(filter #".*foo.*" ["foobar" "goobar" "foobaz"]) |
| 17:59 | clojurebot | #<ClassCastException java.lang.ClassCastException: java.util.regex.Pattern cannot be cast to clojure.lang.IFn> |
| 17:59 | TEttinger | hm, I guess it doesn't work in vanilla clojure without further black magick |
| 18:00 | llasram | TEttinger: yeah -- in JVM Clojure there's no way to turn existing classes (like regular expressions) into IFns |
| 18:00 | technomancy | you could define a clojure.lang.Regex |
| 18:01 | TEttinger | you could add a reader literal to create your own REFn |
| 18:01 | technomancy | since no one has ever used #"" regexes for interop ever |
| 18:01 | TEttinger | it could also be a subclass of the java regexp |
| 18:02 | technomancy | llasram: no seriously |
| 18:02 | technomancy | I would be mildly surprised if anyone on this channel has ever done it |
| 18:02 | Bronsa | TEttinger except Pattern is final :) |
| 18:02 | TEttinger | wat |
| 18:02 | Bronsa | http://docs.oracle.com/javase/7/docs/api/java/util/regex/Pattern.html |
| 18:03 | TEttinger | then you could have another class that has a Pattern as a member and itself implements IFn |
| 18:03 | technomancy | TEttinger: I would vote for that =) |
| 18:04 | Bronsa | TEttinger you couldn't use that for interop then |
| 18:04 | noonian | why do you need it to work with just a literal? |
| 18:04 | llasram | If classes aren't explicitly designed to be extensible, best to make them final. Keeps things all neat and tidy. |
| 18:04 | llasram | Prevents the proletariat from getting uppity etc |
| 18:04 | TEttinger | right, but you could get the Pattern out of it once and use that for interop |
| 18:04 | TEttinger | I dunno |
| 18:05 | Bronsa | TEttinger but there'd be no way to always known statically when you're passing a MyPattern instead of a proper Pattern to "unbox" it |
| 18:06 | TEttinger | I guess. the best solution would be to not interop, I suppose |
| 18:06 | Bronsa | you'd need to add instance checks + "unbox" paths everywhere you call a method taking a Pattern |
| 18:06 | Bronsa | which might not be too bad actually |
| 18:06 | technomancy | noonian: filtering on a regex is many orders of magnitude more useful than interopping a regex, so it's unfortunate that the latter is convenient and the former is not |
| 18:09 | Bronsa | I might actually attempt a patch for that one of the next days |
| 18:10 | Bronsa | it might break code that explicitely tests for j.u.regex.Pattern though |
| 18:12 | dorkmafia | http://paste.debian.net/120473/ why does line 17 throw a java.lang.NullPointerException the first time i call it but after that it's fine? |
| 18:14 | noonian | ,(filter (partial re-find #".*foo.*") ["foobar" "goobar" "foobaz"]) |
| 18:14 | clojurebot | ("foobar" "foobaz") |
| 18:14 | noonian | i'm happy enough with that though |
| 18:16 | dbasch | noonian: I'd probably want re-matches behavior rather than re-find |
| 18:18 | noonian | dbasch: it wouldn't matter for filtering though right? both would return a truthy value if there are any matches or nil otherwise if i'm not mistaken |
| 18:18 | dbasch | noonian: it depends on the regexp |
| 18:19 | noonian | dbasch: ah, good call |
| 18:19 | noonian | ,(filter (partial re-matches #".*foo") ["foobarfoobar" "goobar" "foobaz"]) |
| 18:19 | clojurebot | () |
| 18:19 | noonian | (filter (partial re-find #".*foo") ["foobarfoobar" "goobar" "foobaz"]) |
| 18:19 | noonian | ,(filter (partial re-find #".*foo") ["foobarfoobar" "goobar" "foobaz"]) |
| 18:19 | clojurebot | ("foobarfoobar" "foobaz") |
| 18:22 | dorkmafia | is there something wrong I'm doing with the chaining of functions? |
| 18:24 | dbasch | dorkmafia: what parameters are you calling that with? What's the exception? |
| 18:26 | dorkmafia | dbasch: http://paste.debian.net/120474/ |
| 18:29 | dbasch | I don't see any calls there, just definitions |
| 18:30 | dorkmafia | it's in the handler |
| 18:32 | noonian | so where do you create the handler? it looks like all those functions get it passed in |
| 18:32 | dorkmafia | http://paste.debian.net/120475/ |
| 18:33 | dorkmafia | hmm |
| 18:33 | dorkmafia | maybe it's passing nil as the from-user? |
| 18:34 | noonian | yeah maybe, you might get a message where the body isn't blank but there is no :from-name |
| 18:35 | noonian | i'd definitely print the message for now so you know what it's getting |
| 18:38 | dorkmafia | hmm |
| 18:38 | dorkmafia | k |
| 18:41 | dorkmafia | nope the from-user is correct |
| 18:42 | dorkmafia | it doesn't print out twice which is strange |
| 18:55 | dorkmafia | noonian: i think it has to do with the roster not being defined |
| 18:57 | dorkmafia | (defn roster [conn] (when conn (.getRoster conn) )) am i using when correctly here? |
| 18:59 | dbasch | dorkmafia: it depends on what you want. If conn is falsey that will evaluate to nil. |
| 19:02 | dorkmafia | hm i dunno |
| 19:03 | noonian | dorkmafia: i'd change it to an if for now and print something if the conn is nil |
| 19:03 | noonian | its nice to have more information during dev/debugging |
| 19:06 | dorkmafia | (.getEntry (roster conn) uname) ) |
| 19:06 | dorkmafia | could it be due to taht? |
| 19:06 | dorkmafia | i'm going to try and use a local variable for the roster there |
| 19:07 | technomancy | IMO you should check for nils as early as possible and error out |
| 19:07 | technomancy | letting them leak through any old place in your program makes for bugs that are tedious to track down |
| 19:08 | dorkmafia | all of the inputs are fine |
| 19:13 | dorkmafia | is it possible I need to set java types for the return types of some of these methods? |
| 19:14 | amalloy | dorkmafia: no |
| 19:15 | tuft | technomancy: they can work like a poor man's maybe monad, which is nice |
| 19:16 | technomancy | monads without a type checker... poor man indeed =) |
| 19:23 | dbasch | dorkmafia: I still don't know how you're starting the whole thing. I assume you call starter-bot, but what is smack/start-bot? |
| 19:23 | amalloy | sounds like bot abuse to me |
| 19:24 | dbasch | amalloy: you just reminded me of a Futurama episode |
| 19:26 | dorkmafia | dbasch: there is another class i missed lol sorry |
| 19:27 | dorkmafia | http://paste.debian.net/120478/ |
| 19:36 | dbasch | dorkmafia: that code is pretty convoluted, where does it come from? |
| 19:36 | dorkmafia | yah that's why i'm trying to make it better it's from xmpp-clj |
| 19:36 | dorkmafia | on github |
| 19:46 | dorkmafia | dbasch: should i just start over? lol |
| 19:48 | adereth | I wish I had done the Heroku Clojure walkthrough sooner. That was really easy. |
| 19:48 | adereth | Made a toy: http://templar-clj.herokuapp.com/ |
| 19:48 | adereth | http://templar-clj.herokuapp.com/?url=http%3A%2F%2Ftemplar-clj.herokuapp.com%2F |
| 19:55 | justin_smith | adereth: is it giving a templated version of the page provided? |
| 19:55 | locks | cute |
| 19:56 | justin_smith | An error occurred in the application and your page could not be served. Please try again in a few moments. If you are the application owner, check your logs for details. |
| 19:58 | adereth | Yes |
| 19:58 | adereth | In Enlive, Hiccup, and Hickory style |
| 19:58 | adereth | Oh noes. Still? |
| 21:12 | yedi | jsut to confirm, clojure lists have 0(1) prepending and appending correct? |
| 21:12 | bbloom | yedi: prepending only |
| 21:13 | yedi | oh... that's unfortunate. is there a data structure that also keeps a pointer to the end of the lis tas well |
| 21:13 | bbloom | yedi: concat constructs a lazy sequence in O(1) time |
| 21:13 | bbloom | yedi: vectors have fast push/pop from the tail and can be converted in to a seq in O(1) time |
| 21:14 | bbloom | if you genuinely need push/pop from both sides, there are contrib libs for finger trees and rrb vectors |
| 21:14 | justin_smith | yedi: there is a lib with a persistent deque (which does fast prepand and append) |
| 21:14 | bbloom | but it's pretty rare that you actually need that |
| 21:14 | yedi | justin_smith: ah i think that was the library you linked me to before |
| 21:14 | justin_smith | yedi: probably |
| 21:14 | yedi | bbloom: well i'm creating a queue that needs to be able to append on one side and pop from the other |
| 21:15 | justin_smith | but you wanted a queue actually, right? and there is a built in Persistentqueue if you want fast front insertion and fast tail removal |
| 21:15 | bbloom | ,clojure.lang.PersistentQueue/EMPTY |
| 21:15 | clojurebot | #<PersistentQueue clojure.lang.PersistentQueue@1> |
| 21:15 | yedi | this is on clojurescript btw |
| 21:15 | TimMc | "by the way" |
| 21:15 | yedi | >_< |
| 21:15 | bbloom | yedi: i think cljs has persistent queue also... |
| 21:15 | yedi | sweet, ill go check |
| 21:17 | TimMc | I'd be curious to hear what you find. |
| 21:17 | bbloom | it's there |
| 21:18 | yedi | yep |
| 21:48 | zeebrah | adereth: is there a link to the walk through? |
| 21:52 | truebuddi | any tips or good reading links about how an experienced OO dev can think of modeling data in a functional world? |
| 21:53 | rubygeek | maybe this? https://leanpub.com/fp-oo |
| 21:53 | matthoffman | truebuddi: I quite liked that one |
| 21:54 | justin_smith | truebuddi: many of Rich Hickey's video talks are about contrasting Clojure style functional programming to Java style OO |
| 21:55 | truebuddi | I did a lot of reading .. practiced almost everything from iloveponies.github.com; watched quite a few talks from rich hickey .. recently started looking at joy of clojure .. i get the language but am having trouble getting something real done in clojure ... |
| 21:56 | justin_smith | truebuddi: what real things have you tried to do? |
| 21:57 | truebuddi | justin_smith: well i wanted to build a small web app .. for fun kind ..but have some starting trouble ... |
| 21:58 | justin_smith | what were your roadblocks? |
| 21:58 | matthoffman | it can be tough to stare at a blank page and think of how to model the world functionally when you're used to OO; i found it easier to try adding a feature to an existing project. |
| 21:58 | matthoffman | 'cause then i had to walk through existing code and figure out how they modelled things |
| 21:59 | jasonjck_ | following SICP in clojure is a good way to learn |
| 22:00 | jasonjckn | i think there's a whole clojure book on webapps |
| 22:00 | jasonjckn | it's not joy of clojure |
| 22:00 | justin_smith | truebuddi: anyway, if you have specific questions, feel free, all of my largest clojure projects have been either web apps or my work on a web app framework, and I know a number of other folks here do clojure web apps too |
| 22:00 | truebuddi | @justin ... for eg, i want to build a "trip journal" where you have a "group of people". each person can comment on a trip...trip cannot be deleted by anyone else other than that person who created it ... things like that ... |
| 22:01 | bja | where has prismatic/schema been all of my life? |
| 22:02 | justin_smith | truebuddi: on a data modeling level, a database is by definition not functional (unless you use something like datomic that has an immutible history, but frankly I think that is often overkill) - functional programming can use persistence and mutation judiciously, just as OO can use immutible data or static methods |
| 22:02 | justin_smith | bja: I know, right? |
| 22:03 | justin_smith | truebuddi: the key, for me, is to have a clear mental model of where and why the mutation / persistence occur (they often go hand in hand), and how they integrate with the purely functional ecosystem that is the rest of my code |
| 22:03 | bja | built a coercer to handle configs pulled in via environ/zookeeper |
| 22:03 | bja | my life is now simple |
| 22:04 | justin_smith | bja: as long as you don't expect to be able to use watches, or treat it like a db, zookeeper is awesome |
| 22:05 | truebuddi | justin_smith: initially i am not even worried about persistence ... for the most part I am only concerned about how you would you model something? say I want anemic object Person .. with a name, profile picture, some description ... you make the person a map or a record or what...thats the kind of stuff that isn't clear to me yet |
| 22:05 | justin_smith | truebuddi: to be more concrete, I will usually associate a request with gathering db data coming in, and then writing db data on the way out again |
| 22:06 | justin_smith | truebuddi: use a map until maps are a bottleneck |
| 22:06 | justin_smith | truebuddi: use assertions or prismatic/schema to make sure the data has the shape you expect |
| 22:06 | bja | justin_smith: what's wrong with using watches? |
| 22:06 | justin_smith | bja: they are flawed inside zookeeper |
| 22:07 | justin_smith | bja: oh, I mean avout - the clj zookeeper binding that acts like an atom |
| 22:07 | justin_smith | it makes zookeeper extremely easy to use, but the watches are not worth it (and don't use it for large data sizes) |
| 22:07 | bja | I've been using watches for settings updates |
| 22:08 | bja | but have not been using about |
| 22:08 | justin_smith | bja: I specifically meant watches on avout/atom objects |
| 22:08 | bja | ah, ok |
| 22:08 | justin_smith | bja: http://avout.io/ check out the example code - they do make it very similar to clojure.core atoms |
| 22:09 | justin_smith | (and refs also, but there is less reason to use those) |
| 22:09 | bja | oh, I saw that on /r/clojure I think |
| 22:10 | justin_smith | but I am sure zookeeper is awesome on its own too (and in some ways simpler when it doesn't try to pretend to be a standard clojure reference type) |
| 22:10 | bja | yeah. We're just using it to distribute settings |
| 22:11 | justin_smith | right, that is what I did too, but being able to look at the settings like atoms was a bonus |
| 22:11 | bja | having a config schema makes it easy to know that a bad settings push won't blow up my production systems |
| 22:14 | justin_smith | truebuddi: another revelation for me was focusing less on creating structures that emulate the real world and more on creating stateless transformations that can be composed to create the process I need |
| 22:15 | justin_smith | truebuddi: if my map needs a new key in it, or the list needs to become a vector, this is a simple change if I wrote my code well - the interesting part isn't getting the data model perfect up front, its being able to quickly iterate the data transformations until I have the program I need |
| 22:17 | truebuddi | justin_smith: so you suggest I start with something basic ... just model as much data as I could with what I know ... maps...lists ... vectors..sets and then refactor later? |
| 22:17 | justin_smith | truebuddi: yeah, that is how clojure programs typically evolve |
| 22:17 | justin_smith | and all the operations on maps are supported on records |
| 22:17 | justin_smith | so if you need something more specific later, you can upgrade easily |
| 22:18 | truebuddi | justin_smith: now that makes me worry next about ownership ... usually in OO you can have a repository which owns a list of people .. so in a fp world who owns say a list of my persons? another structure eventually in a global context? |
| 22:19 | justin_smith | truebuddi: maybe you've seen that Alan Perlis quote? It is better to have 100 functions operate on one data structure than 10 functions on 10 data structures." |
| 22:19 | justin_smith | truebuddi: when you have ubiquitous immutibility, ownership becomes less important - when you need mutation, keep it near the owner, and export something immutible at the earliest practical moment |
| 22:19 | truebuddi | justin_smith: I didn't know it was from Alan Perlis but heard of that quote when doing some reading about Clojure and Rich Hickey quoted it somewhere i guess .. |
| 22:21 | ToxicFrog | How do I express "this function does not return" in a core.typed annotation? |
| 22:22 | justin_smith | truebuddi: so, since you need a mutible storage of user data (assuming that is what "people" are for here), I would make a people ns, keep all implementation details internal to that ns, and clearly delineate the functions comprising the API, which returns immutible people for queries, or takes update maps and manages state based on those updates |
| 22:23 | TimMc | ToxicFrog: Declare it to yield _|_, obviously. :-P |
| 22:23 | truebuddi | justin_smith: so use ns to organize functionality .. hmmm |
| 22:24 | justin_smith | truebuddi: yeah, for me an ns represents some group of related abilities provided to other code |
| 22:24 | TimMc | ToxicFrog: (No, I don't actually know if core.typed supports bottom.) |
| 22:25 | truebuddi | justin_smith: what do you think of https://leanpub.com/fp-oo that was suggested earlier to me .. |
| 22:25 | justin_smith | ⏟⏟ <- a much more shapely bottom, thanks to unicode |
| 22:25 | ToxicFrog | TimMc: it describes "Nothing" as "the bottom type" |
| 22:25 | justin_smith | truebuddi: I have not read it |
| 22:25 | TimMc | justin_smith: Oh, Unicode and its shapely bottoms... |
| 22:26 | truebuddi | justin_smith: been a few years since I did web dev ... anyway do you have a suggestion for a small but practical web app that I can study preferably one in clojure/cljs |
| 22:26 | TimMc | ToxicFrog: But then the docs say "Nothing is the bottom type that inhabits no types except itself." which I think disagrees with (say) the Haskell notion of bottom. |
| 22:26 | TimMc | _|_ is supposed to inhabit *all* types, right? |
| 22:27 | truebuddi | justin_smith: I played around with compojure, http-kit .. so i am not too concerned about the technology but am more interested in how things like sessions, cookies, web sockets are mixed with business end of things in clojure |
| 22:28 | justin_smith | truebuddi: https://github.com/prismofeverything/schmetterling is by a friend of mine (I contributed extensively to the design, but less to the actual code) - sadly I can't think of a really good web service in clojure for reading off the top of my head (all my good ones are closed source client work) |
| 22:28 | justin_smith | TimMc: stupid sexy unicode |
| 22:31 | TimMc | justin_smith: http://www.boardsandrec.com/showthread.php?t=82114 |
| 22:31 | TimMc | "unicode butt" is now in my google search history, forever |
| 22:32 | justin_smith | lol |
| 22:34 | justin_smith | and all along, I was looking for: ⊥ "UP TACK" |
| 22:34 | justin_smith | why the hell is it called up tack? who knows |
| 22:35 | TimMc | *files, also |
| 22:35 | teslanick | Looks like a tack sitting on its head, pointing up? |
| 22:35 | justin_smith | right, but I have never heard it called that name in a mathematical context, though it is categorized as a mathematical symbol |
| 22:36 | justin_smith | TIL http://en.wikipedia.org/wiki/Up_tack |
| 22:36 | justin_smith | "falsum" |
| 22:37 | justin_smith | also, (⊥) has an antonym, (⊤) and both look kind of butt-like when parenthesized |
| 22:38 | teslanick | Indeed. It's like the two great taxinomies of highly convex rear-ends. |
| 22:38 | teslanick | I think Sir Mix-A-Lot wrote a ballad to the union of both taxonomies. |
| 22:39 | justin_smith | (inc teslanick) |
| 22:39 | lazybot | ⇒ 2 |
| 22:39 | teslanick | \o/ I will treasure this. |
| 22:44 | ToxicFrog | Man, apply+core.typed is my worst enemy |
| 22:44 | ToxicFrog | Target: (IFn [java.lang.String Any * -> java.lang.String]) |
| 22:44 | ToxicFrog | Arguments: (clojure.lang.PersistentList String) |
| 22:45 | ToxicFrog | Those look type-compatible to me! |
| 22:45 | justin_smith | ToxicFrog: is apply worse than other higher order constructs? |
| 22:45 | ToxicFrog | justin_smith: well, it's the only one giving me grief |
| 22:46 | justin_smith | one of these days I will take the core.typed plunge - I think I'll try using prismatic/schema more extensively first though |
| 22:46 | ToxicFrog | An earlier issue with it was entirely my fault -- (apply f x ys) matches the type [X Y * -> ...], not [X (Vec Y) -> ...] |
| 22:46 | ToxicFrog | But here it looks like it should be type-compatible; the PersistentList String expands to String String String... when applied, so it should match the signature [String Any * -> ...] |
| 22:48 | ToxicFrog | I also get this new and exciting error: |
| 22:48 | ToxicFrog | Type Error (bltool/data/default.clj:26:1) Internal Error (bltool/data/default.clj:26:1) Unreachable method: Local inferred to be bottom when applying multimethod filter |
| 22:50 | ambrosebs | ToxicFrog: that will fail for an empty list |
| 22:51 | truebuddi | +cnt |
| 22:51 | ToxicFrog | ambrosebs: in this case, the list is generated by macro expansion and is known at compile time to be nonempty. |
| 22:51 | ToxicFrog | (and I don't control the macro, it's slingshot's throw+) |
| 22:52 | ambrosebs | ToxicFrog: very likely throw+ will need a typed variant. |
| 22:52 | ambrosebs | for any complicated macro it's usually the case |
| 22:52 | ToxicFrog | As in, write my own type-annotated replacement for it? |
| 22:52 | ambrosebs | yes |
| 22:52 | ToxicFrog | D: |
| 22:52 | ambrosebs | like clojure.core.typed/for is for clojure.core/for |
| 22:53 | ToxicFrog | I don't suppose there's some way I can tell it to just not check anything inside a throw+ block |
| 22:53 | ToxicFrog | (also, any idea on the internal error?) |
| 22:54 | ambrosebs | ToxicFrog: hmm I'd need to see the defmulti/defmethod |
| 22:55 | ambrosebs | ToxicFrog: core.typed just macroexpands out everything blindly and checks it |
| 22:55 | ambrosebs | the solution is another macro unfortunately |
| 22:59 | ToxicFrog | ambrosebs: they're pretty simple: https://gist.github.com/ToxicFrog/73e20b453e4b578ab590 |
| 22:59 | ToxicFrog | And it's only the second one that it generates that error on, which is especially weird. |
| 23:00 | ambrosebs | ToxicFrog: the return type should not be Nothing |
| 23:00 | ambrosebs | Nothing means an error |
| 23:00 | ambrosebs | of write-games |
| 23:01 | ToxicFrog | What should it be, then? nil? |
| 23:01 | ToxicFrog | Also, that passes type checking, it's read-games that it objects to. |
| 23:01 | ambrosebs | oh right I see |
| 23:02 | ambrosebs | ToxicFrog: so it's saying that read-games with dispatch value "nil" is unreachable based on the type of the multimethod |
| 23:03 | ambrosebs | perhaps the first argument of read-games should be (U nil String) |
| 23:04 | ambrosebs | note that core.typed shouldn't really be complaining this loudly |
| 23:04 | ambrosebs | it should just ignore the method and move on |
| 23:04 | ambrosebs | but I decided to be noisy at least while core.typed's implementation is relatively young |
| 23:04 | ToxicFrog | Yep, if I changed it to (U nil String) it stops complaining about that one and starts complaining about the fourth one. |
| 23:05 | ambrosebs | right same issue I guess |
| 23:05 | ToxicFrog | Yeah. |
| 23:05 | ambrosebs | nothing to do with the Nothing return type |
| 23:05 | ToxicFrog | Either can be nil for "argument not specified" |
| 23:05 | ToxicFrog | And now all four of them are complaining about "bad arguments to apply" from throw+'s use of format, which is more in line with what I'd expect. |
| 23:07 | ToxicFrog | For now I think I'll just mark that ns :collect-only, I really only care about it for checking the other defmethods associated with it. |
| 23:07 | ambrosebs | good idea |
| 23:10 | ToxicFrog | ...hmm. How do I mark it :collect-only? I can't find docs for this, and I thought it was just (ns bltool.data.default ^:collect-only ...) but that doesn't appear to do anything. |
| 23:11 | ToxicFrog | Oh, I see. It's either (ns foo {:core.typed {:collect-only true}} ...), or (ns ^{:core.typed ...} foo ...) |