2016-02-09
| 00:45 | wombawomba | I'm trying to generate data that conforms to a prismatic schema. However, different fields of the data need to conform to certain constraints (on the form `(= field_x (f {:y field_y :z field_z ...}))`). I want my generator to take a schema and a collection of such constraints, and produce valid output when possible. Any ideas on how to get started on this? |
| 00:45 | wombawomba | I was thinking I might be able to leverage core.logic somehow, but I'm not sure |
| 00:46 | wombawomba | specifically I'm thinking that each constraint would be on the form `{:f some-fn :vars {:y [:path :to :y :in :schema] ...}}` |
| 04:41 | noncom | wombawomba: yeah, well, while thinking about it, core.logic seems like it may be of help.. but i am not too much into it, so i cannot really say. you could try #minikanren to ask about core.logic |
| 04:42 | noncom | wombawomba: other than that, a simple solution comes to my mind - something like "combined generators" - akin to combined parsers |
| 04:45 | noncom | wombawomba: you can generate the datastructure level-by-level, using some grammar to describe it, like the L-ssytems |
| 04:54 | jonathanj | does clojure.java.io/copy disturb the input? |
| 04:55 | jonathanj | i have to pass an InputStream to a function to render, but i would first like to parse it as XML (to extract some information) |
| 04:55 | noncom | jonathanj: disturb the input? |
| 04:55 | jonathanj | there is a possibility the stream is not rewindable, how do i get two copies? |
| 04:56 | noncom | ummm idk, why not just work with streams? |
| 04:56 | noncom | copy is just a quick function for an easy task.. not sure it can do what you're asking.. |
| 04:56 | jonathanj | sorry, i don't understand what you're asking |
| 04:56 | jonathanj | i have one stream, i need to do two things with it |
| 04:56 | noncom | <jonathanj> does clojure.java.io/copy disturb the input? |
| 04:56 | noncom | ^^ disturb |
| 04:57 | jonathanj | if at all possible i'd like to avoid trying to store all the content in memory as byte[] |
| 04:58 | noncom | jonathanj: see the source: https://github.com/clojure/clojure/blob/2c9ff46454ebf34b14ab4612f691b3c93031b362/src/clj/clojure/java/io.clj#L391 the function is very bare-bones |
| 04:58 | noncom | if i were you then dealing with any more or less complex task on working with streams, i'd simply write the logic i need manually |
| 04:59 | noncom | not sure if you can coerce (copy) to do anything else than just copy |
| 04:59 | jonathanj | even without copy, is it possibly to clone the original stream somehow? |
| 05:00 | noncom | jonathanj: depends on what you mean by "clone" |
| 05:00 | noncom | sure, you can read data and do two different tasks with it |
| 05:01 | noncom | the stream is read in chunks, so you get these chunks on every "read" |
| 05:01 | noncom | you always read a stream into a buffer of a fixed size |
| 05:01 | noncom | does it make any sense to you? |
| 05:02 | jonathanj | not really, no |
| 05:02 | noncom | what is your task, exactly? |
| 05:02 | jonathanj | the two tasks are: render an XML document (with flying saucer) and parse the XML document to extract information from it |
| 05:03 | jonathanj | i'm not sure how reading chunks out of the stream actually help me achieve both of those tasks unless i read the entire contents of the stream |
| 05:03 | noncom | so, you 1) read the xml doc from a file, 2) send it to the renderer, 3) extract the info from it? |
| 05:03 | noncom | jonathanj: that's the point: "no how will it help you" :) |
| 05:03 | noncom | jonathanj: you simply need to read it all in order to really process it |
| 05:04 | noncom | and when you've read it all, there you have it - you can run several tasks on that data |
| 05:05 | noncom | i don't really see any problem here unless the xml is really big |
| 05:05 | noncom | but then, rendering it would also be pointless |
| 05:06 | noncom | xml is such a thing, it has the opening and closing tags.. you can't really make sense out of the document if you don't have 100% of it |
| 05:06 | MasseR | Streaming xml? |
| 05:06 | MasseR | It's a thing |
| 05:07 | MasseR | But you probably need to have a schema of the document first |
| 05:21 | jonathanj | if i'm using clojure.data.xml, how can i produce a org.w3c.dom.Document? |
| 06:08 | Kah0ona | cd /#clojure-beginners |
| 06:08 | Kah0ona | lol |
| 06:09 | Kah0ona | Question: I am developing a ring app, using compojure.api. But when I change my api definitions, the changes aren't picked up. I have wrap-reload as middle ware in place. Should that do it, or am I missing something |
| 06:11 | jonathanj | Kah0ona: maybe https://github.com/weavejester/lein-ring might be helpful to you? |
| 06:12 | Kah0ona | ok so `lein ring server` should already do the trick? |
| 06:13 | Kah0ona | can it be because of compojure.api requiring its routes to be declared in a macro? Are macro's re-expanded after route definitions have changed? |
| 06:13 | jonathanj | Assuming that auto-reload? is enabled and the code you're changing is in reload-paths |
| 06:13 | Kah0ona | okay |
| 06:13 | Kah0ona | and then it can be inside (defroutes ) and it will work? |
| 06:13 | jonathanj | I'm pretty sure that lein-ring just reloads on file changes, so as long as the file actually changes, it should work regardless of what the code does. |
| 06:14 | Kah0ona | another thing I am confused about with lein ring server --> stuff like (println ) statements arent displayed anywhere. So should I opt for a development flow where i use some (start-server) function that starts up jetty? |
| 06:14 | Kah0ona | or will `lein ring server` provide a repl as well |
| 06:15 | jonathanj | there is an :nrepl option you can use to have lein-ring start an nrepl, that you can connect to with cider or whatever tools you prefer |
| 06:16 | jonathanj | i think lein-ring is the thing that watches for file changes, so if you're not running your code via that then, unless you have something else in place, nothing will be reloading |
| 06:17 | Kah0ona | okay so then it would be: |
| 06:17 | Kah0ona | start lein ring server with nrepl option, |
| 06:17 | Kah0ona | connect to it from a different lein repl session with :connect ..... added? |
| 06:17 | jonathanj | you can also use `lein repl :connect the_host:the_port` to just get a plain clojure REPL if you're not using cider or such |
| 06:17 | Kah0ona | alright, i just noticed i dont have auto-reload? is there |
| 06:17 | jonathanj | Kah0ona: :auto-reload? (according to the docs) is true by default for a dev environment |
| 06:18 | Kah0ona | hmmm |
| 06:18 | Kah0ona | okay |
| 06:18 | jonathanj | you can try explicitly setting it to true but the docs indicate that shouldn't be necessary |
| 06:20 | Kah0ona | yeah, okay thanks for your info. will try some stuff and try to make it work with lein-ring |
| 06:21 | jonathanj | perhaps try minimizing your code while you're debugging it |
| 06:21 | jonathanj | by removing middleware and such, or creating a new ring application with the simplest possible code |
| 06:22 | jonathanj | also read the lein-ring README again to make sure you didn't forget to set something (like :ring) or you didn't put it in the wrong key, etc. |
| 07:14 | Kah0ona | ok it works now, thanks! |
| 08:09 | ashnur | "Could not find tag parser for js/Object" why does it need a tag parser? can't it just use it as a symbol |
| 08:09 | ashnur | ? |
| 08:11 | ashnur | i took some edn i generated and put it into some weird thing called "ankha" |
| 09:17 | lxsameer | what does ^{:a 2} means ? (^ part) |
| 09:20 | opqdonut | it means "attach metadata to the next expression" |
| 09:20 | opqdonut | metadata is used for e.g. type hints, doc strings |
| 09:21 | opqdonut | ,(meta #'map) |
| 09:21 | clojurebot | {:arglists ([f] [f coll] [f c1 c2] [f c1 c2 c3] [f c1 c2 c3 & ...]), :doc "Returns a lazy sequence consisting of the result of applying f to\n the set of first items of each coll, followed by applying f to the\n set of second items in each coll, until any one of the colls is\n exhausted. Any remaining items in other colls are ignored. Function\n f should accept number-of-colls arguments. Retu... |
| 09:22 | opqdonut | ,(meta (read-string "^{:a 2} foo")) |
| 09:22 | clojurebot | {:a 2} |
| 09:53 | fatsaucisson | Hi there |
| 09:54 | noncom | fatsaucisson: hi |
| 09:55 | noncom | ashnur: depends on what you're actually doing |
| 09:55 | noncom | if you don't eval on read, you can treat it as a symbol..? |
| 09:56 | ashnur | i don't want to treat it :), i just wanted to look at it, i didn't know that that ankha thing will try to eval it or something |
| 09:56 | fatsaucisson | I've issues with a macro I'm writing, can I ask that here or this a totally another purpose chan ? |
| 09:57 | pbx | sounds perfect for this channel fatsaucisson |
| 09:59 | noncom | fatsaucisson: yes sure you can |
| 10:01 | fatsaucisson | Cool, I'm writing a macro that expands and works well in the REPL, but when called in a callback function (that's an ircbot) the code fail and drop a ClassCastException where String cannot be cast to IFn |
| 10:02 | noncom | fatsaucisson: use refheap to post your code |
| 10:02 | noncom | example |
| 10:02 | noncom | ashnur: hmmmm |
| 10:02 | fatsaucisson | refheap (defmacro command |
| 10:02 | fatsaucisson | [name input suite & forms] |
| 10:02 | fatsaucisson | `(when (.startsWith ~input ~name) |
| 10:02 | fatsaucisson | (let [~suite (string/replace-first ~input (re-pattern ~name) "")] |
| 10:02 | fatsaucisson | ~@forms))) |
| 10:03 | noncom | fatsaucisson: it's https://www.refheap.com/ XD |
| 10:03 | noncom | but ok |
| 10:03 | fatsaucisson | woops, well here's the macro |
| 10:03 | noncom | this is small enough to grasp here |
| 10:03 | fatsaucisson | not that big |
| 10:04 | noncom | hmmmm |
| 10:04 | noncom | and what is the stack trace? |
| 10:05 | fatsaucisson | https://www.refheap.com/114608 |
| 10:06 | fatsaucisson | the lib used is irclj i link you the error callback |
| 10:07 | noncom | fatsaucisson: well, looks like somewhere you end up using a string as a function |
| 10:07 | noncom | ,("heeeey" 1 2 3) |
| 10:07 | clojurebot | #error {\n :cause "java.lang.String cannot be cast to clojure.lang.IFn"\n :via\n [{:type java.lang.ClassCastException\n :message "java.lang.String cannot be cast to clojure.lang.IFn"\n :at [sandbox$eval25 invokeStatic "NO_SOURCE_FILE" 0]}]\n :trace\n [[sandbox$eval25 invokeStatic "NO_SOURCE_FILE" 0]\n [sandbox$eval25 invoke "NO_SOURCE_FILE" -1]\n [clojure.lang.Compiler eval "Compiler.java" 6... |
| 10:07 | noncom | see, same error |
| 10:08 | fatsaucisson | well i understand that |
| 10:08 | fatsaucisson | but i don't point where |
| 10:09 | noncom | hmmm |
| 10:10 | fatsaucisson | i refhead some use case for you making an idea |
| 10:12 | noncom | wfatsaucisson: well, it is very hard to say.. many things can happen. especially that we don't know what 'forms you're passing in |
| 10:13 | fatsaucisson | here : https://www.refheap.com/114609 |
| 10:15 | fatsaucisson | well i copy/past to quick there is error in the refhead |
| 10:16 | fatsaucisson | here corrected one : https://www.refheap.com/114610 |
| 10:19 | noncom | fatsaucisson: hmmm, well, doing (println ~@forms) before you call ~@forms prints nil... |
| 10:21 | noncom | fatsaucisson: because what's in () gets evaluated before it is passed to the macro |
| 10:23 | luma | the problem is in the command macro |
| 10:23 | noncom | fatsaucisson: that's one thing i have found that you're probably expecting to work the other way |
| 10:23 | noncom | luma what do you think? |
| 10:23 | noncom | luma: i'm actually a bit puzzled by this one |
| 10:23 | luma | in the errorcallback, the command macro expands to (when (.startsWith 'text "!echo") ...) |
| 10:24 | fatsaucisson | yeah |
| 10:24 | noncom | ahh, that |
| 10:25 | fatsaucisson | oh you mean 'text and not text ? |
| 10:25 | noncom | that thing |
| 10:25 | noncom | it's call your macro with a macro thing :) |
| 10:25 | luma | yes, i mean 'text, the symbol text |
| 10:26 | luma | not whatever that symbol would resolve to, because that isn't known at compile time (when the macro is expanded) |
| 10:26 | noncom | and you likely can't use (resolve) because it's a local variable |
| 10:26 | noncom | right? |
| 10:26 | clojurebot | right is not wrong |
| 10:26 | luma | you can |
| 10:27 | luma | you can't |
| 10:27 | luma | because the symbol is just a symbol, it doesn't resolve to anything at that point |
| 10:27 | fatsaucisson | yeah but it's in a context where that symbol is bind to something no? |
| 10:28 | luma | no |
| 10:28 | luma | it will be at runtime |
| 10:28 | fatsaucisson | Yeah at runtime |
| 10:29 | fatsaucisson | that's what i want |
| 10:29 | luma | but not during macro expansion |
| 10:29 | fatsaucisson | I actually want the symbol text and the symbol suite |
| 10:30 | luma | hmm, maybe i misread your code |
| 10:30 | luma | let me take another look at it |
| 10:30 | fatsaucisson | in fact after a macroexpansion errorcallback become goodcallback |
| 10:31 | fatsaucisson | or at least I think it does |
| 10:31 | luma | yeah, i see my mistake, i thought that the when was outside the syntax-quote |
| 10:31 | luma | sorry |
| 10:33 | fatsaucisson | I don't think it's inside the irclj lib, because the callback function is pass at Runtime so it should already be macroexpand |
| 10:33 | luma | yes, it was my mistake |
| 10:34 | luma | i plugged that into repl and it seems to work (although i don't understand why you bind suite to "" inside errorcallback and never use that binding) |
| 10:35 | fatsaucisson | if I don' bind it, it does not want to compile |
| 10:35 | fatsaucisson | is there an other way to declare it ? |
| 10:37 | luma | you don't need to "declare" it |
| 10:38 | luma | your macro is generating the let binding for it |
| 10:39 | noncom | yeah, just use like (let [suite# (something) ...] ...) |
| 10:40 | luma | no |
| 10:40 | luma | you don't want to do that here |
| 10:40 | luma | you want to give the symbol as a parameter for the macro so that you can use that symbol in the forms |
| 10:40 | noncom | oh |
| 10:41 | luma | seems to work for me: https://www.refheap.com/114611 |
| 10:41 | fatsaucisson | errorcallback function works properly… |
| 10:41 | fatsaucisson | I don't get it |
| 10:42 | fatsaucisson | that's irclj doing obscure stuff then |
| 10:42 | luma | what is the actual error that you get? |
| 10:44 | fatsaucisson | When I give errorcallback as a callback function for irclj (do that stuff each time you receive an irc message) it returns an error when receiving a message |
| 10:44 | fatsaucisson | that's not the case with goodcallback |
| 10:46 | fatsaucisson | ok |
| 10:46 | fatsaucisson | so now it works properly |
| 10:46 | fatsaucisson | and I have no idea why |
| 10:46 | fatsaucisson | how bizarre |
| 10:57 | fatsaucisson | well |
| 10:59 | fatsaucisson | it seems that simplifying the field accessed in the args worked (just picked text, nick, target, host) |
| 10:59 | fatsaucisson | whereas when i bind all the fields that somehow breaks |
| 10:59 | fatsaucisson | that's really strange |
| 11:00 | fatsaucisson | no |
| 11:00 | fatsaucisson | ok |
| 11:00 | fatsaucisson | got it |
| 11:00 | fatsaucisson | there was a field named command |
| 11:00 | fatsaucisson | … |
| 11:01 | fatsaucisson | wow sorry for getting you involved in a mistake of that level |
| 11:10 | fatsaucisson | Ok, just another macro question |
| 11:13 | fatsaucisson | i have my command macro, now i want to write a macro doing something like this https://www.refheap.com/114614 |
| 11:14 | fatsaucisson | how can I do in order to rewrite the list of command ? |
| 11:18 | luma | something like this: https://www.refheap.com/114615 |
| 11:20 | fatsaucisson | ok, that's exactly the pattern I was looking for ! |
| 11:20 | fatsaucisson | Thx |
| 11:49 | python476 | hi there |
| 11:49 | fatsaucisson | I'm leaving, bye. Have a nice day. |
| 11:50 | fatsaucisson | python476 : Hi |
| 11:50 | python476 | I'm struggling hard between cljs and dom collections |
| 11:50 | python476 | so far people managed to make a ISeq out of HTMLCollection, but mapping #(... .-name ...) yields 'ReferenceError: proxy is not defined' |
| 11:54 | fatsaucisson | are you in a browser, or just with node ? |
| 11:54 | python476 | in browser sorry |
| 11:55 | python476 | in a jsbin sandbox too |
| 11:56 | fatsaucisson | okay, seems like ecmascript6 support thing. Can't help you on that one. GL |
| 11:57 | python476 | aight |
| 13:03 | TristeFigure | Possible bug : let is reported as a special form in the doc but (special-symbol? 'let) returns false. Under the hood, special-symbol? checks for the presence of the symbol as a key in (. clojure.lang.Compiler specials). 'let is not in this map but 'let* is. (special-symbol? 'let*) returns true. Should I report this ? |
| 13:04 | justin_smith | TristeFigure: let* is actually a special form, let is a macro that expands to a call to let*, I forget the rationale, but there is one for falsely reporting let is special |
| 13:04 | justin_smith | TristeFigure: see also fn vs. fn*, same scenario |
| 13:05 | justin_smith | ,(special-symbol? 'fn) |
| 13:05 | clojurebot | false |
| 13:05 | justin_smith | ,(special-symbol? 'fn*) |
| 13:05 | clojurebot | true |
| 13:06 | justin_smith | TristeFigure: I think the doc is just oversimplifying for the sake of clarity, those are macros not special forms (the difference is that the macros support destructuring and the * version special forms they expand to do not) |
| 13:12 | TristeFigure | justin_smith: okay then. Anyway, special-symbol? is mostly an obscure function ... unless you happen to be writing a debugger ! |
| 13:18 | ekryyn | hello all ! |
| 13:25 | ekryyn | I am new to clojure and I'm struggling with a need that comes very often |
| 13:26 | ekryyn | suppose we have (defn create-cell [color x y] {:color color :x x :y y}) |
| 13:27 | ekryyn | and a vector of coord under that form [ [1 2] [10 20] [5 9] ] |
| 13:27 | ekryyn | what is a good way to create 3 cells with :color fixed to "blue" ? |
| 13:27 | ekryyn | from this set of coords |
| 13:29 | justin_smith | ,(map (fn [[x y]] {:color "blue" :x x :y y}) [[1 2] [10 20] [5 9]]) |
| 13:29 | clojurebot | ({:color "blue", :x 1, :y 2} {:color "blue", :x 10, :y 20} {:color "blue", :x 5, :y 9}) |
| 13:29 | justin_smith | ,(for [[x y] [[1 2] [10 20] [5 9]]] {:color "blue" :x x :y y}) ; alternately |
| 13:29 | clojurebot | ({:color "blue", :x 1, :y 2} {:color "blue", :x 10, :y 20} {:color "blue", :x 5, :y 9}) |
| 13:30 | ekryyn | I really want to use "create-cell" |
| 13:30 | justin_smith | why? |
| 13:30 | clojurebot | why is the ram gone |
| 13:30 | ekryyn | because it's supposed to hold the "implementation" of the cell, wich I simplified to a dict |
| 13:30 | justin_smith | ekryyn: (map #(apply create-cell "blue" %) ...) |
| 13:30 | ekryyn | the cell might be represented differently |
| 13:31 | justin_smith | ekryyn: hiding data representation is not idiomatic in clojure |
| 13:32 | ekryyn | justin : according to the doc, apply will prepend x and y, so i'll end up with calls like : (create-cell 1 2 "blue") |
| 13:32 | justin_smith | ekryyn: though you could implement a protocol if you plan on making multiple implementations and swapping them out |
| 13:32 | justin_smith | ekryyn: no |
| 13:32 | justin_smith | that is false |
| 13:32 | justin_smith | ,(apply list 1 [2 3]) |
| 13:32 | clojurebot | (1 2 3) |
| 13:32 | ekryyn | ok, but if my cell representation is not suitable anymore ? |
| 13:32 | justin_smith | then change your code |
| 13:32 | ekryyn | that means all the places that potentially create cells |
| 13:33 | mmastic | Can core.async do state? or do I need a ref type in addition? |
| 13:34 | justin_smith | ekryyn: if you plan on swapping out implementations, the idiomatic way to do that is a protocol, but that's about abstracting behaviors typically rather than just data structure |
| 13:34 | justin_smith | mmastic: core.async is 100% imperative, it isn't even fp |
| 13:34 | justin_smith | it's all state |
| 13:35 | mmastic | Oh yeah but I mean, can it do *my* state? :P like, can I have a channel that stores a number that I could manipulate over time, for instance? |
| 13:35 | ekryyn | ok justin, I re-read apply doc and I guess it's clear now |
| 13:36 | ekryyn | Thank you for the insight |
| 13:37 | justin_smith | mmastic: you could have (go-loop [state nil] (let [command (alts! change-state send-state)] ... (recur new-state)) (very rough sketch) |
| 13:38 | justin_smith | ekryyn: np. my main point about abstracting data representations (as opposed to behaviors) is that we don't do much information hiding, and don't need it as much because things are for the most part default immutable. So this leads to a different kind of code hygeine, if that makes any sense. |
| 13:38 | mmastic | justin_smith: Oh pretty cool, like seriously a tail-recursive loop, yeah? |
| 13:38 | justin_smith | ekryyn: instead of hiding a data structure in a constructor function, we would be more likely to make a protocol, and implement that using various data structures / behaviors (though in practice all would be records, which act like maps for data access) |
| 13:39 | justin_smith | mmastic: right, where you either send or receive a value based on that alts! for each message, and persist any changed value with recur, and send any changed value back to the channel requested |
| 13:39 | justin_smith | mmastic: a get value request would look like [c] where c is the channel to send back on |
| 13:40 | mmastic | Love it, I'll try it out now. Thanks a lot already ^^ |
| 13:40 | justin_smith | mmastic: that's how I do state with message passing at least. You can also just use an atom / ref / agent where that makes sense :P |
| 13:41 | ekryyn | justin_smith: I'm not sure I really understand. Often, development process is done by enriching structure as features come in |
| 13:41 | mmastic | Yeah, I'm trying to avoid it. State makes me cry. Imagine what explicit ref state does to me.. :P |
| 13:42 | justin_smith | ekryyn: in clojure "enriching structure" usually means attaching a new key to a hash map, and the functions that don't use that key can ignore it |
| 13:42 | justin_smith | mmastic: but core.async is just a big old state dance |
| 13:44 | mmastic | True, and Haskeller me still prefers FRP, but I'm getting that a lot of people like it a lot and prefer it over that, Rich saying it's simpler, plus GUI libraries plug to it out of the box, so it's fair to give it a try. |
| 13:44 | ekryyn | justin_smith: ok it's hard for me to see how things come together in the end. I have a lot to learn yet. Thank you anyway |
| 13:44 | mmastic | Transitioning over is really hard for me but I'm really drawn to Lisp. |
| 13:45 | justin_smith | ekryyn: np, and of course you can implement these things however makes sense for your app, just trying to provide the rationale for our usual idioms. |
| 13:45 | ekryyn | justin_smith: yes it makes sense, how do you look for the usual idioms in specific situations ? What is the best resource ? |
| 13:46 | justin_smith | ekryyn: there are some great books out there, like Joy of Clojure, Clojure Applied in particular |
| 13:46 | ekryyn | ok, cheers |
| 13:47 | justin_smith | ekryyn: also there are often opinionated clojure devs here or on the clojurians slack channel who are willing to argue about design choices :) |
| 13:47 | sdegutis | Using "Components" for an entire web app /seems/ really nice in theory. |
| 13:47 | sdegutis | But in practice, then you have a chicken/egg problem. |
| 13:47 | sdegutis | The router and other services all depend on each other. |
| 13:47 | justin_smith | sdegutis: I solve that by splitting components |
| 13:48 | sdegutis | justin_smith: Even if you have a lot of components, the fact is that the router depends on them, and somehow they have to be usable within the router. |
| 13:48 | justin_smith | sdegutis: for example, I have a "conduit" - a channel of communication. I split this into the raw communication facility, and the abstractions on top of it like routing etc. That way each channel knows how to send something on the other |
| 13:48 | justin_smith | because all the routing / top level mechanisms have access to the sending mechanisms of all the others |
| 13:49 | justin_smith | because the sending facility is separated and doesn't need access to anything else |
| 13:49 | justin_smith | sdegutis: same with components and a router, you can separate any common thing that the router needs that are also needed by something using the router |
| 13:49 | justin_smith | split it and pull it together at the top |
| 13:50 | justin_smith | sdegutis: true loops can be fixed with top level bindings, but they should be rare |
| 13:54 | sdegutis | justin_smith: ahh so your router is pretty "dumb" then, and just translates Ring messages (via something like weavejester/clout) into messages to go over your transport, i.e. a function to call and the parameters to give it, and then just send it over? |
| 13:54 | justin_smith | sdegutis: also, a component can put a promise in the system map that something further down delivers to, if you need to retain modularity |
| 13:55 | justin_smith | sdegutis: oh, the routing I was talking about just now was message routing, but for my http router what I do is write components that implement ring middleware to provide their functionality, and the http-router is at the top level, nobody else needs its data |
| 13:55 | justin_smith | I don't provide the endpoints themselves through component though (I guess I could...) |
| 13:55 | sdegutis | justin_smith: huh, using middleware for core business functionality? never heard of that before |
| 13:56 | justin_smith | sdegutis: eg. my db component passes along a wrapper that provides a handle to the db connection in the request map |
| 13:57 | justin_smith | in the form of a ring middleware, of course |
| 13:58 | sdegutis | justin_smith: oh yeah that makes more sense.. I have a middlware that passes the db, another one that checks if you're logged in and if so assoc's the logged in user, etc |
| 13:58 | sdegutis | actually no "etc" those are literally the only two |
| 13:58 | sdegutis | But now I think I have to have one that passes in the top-level "system" component, so that routes can do stuff with it. |
| 13:59 | justin_smith | sdegutis: couldn't you just make the http-server/router component pull in all the other components? |
| 14:03 | sdegutis | justin_smith: I think so... but then it has to put each of them into a middleware so that routes can actually have access to them... |
| 14:03 | sdegutis | justin_smith: and then that gets into confusion about object lifetimes, regarding objects which have a strong hold on other, which confuses me... |
| 14:03 | justin_smith | sdegutis: see, I did the opposite, and created middlewares in each component then applied them in the http-server component, same result though |
| 14:03 | sdegutis | justin_smith: something about object retain cycles |
| 14:04 | sdegutis | justin_smith: hmm |
| 14:04 | sdegutis | I wonder, in Clojure 1.8 is it possible to use the built-in socket server instead of jetty/ring-adapter? |
| 14:04 | justin_smith | lifetimes of what objects? anything that ends up in a component map implicitly should have the same lifetime as the component system itself |
| 14:04 | sdegutis | I suppose. |
| 14:04 | justin_smith | sdegutis: feel like implementing http? the socket server is just tcp |
| 14:04 | sdegutis | Man, I haven't been this confused in years. |
| 14:05 | sdegutis | justin_smith: ah |
| 14:05 | justin_smith | haha |
| 14:05 | justin_smith | sdegutis: getting confused regularly is a good habit, and unlike eg. drinking lots of whisky this confusion will even likely lead to learning something valuable other than "that's what it feels like to be hung over" |
| 14:06 | justin_smith | free life advice |
| 14:13 | m1dnight_ | Would a library for giphy be something reasonable to publish on Clojars? |
| 14:13 | m1dnight_ | I want to publish something :p |
| 14:13 | justin_smith | m1dnight_: what would a giphy lib do? |
| 14:14 | m1dnight_ | Search for example |
| 14:14 | m1dnight_ | It's something trivial but I figured why not |
| 14:14 | m1dnight_ | Hence the question |
| 14:18 | timvisher | has anyone used `clj-http 2.0.0` to make a `TLSv1.1` request on Java 7? |
| 14:19 | timvisher | come on justin_smith, save my bacon like you always do :P |
| 14:34 | sdegutis | I wouldn't mind a nice gif library, yeah. |
| 14:34 | sdegutis | I don't know how to use all those fancy Adobe softwares, so it's really hard to hit /r/gif's or imgur's front pages. |
| 14:35 | amalloy | m1dnight_: if a thing is written in clojure, and does something that at least one person (you) would want to do, then it is a good candidate for putting on clojars |
| 14:45 | noncom|2 | what do you typically have for clojure in emacs? CIDER, clojure-mode... anything else? |
| 14:45 | justin_smith | timvisher: day job :P - sorry I have never explicitly used TLSv1.1 (though maybe I accidentally used it by making an https request?) |
| 15:09 | timvisher | justin_smith: thanks as always for the response. the fix appears to be to upgrade to java 8 |
| 15:09 | timvisher | amazingly |
| 15:09 | justin_smith | hmph |
| 15:10 | timvisher | there must be a way to get java 7 to do this but it's beyond me :) |
| 15:30 | xemdetia | java 7 can do sslv3 to tls v1.2, I just don't know how clj-http works |
| 15:32 | xemdetia | you need to tune the jce though I think |
| 15:32 | xemdetia | not usually |
| 15:33 | xemdetia | Usually some combination of SSLContext.getInstance() w/ https://docs.oracle.com/javase/7/docs/technotes/guides/security/StandardNames.html#SSLContext |
| 15:36 | xemdetia | again you can sometimes tune this externally through -D options |
| 15:36 | timvisher | how do i tell `clojure.java.jdbc/insert!` to use `CURRENT_TIMESTAMP` or `NOW` for a value? |
| 15:37 | timvisher | xemdetia: i've seen mention of a `https.protocols` system property |
| 15:37 | timvisher | that seems to have no effect on anything when i attempt to use it though |
| 15:37 | xemdetia | it depends on the JCE driver you are using |
| 15:37 | xemdetia | I am aware of 10 |
| 15:38 | timvisher | whew |
| 15:38 | xemdetia | the flags are implementation specific |
| 15:38 | timvisher | it's apache httpcomponents under the hood |
| 15:38 | timvisher | is that what you mean? |
| 15:38 | xemdetia | no, I am talking specifically about the cryptography engine |
| 15:39 | timvisher | https://gist.github.com/e94682655756035c945a |
| 15:39 | timvisher | does that give you any clues? |
| 15:46 | xemdetia | what is your default JCE driver? are you on a sunjsse2 stack with oracle jvm? are you on openjdk? |
| 15:46 | xemdetia | lots of questions |
| 15:47 | timvisher | xemdetia: lots of questions indeed. |
| 15:47 | timvisher | java version "1.7.0_95" |
| 15:47 | timvisher | OpenJDK Runtime Environment (IcedTea 2.6.4) (7u95-2.6.4-0ubuntu0.14.04.1) |
| 15:47 | timvisher | OpenJDK 64-Bit Server VM (build 24.95-b01, mixed mode) |
| 15:47 | timvisher | i honestly don't know what the default JCE driver is |
| 15:47 | xemdetia | and you are using clj-http right |
| 15:52 | xemdetia | I mean I don't know how the org.apache.http.conn.ssl is different than other tls implementations |
| 15:52 | xemdetia | not usually my tool of choice |
| 15:52 | xemdetia | did you check to see if the remote can even do tls 1.1 or tls 1.2? |
| 15:52 | xemdetia | how did you scan the port? |
| 15:53 | xemdetia | if you have openssl 1.0.1 or later you can just do openssl s_client -connect host:port -tls1, openssl s_client -connect host:port -tls1_1 and openssl s_client -connect host:port -tls1_2 |
| 15:53 | timvisher | xemdetia: the story is that the service used to support 1.0, 1.1, and 1.2 |
| 15:53 | timvisher | they are turning of 1.0 soon |
| 15:54 | timvisher | and we're discovering that our client appears to be unable to speak anything else |
| 15:54 | xemdetia | this is common |
| 15:54 | xemdetia | especially if it was something that was built around the time of openssl 0.9.8 |
| 15:54 | timvisher | if we bump to java 8, which supposedly use tlsv1.2 by default (i'm not sure what tha means) then everything just starts working |
| 15:54 | xemdetia | https://github.com/dakrone/clj-http/blob/master/src/clj_http/conn_mgr.clj#L35 |
| 15:54 | xemdetia | here you go |
| 15:54 | xemdetia | it is probably this |
| 15:55 | timvisher | that's extremely interesting |
| 15:55 | xemdetia | timvisher, because of security changes and the fact java is trying to be a stable platform |
| 15:55 | timvisher | i would think though that with that in place upgrading java should have no effect? |
| 15:55 | xemdetia | the string passed to SSLContext's gets interpreted differently depending what JCE driver is getting it |
| 15:55 | xemdetia | so for instance post POODLE, "SSL" was auto-corrected to "TLS" in recent java's |
| 15:56 | xemdetia | java 8 might be autopromoting everything to "TLSv1.2" by default |
| 15:56 | timvisher | oh very interesting |
| 15:56 | xemdetia | anyway I would dork with that line I found |
| 15:56 | xemdetia | it looks like it accepts a set |
| 15:57 | xemdetia | or use a different string like I mentioned earlier from https://docs.oracle.com/javase/7/docs/technotes/guides/security/StandardNames.html#SSLContext |
| 15:57 | xemdetia | switching it to just "TLS" may permit it to talk TLSv1, TLSv1.1, and TLSv1.2; most things work like that |
| 15:57 | xemdetia | depends on the JCE driver though |
| 15:57 | timvisher | xemdetia: right. the problem with that is that we're not explicitly defining the SSLContext here |
| 15:58 | xemdetia | right, so if you want it to work modify the source and see |
| 15:58 | xemdetia | in that .clj |
| 15:58 | timvisher | xemdetia: yep |
| 15:58 | timvisher | thanks this was extremely helpful |
| 15:58 | timvisher | (i'm a little out of my depth on this one :P) |
| 15:58 | xemdetia | most are |
| 16:03 | justin_smith | xemdetia: I think security stuff makes me a little more cautious about my usual "OK I get most of this lets just plow forward optimistically" plan :) |
| 16:04 | xemdetia | justin_smith, or you become the unfortunate curator of that domain for everyone around you |
| 16:04 | xemdetia | this seems to be my case |
| 16:04 | justin_smith | xemdetia: oh, I am in that position too! |
| 16:05 | justin_smith | I'm just not as far along the path to competence |
| 16:10 | xemdetia | I suppose |
| 16:10 | xemdetia | I have been so deep in it lately I just want a nap! |
| 16:11 | timvisher | xemdetia: you have my permission :P |
| 17:23 | macrolicious | trying to learn the syntax; I want foozy to contain 9; evaluating (def foozy []) (map #(if (> % 5) (conj foozy %) [1 3 2 9]) produces [] … help. |
| 17:23 | macrolicious | also, if anyone wants to give me tips on how my question would have been better structured/presented, all ears. |
| 17:27 | justin_smith | macrolicious: [] is not mutable |
| 17:28 | macrolicious | ok... |
| 17:28 | justin_smith | macrolicious: conj returns a new data structure that has your argument added |
| 17:28 | justin_smith | you need to use the return value of conj if you want that new data structure |
| 17:28 | macrolicious | I tried and failed to use def in that way… |
| 17:29 | macrolicious | wasn't nailing it... |
| 17:29 | justin_smith | ,(def a []) |
| 17:29 | clojurebot | #'sandbox/a |
| 17:29 | justin_smith | ,(def a (reduce conj a [1 2 3])) |
| 17:29 | clojurebot | #'sandbox/a |
| 17:29 | justin_smith | ,a |
| 17:29 | clojurebot | [1 2 3] |
| 17:29 | justin_smith | the thing is we never do that |
| 17:29 | macrolicious | ok |
| 17:29 | justin_smith | def is for values that won't change |
| 17:30 | macrolicious | I'm guessing I'm thinking in the old way |
| 17:30 | amalloy | (def foozy (filter #(> % 5) [1 3 2 9])) would be the closest thing to what you were trying to do |
| 17:30 | macrolicious | ah, filter, one I don't know |
| 17:30 | macrolicious | ok |
| 17:30 | macrolicious | sweet |
| 17:30 | justin_smith | what you actually do is use let for local bindings, and do function calls using those bindings, without creating top level defs - def is for things known at compile time typically |
| 17:31 | justin_smith | but one step at a time, of course :) |
| 17:31 | macrolicious | okey dokey |
| 17:32 | macrolicious | I'm following tutorials (slowly) then decided to play around in the repl, with predictable results… back to the tutorials ;-) |
| 17:33 | macrolicious | https://www.youtube.com/watch?v=MeRghYqi090 |
| 17:38 | amalloy | is that link relevant somehow? off-topic chat in here is fine, but a video link with no context, where someone can't even evaluate whether they might want to watch it without clicking it first, is something i wouldn't encourage |
| 17:39 | sdegutis | Yeah I'm with amalloy on this one. |
| 17:39 | sdegutis | No rickrolling please. |
| 17:40 | amalloy | i'm never gonna give up rickrolling |
| 17:42 | sdegutis | amalloy: Oh you! http://i.imgur.com/uVs9TRS.jpg |
| 17:44 | sdegutis | Dear everyone here, including justin_smith: when you're writing a web app and Hiccup is involved, what's your preferred way to handle the monstrosity of Hiccup code that's extracted as the common "template" (header & footer in Hiccup) for all your pages? |
| 17:44 | justin_smith | sdegutis: I use a templating library that does "wraps" (which are like includes but inside out - your content goes in the middle instead of it going in the middle of your content) |
| 17:45 | justin_smith | actually I have not done that kind of templating in a while, but that's what I did back then |
| 17:46 | justin_smith | sdegutis: with hiccup you can do (assoc-in page-skeleton [magic spot here] content) |
| 17:46 | justin_smith | same concept |
| 17:47 | justin_smith | if skeleton is [:html [:head ...] [:body]] then (assoc-in page-skeleton [2 0] content) |
| 17:48 | sdegutis | Hmm, that seems limited since it can't do evaluation on input when the page-skeleton contains logic. |
| 17:48 | justin_smith | or... [2 1] but you probably get the idea |
| 17:48 | sdegutis | Like, to show a different navbar whether you're signed in or not. |
| 17:49 | justin_smith | well that's a different skeleton for each condition, but same concept (you'll just be associng deeper) |
| 17:51 | amalloy | that sounds awful |
| 17:51 | justin_smith | amalloy: alternate proposal? |
| 17:51 | amalloy | a function that takes arguments for the variable stuff |
| 17:51 | amalloy | (defn page [body] [:html [:head whatever] [:body body]]) |
| 17:51 | justin_smith | oh yeah that's cleaner |
| 17:52 | amalloy | hiccup data structures are basically write-only |
| 17:52 | amalloy | if you ever take one as input, lose 8 Sanity |
| 17:52 | amalloy | if you want to treat your html structure as input (a reasonable thing to want), you want to use something other than hiccup, like enlive |
| 17:54 | amalloy | i wrote this years and years ago, but see https://github.com/4clojure/4clojure/blob/develop/src/foreclojure/template.clj for a larger example of the style i'm suggesting |
| 17:59 | sdegutis | amalloy: that's waht I have now, but it's a really huge Hiccup template, like 100 lines or something... |
| 17:59 | amalloy | i mean, you can break that up into some smaller functions, and that helps a little |
| 17:59 | sdegutis | Good thinking. I may do that. |
| 18:00 | amalloy | but some of it is just like...i dunno, you play with fire, you get burned. webdev, not even once |
| 18:00 | sdegutis | I've been cleaning up my routing code a bit, and this just felt like kind of an anti-pattern for some reason. |
| 18:01 | sdegutis | So I wanted to clean it up, because there's basically (ns myapp.web.template) which has (defn template [& body] ...) and that's all the file is, but it's like 102 lines long or something. |
| 18:01 | sdegutis | And it just felt like this thing floating out there by itself, being weird and not fitting in anywhere. |
| 18:02 | sdegutis | Yet, like, 30 other namespaces all depend on it so that they can just call (template (view/whatever)) as the end-result of the route |
| 18:02 | sdegutis | I can't quite put my finger on why that feels weird, but it just does... |
| 18:02 | sdegutis | Does that make sense? |
| 18:02 | amalloy | i find it hard to believe you can do much with just [& body] params |
| 18:03 | amalloy | add some real named params, at least one "config" map, to let your callers specialize how the template is produced for them |
| 18:12 | macrolicious | amalloy: my apologies for the video link… the preceding chat gave context (and hence it was an analogy to my learning clojure) but my bad. |
| 18:16 | sdegutis | amalloy: Oh right it also takes the request, so it can find out if you're signed in and access the signed in user if so. |
| 18:22 | ridcully | so sister mary can use hiccup for input |
| 18:23 | sdegutis | ridcully: who? what? huh? |
| 18:25 | amalloy | sister mary gets some kind of Sanity bonus |
| 19:40 | sdegutis | hi |
| 19:46 | sdegutis | hi justin_smith |
| 19:49 | justin_smith | sdegutis: how do I do undo-tree but only apply changes inside the region? |
| 19:49 | justin_smith | I am fearing it is impossible |
| 19:49 | sdegutis | justin_smith: no this is patrick |
| 19:49 | sdegutis | justin_smith: anyway yeah I never tried that |
| 19:50 | sdegutis | justin_smith: usually I just undo until I find the change I want, copy it, then redo until I'm where I started, and paste it |
| 19:50 | justin_smith | yeah yeah OK |
| 19:51 | sdegutis | man we're gonna watch o brother tonight havent seen that in years so excited also unbreakable its a pretty good plot personally i think |
| 20:13 | sdegutis | amalloy: do you do what justin_smith does with components and router? or how do you tackel that? |
| 20:13 | amalloy | i lack the context to answer that question |
| 20:15 | sdegutis | ok |
| 20:19 | sdegutis | amalloy: like heres what i mean.. ok look.. you have a router, and you have components, and a system component, and presumably the router is one of the components, but it also has asccess to all the other components or some not all, or all. and how do you get the routes to have hold of those other components? lets say you're using compojure for e.g. what do you usually do to solve this? |
| 20:19 | sdegutis | it's the same question i asked justin_smith earlier in here publicly btw fwiw fyi |
| 20:19 | amalloy | i haven't really built a webserver of any size since component became popular |
| 20:20 | sdegutis | touché |
| 20:20 | amalloy | and i don't know what you mean by a router either |
| 20:20 | amalloy | so i am probably the wrong person to answer |
| 20:21 | sdegutis | hey thats ok amalloy dont feel bad |
| 21:41 | TimMc | I assume it's a question about dependency management within a web server. |
| 21:42 | binjured | how can i use a macro to generate a type-hinted function? i'm running into an issue during compilation where, e.g., [^java.lang.Integer foo] is being evaluated as [gf__^java.lang.Integer__46045] which, surprise, is not a class |
| 21:43 | binjured | interestingly (to me), the short form [^Integer foo] works fine, assuming Integer was imported in the ns already. |
| 21:44 | binjured | macroexpand doesn't show the gensym-style name in the output, either. |
| 22:06 | TEttinger | binjured: interesting. I think it may be because that's in a syntax quote |
| 22:07 | TEttinger | ,`(fn [^java.lang.Integer x] (+ x 1)) |
| 22:07 | clojurebot | (clojure.core/fn [sandbox/x] (clojure.core/+ sandbox/x 1)) |
| 22:07 | TEttinger | ,``(fn [^java.lang.Integer x] (+ x 1)) |
| 22:07 | clojurebot | (clojure.core/seq (clojure.core/concat (clojure.core/list (quote clojure.core/fn)) (clojure.core/list (clojure.core/apply clojure.core/vector (clojure.core/seq (clojure.core/concat (clojure.core/list (clojure.core/with-meta (quote sandbox/x) (clojure.core/apply clojure.core/hash-map (clojure.core/seq #)))))))) (clojure.core/list (clojure.core/seq (clojure.core/concat (clojure.core/list (quote cloj... |
| 22:07 | binjured | scary! :D |
| 22:08 | TEttinger | do you have the full macro to put ob refheap or gist? |
| 22:08 | TEttinger | on |
| 22:09 | binjured | not at the moment, currently seeing if i can get it to cooperate by using with-meta instead of just literal symbols |
| 22:15 | binjured | TEttinger: looks like using with-meta fixed it. |
| 22:15 | TEttinger | interesting |
| 22:16 | binjured | in unrelated news, the `meta` function seems to throw CIDER into an infinite loop, which is interesting! |
| 22:16 | amalloy | binjured, TEttinger: http://stackoverflow.com/q/11919602/625403 |
| 22:20 | binjured | amalloy: that doesn't really explain it, though. i wasn't evaluating [^java.lang.Integer foo] i was emiting it; that question is only really addressing the mistake of evaluating forms in a macro, hence all the namespace pollution. |
| 22:21 | binjured | it also doesn't explain why emiting [^Integer foo] works fine, unless i'm missing something |
| 22:23 | amalloy | i don't think you are correct about what you're emitting. what code are you actually running? |
| 22:24 | cfleming | marcfontaine: Sadly no structural search for Clojure code, although it would certainly be nice |
| 22:28 | binjured | amalloy: i basically just replaced `[~(symbol (str "^" thing)) ...] with `[~(with-meta ... {:tag thing})] and it worked fine after that. |
| 22:28 | amalloy | well yeah, because symbol str is nonsense |
| 22:28 | amalloy | like it's fine, and it generates something that *prints like* attaching metadata, but is in fact jsut a symbol with an awful name |
| 22:29 | binjured | well then, i was tricked by macroexpand! ;) |
| 23:22 | rhg135 | Ah, ya gotta love the symbol /keyword fns |
| 23:23 | rhg135 | ,(symbol "1") |
| 23:23 | clojurebot | 1 |