Fork me on GitHub
#clojure
<
2018-08-09
>
didibus00:08:49

Can you override a defmethod only within a form? Similar to how with-redefs can redef a normal function only within its form?

lwhorton00:08:59

is there a less-icky way to say “if this isn’t in a seq, put it in one” without flatten?

(flatten (conj [] x))
that just smells off to me

hiredman00:08:56

that is terrible

🎉 4
hiredman00:08:06

(if (seq? x) x [x])

hiredman00:08:12

never do that other thing

hiredman00:08:43

(seq? can be seq?, coll?, sequential?, your pick)

hiredman00:08:57

(cond-> x (not (seq? x)) list) maybe if you feel fancy

noisesmith00:08:03

the real fix is to never have something that sometimes returns a collection and sometimes doesn't; as a consumer of a bad api you don't always get to make that choice though

👍 12
lwhorton00:08:57

yea past-me is really bad at writing apis 😞

seancorfield00:08:58

(I have a few of those at work, in code written years ago, and I shudder every time I have to interact with those functions)

didibus00:08:01

I ended up writing my own using get-method remove-method and defmethod

henrik06:08:34

Is there anything like lein-ancient, compatible with deps.edn? https://github.com/xsc/lein-ancient

orestis13:08:04

Any love here for AWS ElasticBeanStalk? I just managed to set a Java project up, and it seems to be working nicely (as in, I don’t have to worry about much, just upload a new uberjar and everything seems to be going well). Any horror stories I should know about?

mgrbyte13:08:09

I'm happy with it. I'd rather not create an uberjar but that aside :thumbsup:

dominicm13:08:43

We had a lot of pain trying to debug things, hard to get lots out.

orestis14:08:28

Yeah that’s my worry, but I’m not sure how it differs from other clouds. Did you use CloudWatch or whatever that’s called?

dominicm14:08:08

We didn't use it with ELB.

dominicm14:08:58

We do use CloudWatch with EC2/ASG though

logistark14:08:59

Too slow to deploy

orestis14:08:06

So what are alternatives? It is kinda slow to deploy but if you use big instances it takes a minute or so and it does rolling deploys, health checks and so on.

orestis14:08:56

I started testing it out with a t2.micro and that was painful, but with an m5.large deploys and conf. changes go fast.

dominicm14:08:38

@U7PBP4UVA 1 minute? Do you have a load balancer in front of that?

orestis14:08:35

Yes, using the App load balancer.

orestis14:08:25

I only spent one day trying to piece everything together using a toy app, so I’d have to do something bigger to see what it looks like.

orestis14:08:02

Also, region was London.

dominicm14:08:28

I suppose with EBS rolling deploys aren't mutating in place, it's spinning up a new one and then async killing old ones.

dominicm14:08:44

but that would be blue/green I think

orestis14:08:12

Yeah, I’m not quite sure how that worked, there are a few strategies there.

orestis14:08:40

But yes, the policy I’m looking is either rolling or rolling+1

dominicm15:08:57

with codedeploy, it spends 6m to block traffic from alb->particular ec2 instance

orestis15:08:38

I don’t think my workflow went through code deploy. I was manually uploading a prebuilt jar to the console.

orestis15:08:08

And also had no traffic...

dominicm15:08:24

Sure, but I think that's a general pattern. Terraform does the same for blue/green deploys.

sobel15:08:15

So, I built an uberjar with lein, and I've stepped on a static initializer based problem

sobel15:08:40

when i "lein run" the problematic static initializer is not run unless I execute the codepath that depends on it

sobel15:08:34

when i "java -jar" the static initializer runs, and it's a problem for some codepaths that do not depend on it

sobel15:08:59

(surprise, it's SOAP libraries)

orestis15:08:13

So how are people deploying web apps these days?

dominicm15:08:01

CodeDeploy to EC2 instances in AutoScaling Groups behind a ALB. All created via terraform. Uberjar generated with pack.alpha

orestis15:08:54

I’d love to have a sample terraform file. Any good resources out there?

orestis15:08:23

Also, is this also integrated with some kind of CI/CD system?

dominicm15:08:35

Cloudposse have a lot of great modules, combined with our rock ami it's fairly distinct.

dominicm15:08:10

We can't do CD for compliance reasons - releases need sign off. But it's on my list for dev, just lower down because it's not so useful to us.

dominicm15:08:30

Generally CI/CD doesn't seem so important, you can run tests locally and shout if someone breaks them.

orestis15:08:54

I’d love to have a sample terraform file. Any good resources out there?

bwstearns15:08:43

Trying to remember a blog or Hickey talk/essay but my google skills are failing me. It basically describes clojure as a good language to use in long running systems with requirements that change over time and have to deal with messy human inputs as opposed to things like compilers that generally have a more fixed idea of the world and more slowly changing requirements etc. Does anyone know the post?

ghadi16:08:24

it was his keynote at the Conj last year @bwstearns

bwstearns16:08:22

I couldn’t quite remember the term “situated program”

lwhorton18:08:20

am i doing something wrong here reading in env vars at startup?

(def config (read-string (or (System/getenv "MY_ENV_FOO") "5")))
...
(with-redefs [some.ns/sym config]
  (run-app)))
I keep getting a bad cast- java.lang.String cannot be cast to clojure.lang.IPersistentMap

