#clojure log - Feb 09 2016

The Joy of Clojure
Main Clojure site
Google Group
IRC
List of all logged dates

0: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?

0:45 I was thinking I might be able to leverage core.logic somehow, but I'm not sure

0:46 specifically I'm thinking that each constraint would be on the form `{:f some-fn :vars {:y [:path :to :y :in :schema] ...}}`

4: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

4:42 wombawomba: other than that, a simple solution comes to my mind - something like "combined generators" - akin to combined parsers

4:45 wombawomba: you can generate the datastructure level-by-level, using some grammar to describe it, like the L-ssytems

4:54 jonathanj: does clojure.java.io/copy disturb the input?

4:55 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)

4:55 noncom: jonathanj: disturb the input?

4:55 jonathanj: there is a possibility the stream is not rewindable, how do i get two copies?

4:56 noncom: ummm idk, why not just work with streams?

4:56 copy is just a quick function for an easy task.. not sure it can do what you're asking..

4:56 jonathanj: sorry, i don't understand what you're asking

4:56 i have one stream, i need to do two things with it

4:56 noncom: <jonathanj> does clojure.java.io/copy disturb the input?

4:56 ^^ disturb

4:57 jonathanj: if at all possible i'd like to avoid trying to store all the content in memory as byte[]

4: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

4:58 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

4:59 not sure if you can coerce (copy) to do anything else than just copy

4:59 jonathanj: even without copy, is it possibly to clone the original stream somehow?

5:00 noncom: jonathanj: depends on what you mean by "clone"

5:00 sure, you can read data and do two different tasks with it

5:01 the stream is read in chunks, so you get these chunks on every "read"

5:01 you always read a stream into a buffer of a fixed size

5:01 does it make any sense to you?

5:02 jonathanj: not really, no

5:02 noncom: what is your task, exactly?

5:02 jonathanj: the two tasks are: render an XML document (with flying saucer) and parse the XML document to extract information from it

5:03 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

5:03 noncom: so, you 1) read the xml doc from a file, 2) send it to the renderer, 3) extract the info from it?

5:03 jonathanj: that's the point: "no how will it help you" :)

5:03 jonathanj: you simply need to read it all in order to really process it

5:04 and when you've read it all, there you have it - you can run several tasks on that data

5:05 i don't really see any problem here unless the xml is really big

5:05 but then, rendering it would also be pointless

5:06 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

5:06 MasseR: Streaming xml?

5:06 It's a thing

5:07 But you probably need to have a schema of the document first

5:21 jonathanj: if i'm using clojure.data.xml, how can i produce a org.w3c.dom.Document?

6:08 Kah0ona: cd /#clojure-beginners

6:08 lol

6:09 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

6:11 jonathanj: Kah0ona: maybe https://github.com/weavejester/lein-ring might be helpful to you?

6:12 Kah0ona: ok so `lein ring server` should already do the trick?

6:13 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?

6:13 jonathanj: Assuming that auto-reload? is enabled and the code you're changing is in reload-paths

6:13 Kah0ona: okay

6:13 and then it can be inside (defroutes ) and it will work?

6: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.

6: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?

6:14 or will `lein ring server` provide a repl as well

6: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

6:16 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

6:17 Kah0ona: okay so then it would be:

6:17 start lein ring server with nrepl option,

6:17 connect to it from a different lein repl session with :connect ..... added?

6: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

6:17 Kah0ona: alright, i just noticed i dont have auto-reload? is there

6:17 jonathanj: Kah0ona: :auto-reload? (according to the docs) is true by default for a dev environment

6:18 Kah0ona: hmmm

6:18 okay

6:18 jonathanj: you can try explicitly setting it to true but the docs indicate that shouldn't be necessary

6:20 Kah0ona: yeah, okay thanks for your info. will try some stuff and try to make it work with lein-ring

6:21 jonathanj: perhaps try minimizing your code while you're debugging it

6:21 by removing middleware and such, or creating a new ring application with the simplest possible code

6:22 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.

7:14 Kah0ona: ok it works now, thanks!

8: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

8:09 ?

8:09 * ashnur has no idea what he is doing :D

8:11 ashnur: i took some edn i generated and put it into some weird thing called "ankha"

9:17 lxsameer: what does ^{:a 2} means ? (^ part)

9:20 opqdonut: it means "attach metadata to the next expression"

9:20 metadata is used for e.g. type hints, doc strings

