Fork me on GitHub
#clojure
<
2015-12-20
>
trancehime04:12:21

can i just use lein uberjar to deploy a clj/cljs app based on immutant 2

arrdem05:12:45

Anyone know of a re-cond macro in a library somewhere? Looking thinking of (re-cond [bindings regexp form]*) implemented as chained if-lets on the regexp match and thought I'd take a minute to check for prior art.

cjmurphy05:12:42

@trancehime: I've never used lein uberjar but my understanding is that it will give you a self contained server with all your dependencies in it, that you can easily try out as long as you know the url your web application is served from. You just need to find the jar file produced and run it with java -jar ..., I would think.

trancehime06:12:54

Hmm... 'Cause I'm trying to figure out a way to deploy the immutant app on a server. I remember I have 2 options, either uberjar or to deploy to Wildfly.

trancehime06:12:15

I never actually used Wildfly before so I am trying to know how to configure it.

cjmurphy06:12:24

I would not use uberjar to deploy to an existing web server (Wildfly).

cjmurphy06:12:50

You need a jar that just has your webapp.

cjmurphy06:12:23

Then all the other jars have to be in the lib directory of the web container.

cjmurphy06:12:34

lein install - try that - then use a zip program to see what's in the jar file produced.

cjmurphy06:12:17

Actually the jar produced does not need to refer to the jars it needs in any way. Just normal code references is all that's required.

cjmurphy06:12:32

Is there a webapps directory?

cjmurphy06:12:00

If it is anything like jetty / tomcat under your partic webapp directory there will (need to) be a WEB-INF/lib directory.

cjmurphy06:12:31

Wildfly should come with at least one example webapp - check its structure.

cjmurphy06:12:26

lein install is more for making your own library so I'm not 100% that's the right lein command, but it's better than uberjar.

cjmurphy06:12:21

I think lein immutant war is what you want. The resultant jar there will be worth looking into with 7-zip (or whatever you use), because iirc you will see the whole structure - WEB-INF directory etc. A 'war' is just a jar 'jar' made for deployment to a web server - so exactly what you want.

trancehime06:12:54

Yeah that should be if I'm deploying it to WildFly

trancehime06:12:09

but I don't know how to configure WildFly just yet =x

cjmurphy07:12:05

If it is like the others just install it then put the war in the webapps folder and restart WildFly. Know where WildFly's log file is for stack traces. However open the webapp in the browser first to see if you even need to look in the log file.

trancehime07:12:42

Well it's less the actual deployment and more virtual host/URL setups since I don't usually do that stuff

jaen08:12:55

@trancehime: anything in particular you having problems with wrt immutant deployment?

trancehime08:12:44

It's not really a problem i've run into so much as it is "I need to deploy this app ASAP instead of running locally"

jaen08:12:12

Ah, I see. Any particular requirements like SSL?

trancehime08:12:44

SSL etc. isn't a pressing requirement at the moment

jaen08:12:42

How do you do migrations?

jaen08:12:52