seancorfield18:08:49

@lwhorton First off, I'd advise against using def for something that interacts with the environment since it will run whenever the namespace is loaded (e.g., at compile time). Second, that error sounds like something expects some.ns/sym to resolve to a hash map?

seancorfield18:08:11

The stack trace should tell you which line of code is complaining about that.

seancorfield18:08:58

(oh, and from a security standpoint, don't use read-string on arbitrary external data -- it can be made to run arbitrary code and thus "hack" your application!)

seancorfield18:08:07

Use something like Long/parseLong if you just want to safely turn a string into an integer.

lwhorton18:08:40

what do you use instead of a def? just inline the System/getenv and don’t def it?

lwhorton18:08:04

ah… i see the other problem now- i’m using with-redefs which is a macro. so i’m mixing my compile time + runtime. thanks for the info @seancorfield

royaldark20:08:33

Is it a known issue that the spec for valid Clojure symbols (https://clojure.org/reference/reader#_symbols) is wildly inaccurate? The EDN spec if correspondingly wrong (https://github.com/edn-format/edn#symbols), which is the context in which I encountered the issue. It seems essentially any Unicode character not otherwise reserved can be used, including some insane ones like \0:

royaldark20:08:43

=> (type (clojure.edn/read-string "µ"))
clojure.lang.Symbol
=> (type (clojure.edn/read-string "🔥"))
clojure.lang.Symbol
=> (type (clojure.edn/read-string "\0"))
clojure.lang.Symbol

royaldark20:08:12

As someone implementing an EDN parser, this discrepancy is pretty confusing

polymeris21:08:58

> A symbol can contain one or more non-repeating ':'s. what does non-repeating mean? non-consecutive?

john21:08:06

There's a lot in the specs that the implementations don't validate. But if you go outside the spec, don't be surprised if future validation tools throw errors at you.

royaldark21:08:20

So I guess if you're implementing an EDN parser in another language, you have two options: either follow the spec, and break on certain EDN that works with the official parser. Or try to match the official parser, but know you're "wrong" and it might break in the future.

royaldark21:08:09

I love EDN, think it's a great data format, but that makes it very hard to justify using for any serious cross-language project

john21:08:08

If you're building inbound validation into your implementation, you should probably implement to the spec.

ghadi21:08:36

if you're looking for cross-language EDN semantics, it's already built: Transit

royaldark21:08:56

Transit is great, but not if you want human readability

john21:08:18

As a lib author, I wouldn't worry as much about breaking on certain EDN that happens to work with the official parser. The core stuff has to be a little more permissive for historical reasons. And perhaps some performance reasons. But a stricter implementation would probably be welcome by a lot of folks.

john21:08:40

@polymeris Yes. But the CLJS reader doesn't catch that one

andy.fingerhut22:08:55

It isn't clear to me what might break in the future if you match the "official parser" behavior when reading. As far as I recall, at least, the English spec is strictly more constrained in what it allows as compared to the official parser.

andy.fingerhut22:08:10

Agreed that if you write code that generates EDN that is outside the constraints of a future more-strict-parser, that more-strict-parser will not accept such files.

royaldark22:08:49

My point is that a spec is only as useful as its most popular implementation. If clojure.edn can generate, and parse, EDN data with symbols outside the defined spec, what is the purpose of the spec? A user could justifiably say "I made this EDN file using Clojure itself - why can't your tool read it?" and "the spec says so" wouldn't be a satisfying answer

royaldark22:08:48

Note that the Clojure reader docs don't even cover all the symbol characters used in clojure.core (!!!) - < and > are definitely missing, maybe more

royaldark22:08:50

I have discovered this issue working with syntax highlighters in the past too where allowable-but-non-spec-conformant symbol characters were syntax highlighted incorrectly or threw errors

andy.fingerhut22:08:37

You can vote on this issue if you are interested in maybe seeing tighter docs on this topic: https://dev.clojure.org/jira/browse/CLJ-1527 Some of the description and comments on that issue list some of the things you mention, and perhaps others you haven't seen yet.

andy.fingerhut22:08:42

If you want tight specs with sharp edges for "in" or "out" on every question, Clojure and EDN are not currently the kind of place where those abound.

andy.fingerhut22:08:23

Or I guess as you point out, there are multiple tight specs (English, spec, code implementations) that do not match each other exactly.

andy.fingerhut22:08:23

Given the Clojure core team's strong emphasis on backwards compatibility, Hyrum's Law comes into play: http://www.hyrumslaw.com

royaldark23:08:17

Ah I missed that issue. Thanks for the link!

royaldark23:08:57

I think a "living spec" based on the Clojure implementation is a great approach - I just think it's misleading to have an "official" spec/documentation that doesn't line up with reality

royaldark23:08:47

Especially since the EDN spec claims a formal (i.e. BNF) specification is forthcoming (as of 4 years ago...): https://github.com/edn-format/edn#spec

andy.fingerhut23:08:53

My guess: If you implement something compatible with the current implementation, that is likely to change more slowly than the docs.

👍 4
Oliver George23:08:28

Does anyone ever switch out clojure.core for their own version eg. (ns foo (:refer-clojure :only []) (:use my-stricter-clojure.core))?

noisesmith23:08:04

I've seen some newcomers suggest the idea, I've never seen it in practice