9:21 ,(meta #'map)

9: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...

9:22 opqdonut: ,(meta (read-string "^{:a 2} foo"))

9:22 clojurebot: {:a 2}

9:53 fatsaucisson: Hi there

9:54 noncom: fatsaucisson: hi

9:55 ashnur: depends on what you're actually doing

9:55 if you don't eval on read, you can treat it as a symbol..?

9: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

9:56 fatsaucisson: I've issues with a macro I'm writing, can I ask that here or this a totally another purpose chan ?

9:57 pbx: sounds perfect for this channel fatsaucisson

9: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 example

10:02 ashnur: hmmmm

10:02 fatsaucisson: refheap (defmacro command

10:02 [name input suite & forms]

10:02 `(when (.startsWith ~input ~name)

10:02 (let [~suite (string/replace-first ~input (re-pattern ~name) "")]

10:02 ~@forms)))

10:03 noncom: fatsaucisson: it's https://www.refheap.com/ XD

10:03 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 and what is the stack trace?

10:05 fatsaucisson: https://www.refheap.com/114608

10:06 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 ,("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 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 well i copy/past to quick there is error in the refhead

10:16 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 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 luma what do you think?

10:23 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 it's call your macro with a macro thing :)

10:25 luma: yes, i mean 'text, the symbol text

10:26 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 right?

10:26 clojurebot: right is not wrong

10:26 luma: you can

10:27 you can't

10:27 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 it will be at runtime

10:28 fatsaucisson: Yeah at runtime

10:29 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 let me take another look at it

10:30 fatsaucisson: in fact after a macroexpansion errorcallback become goodcallback

10:31 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 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 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 is there an other way to declare it ?

10:37 luma: you don't need to "declare" it

10:38 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 you don't want to do that here

10:40 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 I don't get it

10:42 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 that's not the case with goodcallback

10:46 ok

10:46 so now it works properly

10:46 and I have no idea why

10:46 how bizarre

10:57 well

10:59 it seems that simplifying the field accessed in the args worked (just picked text, nick, target, host)

10:59 whereas when i bind all the fields that somehow breaks

10:59 that's really strange

11:00 no

11:00 ok

11:00 got it

11:00 there was a field named command

11:00

11:01 wow sorry for getting you involved in a mistake of that level

11:10 Ok, just another macro question

11:13 i have my command macro, now i want to write a macro doing something like this https://www.refheap.com/114614

11:14 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 Thx

11:49 python476: hi there

11:49 fatsaucisson: I'm leaving, bye. Have a nice day.

11:50 python476 : Hi

11:50 python476: I'm struggling hard between cljs and dom collections

11:50 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 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 TristeFigure: see also fn vs. fn*, same scenario

13:05 ,(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 I am new to clojure and I'm struggling with a need that comes very often

13:26 suppose we have (defn create-cell [color x y] {:color color :x x :y y})

13:27 and a vector of coord under that form [ [1 2] [10 20] [5 9] ]

13:27 what is a good way to create 3 cells with :color fixed to "blue" ?

13:27 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 ekryyn: no

13:32 that is false

13:32 ,(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 mmastic: core.async is 100% imperative, it isn't even fp

13:34 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 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 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 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 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 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 But in practice, then you have a chicken/egg problem.

13:47 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 because all the routing / top level mechanisms have access to the sending mechanisms of all the others

13:49 because the sending facility is separated and doesn't need access to anything else

13:49 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 split it and pull it together at the top

13:50 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 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 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 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 actually no "etc" those are literally the only two

13:58 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 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 justin_smith: hmm

14:04 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 justin_smith: ah

14:05 justin_smith: haha

14:05 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 free life advice

14:13 m1dnight_: Would a library for giphy be something reasonable to publish on Clojars?

14:13 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 It's something trivial but I figured why not

14:14 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 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 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 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 you need to tune the jce though I think

15:32 not usually

15:33 Usually some combination of SSLContext.getInstance() w/ https://docs.oracle.com/javase/7/docs/technotes/guides/security/StandardNames.html#SSLContext

15:36 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 xemdetia: i've seen mention of a `https.protocols` system property

15:37 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 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 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 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 lots of questions

15:47 timvisher: xemdetia: lots of questions indeed.

15:47 java version "1.7.0_95"

15:47 OpenJDK Runtime Environment (IcedTea 2.6.4) (7u95-2.6.4-0ubuntu0.14.04.1)

15:47 OpenJDK 64-Bit Server VM (build 24.95-b01, mixed mode)

15:47 i honestly don't know what the default JCE driver is

15:47 xemdetia: and you are using clj-http right

15:52 I mean I don't know how the org.apache.http.conn.ssl is different than other tls implementations

15:52 not usually my tool of choice

15:52 did you check to see if the remote can even do tls 1.1 or tls 1.2?

15:52 how did you scan the port?

15:53 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 they are turning of 1.0 soon

15:54 and we're discovering that our client appears to be unable to speak anything else

15:54 xemdetia: this is common

15:54 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 here you go

15:54 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 so for instance post POODLE, "SSL" was auto-corrected to "TLS" in recent java's

15:56 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 it looks like it accepts a set

15:57 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 switching it to just "TLS" may permit it to talk TLSv1, TLSv1.1, and TLSv1.2; most things work like that

15:57 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 in that .clj

15:58 timvisher: xemdetia: yep

15:58 thanks this was extremely helpful

15:58 (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 this seems to be my case

16:04 justin_smith: xemdetia: oh, I am in that position too!

16:05 I'm just not as far along the path to competence

16:10 xemdetia: I suppose

16:10 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 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 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 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 ok

17:30 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 but one step at a time, of course :)

17:31 macrolicious: okey dokey

17:32 I'm following tutorials (slowly) then decided to play around in the repl, with predictable results… back to the tutorials ;-)

17:33 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 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 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 actually I have not done that kind of templating in a while, but that's what I did back then

17:46 sdegutis: with hiccup you can do (assoc-in page-skeleton [magic spot here] content)

17:46 same concept

17:47 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 (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 if you ever take one as input, lose 8 Sanity

17:52 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 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 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 And it just felt like this thing floating out there by itself, being weird and not fitting in anywhere.

18:02 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 I can't quite put my finger on why that feels weird, but it just does...

18:02 Does that make sense?

18:02 amalloy: i find it hard to believe you can do much with just [& body] params

18:03 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 hi justin_smith

19:49 justin_smith: sdegutis: how do I do undo-tree but only apply changes inside the region?

19:49 I am fearing it is impossible

19:49 sdegutis: justin_smith: no this is patrick

19:49 justin_smith: anyway yeah I never tried that

19:50 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 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 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 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 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 interestingly (to me), the short form [^Integer foo] works fine, assuming Integer was imported in the ns already.

21:44 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 ,`(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 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 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 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 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 ,(symbol "1")

23:23 clojurebot: 1

Logging service provided by n01se.net