(that's one thing I had problems with depending on the env)

jaen08:12:02

And also, what do you use to manage environment? Environ?

jaen08:12:49

And migrations?

jaen08:12:49

Hmm, okay, we'll see. Maybe it won't have problems ragtime/joplin had.

jaen08:12:31

Anyway, you create the jar with the boot/lein plugin. IIRC you don't need to AOT, but you need to include sources.

jaen08:12:35

When you have that war

jaen08:12:27

You just download WildFly from http://download.jboss.org/wildfly/9.0.2.Final/wildfly-9.0.2.Final.tar.gz, unzip it and run ./bin/standalone.sh -c standalone-full.xml from the directory.

jaen08:12:08

When it's up and running you just shove the war into ./standalone/deployments/ and that's it.

jaen08:12:23

Unless there will be some problems with things like migrations that is.

trancehime08:12:34

OK, but to be sure, my main issue isn't exactly clojure related

trancehime08:12:43

it's more how do i configure urls

trancehime08:12:59

since I will probably be naming the war file as ROOT.war

jaen08:12:51

You specify the context path in the war task

jaen08:12:00

It creates an appropriate XML file for jBoss in the archive

jaen08:12:57

/WEB-INF/jboss-web.xml inside the war if you're curious.

trancehime08:12:57

i think there is a miscommunication here

jaen08:12:06

Ok, there could be.

trancehime08:12:31

with my other clojure app which I have to deploy into Tomcat, there's already some url configured

trancehime08:12:05

so if the context path of the app was path i would access the app via

trancehime08:12:21

i don't really have much experience with configuring that kind of thing

jaen08:12:38

Yeah, so you would set the context path to / if you want to access it under server/, I think.

jaen08:12:10

There's also :virtual-host option to specify.

jaen08:12:36

So you will get a jboss-web.xml file looking like so:

<jboss-web>
    <virtual-host>your-virtual-host</virtual-host>
    <context-root>your-context-root</context-root>
</jboss-web>

jaen08:12:33

You don't need to touch Wildfly's configuration, this all will be done by the immutant task and Wildfly should respect it. But if I'm misuderstanding something, then sorry.

trancehime08:12:00

My question is actually server-specific, ie: how do I configure the main host path URL so that when I deploy the application on a WildFly instance I can access the app at that URL.

trancehime08:12:36

Like I said, not necessarily clojure related, so prolly don't belong here anymore, quite off-topic

trancehime08:12:23

Ah I'll figure it out, it can't be that difficult

jaen10:12:06

Huh. A quick google around and it looks like you the closest equivalent is split, but it partitions only in two halves. Interesting why they omitted a function to split into multiple sublists.

borkdude10:12:23

It seems Scala doesn't have a good answer to this in the standard library

onetom14:12:04

Are there any major drawbacks of interleaving the midje specs with the implementation? I see a few upsides, like 1. I don't have to jump between implementation and test files constantly 2. I don't have to have twice as many files in my directory tree (also repeating the same namespace segments)

borkdude14:12:07

I wrote this Scala solution (because I'm learning it right now) and then tried the Clojure solution of @bhauman. Not only is it shorter, it's much faster. I wonder what's up with that: https://gist.github.com/borkdude/3d080f43c2097ddf26b8

borkdude14:12:28

maybe because the Clojure version doesn't retain many objects in memory at once?

jaen14:12:00

Well, that sounds plausible - I think Scala's lists and function on interables are strict by default, whereas Clojure's are lazy. Maybe changing list to a stream would help?

borkdude15:12:42

I think I found the culprit: if I replace the intermediate strings with a StringBuilder in Scala, it is as fast. Could it be the Clojure version 'magically' compiles to StringBuilders in Java?

borkdude15:12:48

if that isn't the case I can't explain it

borkdude15:12:06

maybe the JIT is so clever, it can recognize the loop on strings going in and out?

jaen15:12:12

Well, in Clojure you only concatenate the string once.

jaen15:12:25

When you apply str onto the seq.

jaen15:12:37

So I guess that could be the underlying issue indeed.

borkdude15:12:59

no magic then simple_smile

borkdude15:12:17

what is still magic is the conciseness of the clojure solution simple_smile

jaen15:12:32

Yeah, true, it's pretty concise.

borkdude15:12:50

I missed two critical functions for this in Scala: partition-by and iterate

jaen15:12:40

Well, I don't think you need iterate explicitly, you can just map over an infinite stream just as well - http://www.scala-lang.org/api/2.10.2/index.html#scala.collection.immutable.Stream

jaen15:12:10

But yeah, absence of partition-by is a bit of a bummer. Curious what's the rationale.

borkdude15:12:09

Took me a while, but now it's fast and reasonable... learned some new things today. simple_smile https://www.reddit.com/r/adventofcode/comments/3w6h3m/day_10_solutions/cy5jdse

borkdude15:12:33

(sorry for polluting this space with non-Clojure code)

jindrichm16:12:28

Hi, can you create a Prismatic Schema for a vector that contains at least 1 s/Int? I tried [(s/optional s/Any "head") (s/one s/Int "integer") (s/optional s/Any "tail")], but starting with optional schema is not allowed.

gfredericks17:12:42

jindrichm: I believe so

gfredericks17:12:50

[(s/one s/Int) s/Int] might do it

jindrichm17:12:22

@gfredericks: Then the vector needs to start with s/Int.

gfredericks17:12:27

seancorfield: do you have any thoughts on the relationship between clj-time and the new java.time classes? e.g., could clj-time expand to support them, or would a parallel library be appropriate?

gfredericks17:12:46

jindrichm: oh you mean it can have various other things throughout as long as there's an integer?

jindrichm17:12:25

Yes, vector of anything containing at least 1 s/Int at whatever position.

gfredericks17:12:41

that's a pretty weird schema; my guess is only s/pred could handle that

charliegriefer17:12:04

Maybe more appropriate for #C053AK3F9, but given two maps with identical keys in both, I want to return kv pairs where the values differ. Is clojure.data/diff a reasonable solution there?

charliegriefer17:12:41

or is there a solution somewhere in clojure.core that I’m not seeing?

jindrichm17:12:05

@gfredericks: Yes, I've made it up to have a simpler example. Actually, I need to check a vector that contains maps, of which at least 1 needs to match a specific schema.

gfredericks17:12:08

(keep (fn [k] (when (not= (m1 k) (m2 k)) [k (m1 k) (m2 k)])) (keys m1))

gfredericks17:12:24

charliegriefer: something like ☝️ that isn't too hard

charliegriefer17:12:47

@gfredericks: thank you. will play around with that.

gfredericks17:12:57

jindrichm: same thoughts as the simple one

jindrichm17:12:54

OK, I'll try to capture that restriction with s/pred.

jindrichm17:12:15

I've come up with (s/both (s/pred (partial some integer?)) [s/Any]), but s/both is deprected and its translation to s/conditional is unclear to me.

gfredericks17:12:56

that's basically (s/pred (fn [xs] (and vector? xs) (some integer? xs))) though

jindrichm17:12:35

Yes, that may be simpler.

gfredericks17:12:45

but I can see why you'd want it the other way and am still confused about s/conditional myself

jindrichm17:12:45

The benefit of the first approach is that you "stay in Schema" when possible.

amacdougall17:12:40

As I develop this REST API, I'm noticing a lot of common functions between resource types. I had been putting them in type-specific namespaces: (video/create!), (user/create!), and so on. I'm starting to think that one of Clojure's OO-like features would be nice to use here. Protocols and records? Or if I don't need true polymorphism—that is, I always know the data type I'm working on—maybe I should stick with my namespaced functions? I'm never going to be calling (create! <some-map>) and not know/care what type of thing I'm trying to create, after all.

mikera17:12:55

I recommend keeping functions that create / deal with different types of things separate

mikera17:12:23

protocols only really make sense if it is actually exactly the same operation (just needs to handle different argument types)

amacdougall17:12:42

Thanks. When you're new to a language, it's tempting to use all the features, even when they are not strictly appropriate.

mikera17:12:11

This is especially true for creation

mikera17:12:54

e.g. much better have "create-user" and "create-video" functions than a single "create" function with really complex arguments

mikera17:12:03

also makes it easier to verify such functions with tests and/or tools like prismatic schema

amacdougall17:12:51

True. In my case, 100% of activity will go through the API, so I have Schema set up on my routes, enforcing arguments/returns, but I'm not using it in the business logic. This saves me time in the short run... any opinions on the long run?

seancorfield19:12:41

@gfredericks: re: clj-time -- to use the new Java time stuff requires the new Java version, whereas clj-time runs on several Java versions. Not sure how much of a concern that is in the real world but that would be my first reaction. Does the Java time stuff bring any real benefits over using Joda Time?

lfn319:12:20

@timvisher: There’s https://github.com/yeller/laboratory I haven’t had any production use of it, but I assume @tcrayford has.

trinity19:12:24

anyone know of a clojure-equivalent to https://github.com/dmendel/bindata (used for parsing structured binary data)? i've looked at gloss, buffy, and binary but none seem to support the onlyif specification that bindata has. buffy comes closest w dynamic frames.

gfredericks20:12:22

seancorfield: you could do compile-time conditionals to preserve backwards compatibility; I don't know of any direct benefits, I just get antsy with "if everything's going to move to this new API anyhow I'd like to do it sooner"

seancorfield20:12:34

We rely on clj-time heavily at work, we're on Java 8 but I have no desire to switch from Joda Time to Java 8 just "because". I'd worry about changing the behavior of clj-time.

seancorfield20:12:15

I can see some argument for modifying the coercions to/from java.util.Date to use the new Java API but even there I don't really see a benefit.

seancorfield20:12:28

It just sounds like change for change's sake to me.

gfredericks20:12:40

I don't think you'd change j.u.Date, since that still exists

gfredericks20:12:53

you'd add j.t.Instant as a new thing to coerce to/from

seancorfield20:12:51

Feel free to send a PR with an enhancement then, to add coercion support for the new types.

gfredericks20:12:26

I wonder if it could also participate in the other protocols cleanly

seancorfield20:12:44

As long as it still works on older JVMs and older Clojure versions -- and is purely additive -- I'm sure the clj-time maintainers will be happy to accept it.

gfredericks20:12:00

seancorfield: cool, thanks for the discussion

borkdude20:12:41

I was thinking, would it make sense to have persistent immutable strings on the JVM instead of just immutable?

borkdude20:12:07

I ran into this problem with a 'reduce' on a lot of intermediate strings. StringBuffer was the answer, but I think persistent (shared) strings would have saved me there also

jaen20:12:37

That's interesting, but wouldn't that loose easy Java interop?

borkdude20:12:57

There might be a good reason why they didn't implement it like this

jaen20:12:10

I suppose they would share some downsides of ropes - https://en.wikipedia.org/wiki/Rope_(data_structure)

gfredericks23:12:02

help I think I might be about to write a data structure that has indexes of things