This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2017-03-06
Channels
- # architecture (25)
- # bangalore-clj (1)
- # beginners (21)
- # boot (45)
- # cljs-dev (38)
- # clojure (272)
- # clojure-austin (7)
- # clojure-finland (7)
- # clojure-france (3)
- # clojure-italy (7)
- # clojure-japan (1)
- # clojure-russia (13)
- # clojure-spec (36)
- # clojure-uk (31)
- # clojurescript (96)
- # core-async (15)
- # cursive (16)
- # datascript (3)
- # datomic (97)
- # emacs (107)
- # hoplon (16)
- # jobs (9)
- # keechma (1)
- # luminus (1)
- # off-topic (19)
- # om (39)
- # onyx (15)
- # pedestal (3)
- # planck (22)
- # protorepl (4)
- # re-frame (20)
- # reagent (3)
- # ring-swagger (25)
- # specter (26)
- # test-check (19)
- # testing (1)
- # untangled (381)
@tbaldridge thanks
@tbaldridge Hi! pedestal is interesting framework. how to avoid repl hang out when running a server? in your latest tutorial about pedestal there was the same error in demo.
@mike1452 add join false: https://github.com/pedestal/pedestal/blob/master/samples/fast-pedestal/src/fast_pedestal/fasterjetty_service.clj#L118
@tbaldridge any numbers to back this up or is it just a conclusion from its design?
@tbaldridge thanks, it works!
when e.g. 10 msgs sent to the channel only the first 9 grouped together and the remaining 1 not
the remaining is on hold until more messages come in, the channel is not a fixed size thing that closes after 10 puts
I have a list (:a 1 :b 2 :c 3 :d 24323 :e 205829 :f 824)
What is the shortest code for transforming into a {:a 1 😛 2 :c 3 ... } map ?
(hash-map :a 1 :b 2 :c 3 :d 24323 :e 205829 :f 824)
but if you need to preserve ordering, might need sorted hash map or similar
Hi, someone linked a talk here about data driven development, I think it was about clojure, In the talk the presenter used junit or spring as an example, does someone know which one this was?
@mpenet Pedestal "bends" the rules in several areas to improve performance quite a bit. For example, compojure's routing time is O(n), and has to be due to how complex the routes are. Pedestal can be constant time if you're willing to give up some things like parameters in the route, or wildcards
@mpenet that's a theme you'll see other places in Pedestal as well, you can get better performance by switching into a mode were requests maps are "map-like" and not exactly PersistentHashMaps
If you say "map-like" you can do things like zero copy of HTTP requests, where getting a key from a request map taps directly into the HTTP buffer
The async bits scare me a bit tho, seems like there's blocking IO in go blocks in a few places
About routing, it's rarely the bottleneck of a service I guess, but faster is always better
I made the same mistakes in a framework I authored on top of jetty9 for the blocking IO in go blocks, and that becomes a real problem when number of users hitting the service is decent (fixed it in branches in emergency mode). Jetty9 provides ways to avoid these issues as well, no reason not to do it
(match a
() "1"
{:email email :ativo nil} "2"
{:email email :ativo 0} "3"
{:email email :ativo 1} "4"
:else :no-match)
the first case is an empty list, how can i get this to work?in my experiece, putting the expr inside .a [], i.e. (match [a] ...
makes things much easier
Hm, I somehow cannot find anything about Lock primitives in clojure or I don’t understand how the same result can be achieved with included concepts… Say, I temporarily want to interrupt a thread (pause a future). Is there a introduction for such things somewhere?
can someone help me understand a problem i'm having in my repl? i'm trying to get the version number of my lein project. when i fire up the repl it loads the redgenes.server
namespace, but when i run the following:
(some-> ( "project.clj") slurp clojure.edn/read-string)
i get the project.clj for.... clj-time
!
redgenes.server=> (some-> ( "project.clj") slurp clojure.edn/read-string)
(defproject clj-time/clj-time "0.11.0" :description "A date and time library for Clojure...
why isn't it picking up my project.clj?io/resource
uses the classpath
Better would be to do a def
in your project.clj
and use that (defproject fooo ~version...)
and pass it in as an env variable too
io/file
, like @rauh mentioned is probably what you want to grab a file by its path
(-> "project.clj"
😛
ah okay, thanks guys. i'm trying to build the version number of my project into my clojurescript application using lein. your suggestions worked! are functions in project.clj evaluated? i have the following in my project.clj in a build configuration:
:closure-defines {goog.DEBUG false
redgenes.core/VN (-> "project.clj" slurp read-string (nth 2))}
but cljsbuild returns
value for must be string, int, float, or bool
@joshkh It's probably nil
. But why not define it and pass it to places you need it. An example:
yup, i'm going with your suggestion of def'ing it. one last question. when i attempt to evaluate this:
(def version "3.3")
(defproject redgenes ~version ....
i get Caused by: java.lang.IllegalStateException: Attempting to call unbound fn: #'clojure.core/unquote
(thanks for the help on the newbie questions by the way)you know, maybe i'm chasing my tail. perhaps it's a problem with figwheel or cljsbuild.
The key redgenes.core/VN at (:cljsbuild :builds :min :compiler :closure-defines) has a non-conforming value:
(str "thisisatest")
It should satisfy one of: Number | NonBlankString | boolean?
{:cljsbuild
{:builds
{:min
{:compiler
{:closure-defines
{goog.DEBUG false
redgenes.core/VN (str "thisisatest")
^---- The value at key redgenes.core/VN doesn't conform
}}}}}}
i don't think i can get any more NonBlankString
than that 😉(just to sum up my misunderstandings, Lein implicitly quotes everything and that's why it's breaking)
I just came across http://dev.clojure.org/display/community/Library+Coding+Standards and am confused about "Don't unroll optional named arguments" as the example goes on to suggest that unrolled arguments are actually "good". So either the example is wrong or my understanding of what unrolling means in this context is flawed 🙂 Can somebody clarify this?
Also, the "don't unroll" rule is contradicted by both the clojure.spec
and the core.async
API so it seems a bit odd.
can't comment on what's written there, but that page might be quite old and it's been the consensus for a while now that The Clojure Way is to provide maps rather than keyword args
keyword args have the only benefit of requiring 2 less characters to type and tons of downsides
@bronsa I generally agree with you here but as mentioned in my own reply to my message above (let's maybe continue the discussion in that thread), fairly recent core libraries (`clojure.spec` and core.async
) actually exclusively use unrolled keyword args.
Yeah, that would at least explain it for clojure.spec
A rule I generally follow is: when giving a fn multiple arities, keep the same types in the same positions. Thus, if there is an optional options map, it’s almost certainly going to be at the end.
OK, so that wiki page is maybe obsolete then
same for core.async
where kw args are usually on macros like alt!
that already introduce syntax
The advice to generally order fn args from least to most variance is good though
@bronsa Right, I was thinking of alts!
and alts!!
, but maybe here they were also unrolled for symmetry with the syntax versions.
In any case, the wiki page is inconsistent here. If anyone with editing rights reads this, maybe they could fix it 🙂 Even if it hasn't been touched for 3 years, I wouldn't consider its contents obsolete. On the contrary!
I'm getting a fairly inscrutable error when I try to cider-jack-in-clojurescript
. I also get the same error if I do lein repl
, but not with lein figwheel dev
. It's on a commit that worked yesterday and stopped working. I get this error:
Compiling soul.server
2017-03-06 12:10:47.853:INFO::main: Logging initialized @1493ms
java.lang.NoClassDefFoundError: javax/servlet/http/HttpUpgradeHandler, compiling:(ring/adapter/jetty.clj:27:11)
Exception in thread "main" java.lang.NoClassDefFoundError: javax/servlet/http/HttpUpgradeHandler, compiling:(ring/adapter/jetty.clj:27:11)
The only info I can find by googling suggests that ring 1.2.1 is the cause, but I'm on 1.5.1. The project is based on the re-frame template.
Can anyone give me any pointers as to where to start looking for the cause of this?@madstap you're assertion that you're on ring 1.2.1 is based off your project.clj
or the output of lein deps :tree
?
(just the first thing I would check to debug, that you're actually running the versions of code that you think you are, which makes the googling of errors easier)
This is the output from lein deps :tree
https://gist.github.com/madstap/f8b27dd99e269f4d2c0d717c1b7859d5
@madstap what does your actual project.clj
look like?
I've tried using [ring "1.5.1" :exclusions [javax.servlet/javax.servlet-api]]
like suggested by lein deps :tree, just as a random thing that might make sense if it worked, but it didn't
adding [ring/ring-jetty-adapter "1.5.1"]
explicitly might fix it...but I don't know why it wouldn't be pulling that through correct as it is?
sorry, I don't know how to help then.
It sounds like you want to add an exclusion in java-kit
Dependencies that are “closer” take priority over dependencies that are more removed.
So the newer servlet 3.1.0 dependency is being overridden.
You either need to add the servlet dependency explicitly, or put an exclusion on java-kit
I swear it worked before though, I used the java-kit stuff in the repl with everything working...
@madstap Order matters, so if you moved your ring from top to bottom, then that'd explain why it failed now
@dergutemoritz I removed that item from the wiki page.
Is there any way to know whether the thread backing a cancelled future has actually ended yet?
futures aren't backed by a thread, they are backed by a threadpool, the thread a future runs on can end up running multiple futures one after another
the java Future interface defines a get that takes a timeout, and an isDone and isCanceled method. clojure has a future-canceled? predicate
@hiredman does cancelled mean that the future will see no more execution? I would think that incompatible with the JVM execution model?
https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Future.html#cancel(boolean)
Hello. I am new to Clojure and trying to recreate a program in code via the lein repl. I am stuck on the dependencies first thing. Can someone educate me on the following (link appreciated).
user=> (require '[org.elasticsearch/elasticsearch "2.3.2"])
ClassCastException java.lang.Character cannot be cast to clojure.lang.Named clojure.core/name (core.clj:1546)
does that mean there are two different ways to do dependencies in the REPL?
Like this? (require '[clojure.set :as set])
[org.elasticsearch/elasticsearch "2.3.2"] is a maven artifact coordinate which you build tool (lein) needs to make available
https://github.com/technomancy/leiningen/blob/master/doc/TUTORIAL.md#leiningen-projects
Does this mean there is no way to do this without a configuration file? I noticed the usage of it, didn't know if it was required.
OK, thanks, I need to read more 🙂 before I get off the beaten path.
but, as the app is (mostly) stateless, and written in clojure, one could imagine something like figwheel, but for servers.
if you have a load balancer in front, you have it hitting your app on port X, you dpeloy a new version on port X+1, have your lb direct new traffic to X+1, and take X out of the lb, once there is no more traffic
@slipset you can try building WARs and putting them on elastic beanstalk, or perhaps, write a Dockerfile and leverage docker
to deploy new code, you enter the code in the repl, and redefine the functions as needed.
having a repl is nice for debugging, handling production issues, but it absolutely is not your deployment mechanism
But, instead of killing the idea off, I thought it would be interesting to think of how it could be done safer/safely.
I once read that NASA had a lisp system running on a freaking spaceship and they did software updates on it using its repl
@nooga Their options were limited: pushing new code and “restarting” the system wasn’t really an option.
If you have to push code in multiple namespaces, doing so “safely” via the REPL gets to be complex real quick and often impossible (since you have some functions redefined but not others).
@hiredman: I’d like to disagree. I want to be able to reproduce what’s in production.
Even if you could push some small set of changes live via the REPL, you still need to push the updated source (via an updated JAR, for example), in case of a restart etc. So now you have to keep multiple things in sync.
given something like https://github.com/Datomic/codeq
@seancorfield that’s a good argument against. Thank you
you don't want to reproduce what is in production, you want what is in production to be a reproduction of something you know is good
whereas if you're evaling different forms there's no telling what "version" is actually running at any one time
@slipset And, just to be clear, at World Singles we do run REPLs in (some) production apps and we have very occasionally pushed critical fixes live via the REPL. And we have run into the “keep stuff in sync” issue where a patch was pushed via the REPL, then another patch was pushed via the REPL and via a source code update, and then we had to restart the process [and one patch had not made it to the source code on that machine].
So it is very dangerous to go down that path. I can tell you from experience 🙂
We no longer run REPLs in our production processes (with one special exception).
the runtime itself is a big ball of mutable state, you want to touch it as little as possible, you have to touch it some because it has to load code, once you start loading code more than once, and mutating the state, all bets are off
@slipset embed https://github.com/clojure/tools.nrepl and run some experiments, it shouldn’t take long to test out the idea
Again, I’m not going down that path any time soon. But I like thinking about the idea, and what kind of support infrastructure you’d need.
We used to stop/start REPLs in all our production processes back in the day… and we used to do mostly source-based deploys too (so we could “in theory” use the REPL to force a reload from source “easily” — but practice doesn’t match theory here in general).
Do you replace stored procedures in DBs on the fly “all the time”? Or just update data?
The lure of “live updates” was why we originally went down this path. And it proved useful (and safe) maybe half a dozen times max over about five years. But it also trashed the app state several times, even tho’ we were really careful.
@seancorfield I can imagine. And that sort of reflects what’s said about, and my experiences with, figwheel and stateless programming on the front-end.
if you are annoyed at scping a large uberjar, there are a bunch of neat binary diffing tools
also, how do you do "breaking" changes. If function A changes its return type and function B is the consumer of that new type, how do you update them in tandem so that the application remains in a valid state the entire time?
We still have machinery embedded in most of our processes so that we can fire up a version with a REPL active (based on an env var) — but that is now a specific, deliberate choice, purely for debugging if necessary.
We keep a socket server REPL active in just one production process these days and we almost never use it, preferring to start a command line REPL server (and “start” a specific component-based debugging application from scratch) when we need to do anything complex.
@seancorfield sounds like a talk I’d like to attend.
Maybe one day...
I gave a talk at Clojure/West years ago about our gradual introduction of Clojure (2012 maybe?) but we’ve come a long way since then and pretty much every part of our system is different. And it’s all still changing so any talk I gave would be just a snapshot and shouldn’t be taken as best practice.
World Singles is about 100 Internet dating sites, powered by about 50,000 lines of Clojure (and a bunch of legacy code).
@seancorfield most talks are reflections of current state of the art.
I actually submitted a talk about our use of clojure.spec
last year but had to pull it because a) I was slammed in my personal life and couldn’t find time to write the talk and b) our use of spec kept changing so what I’d submitted wouldn’t match what we were actually doing a few months later 🙂
We’re one of those places that has consistently run alpha builds of Clojure in production… starting with 1.3.0 Alpha 7 (or 8) back in 2011.
I remember being awestruck by @matlux talk at euroclojure in 201(3|4) about jvm-breakglass https://github.com/matlux/jvm-breakglass
We’ve been on 1.9.0 Alpha 14 in production for many months.
@ronald.petty take a look at
, it can load dependencies on the fly (while you are inside the REPL):
boot.user=> (set-env! :dependencies '[[org.elasticsearch/elasticsearch "2.3.2"]])
;; Retrieving elasticsearch-2.3.2.pom from
;; ...
boot.user=>
@slipset I tend to always run nrepl baked into the app when I actively work on it. As the app gets to be more mature, stable and better thought out, I tend to keep it off, but still configurable: i.e. I can bounce the app with the nrepl on/off. There are no absolutes. There are risks and benefits with everything. Do what makes sense in your use case
I have a quick question. If I define a function in a namespace, can I use that function in a function further up in the same namespace, like e.g. JavaScript? (Obviously not "namespaces" there, but you hopefully know what I mean.)
@tech_hutch You can declare
it ahead of use.
@seancorfield I wanted to introduce spec while re-writing one of our core services but I’m not entirely sure about using language 1.9-alpha...
Well, actually, I suppose in JS it wouldn't even have to be inside another function.
I find it strange that the capability to inspect and alter a running instance is not used/discussed more.
Okay, I see.
@slipset For dev, I do everything in a REPL. Either via an nREPL server running in an uberjar’d app, or by starting the components directly in a REPL in my editor.
What do you do? Usually just define functions above where they're used?
@seancorfield likewise
@tech_hutch generally, I just rearrange the NS so I don't need declare (i.e. make sure the function definitions always come before the call)
@jstew Yeah, mostly Clojure has been incredibly stable in alpha and beta builds.
only time I use declare is when I have a circular reference between function definitions
Okay.
another thing is that I can’t imagine using namespaced keywords in my current codebase because I will get :foo.apples/oranges
most of the time and it will make me gouge my eyes out
@nooga We tend to have a namespace alias in place so ::m/username
is what is used in “real” code.
> I find it strange that the capability to inspect and alter a running instance is not used/discussed more. @slipset this becomes less fun when you have the same app deployed on >50 servers
what I would do, most likely, is to make namespaces just for keywords, because sometimes there’s no code associated directly with them
(specifically we have ::api-spec/username
for a username provided via the REST API and ::m/username
for a username within our domain model, so typically we only have two main aliases)
> I find it strange that the capability to inspect and alter a running instance is not used/discussed more.
@slipset I think there are two reasons for that: 1. Not many people who have "sensitive" clojure production apps are here active on slack discussing their setups. 2. "`alter`" is a keyword for the answer to your question. Clojure community is "bound to immutability", any time you say alter
, there are many, good, CS and experience backed arguments why you "should not" or "should do it differently". Hence most people just don't bring it up. This is my feeling of course. Not a fact.
Or, sometimes there is, but sometimes not. And trying to slap stray keywords into existing namespaces will end up as :foo.apples/oranges
@grav Leiningen typically starts two JVMs and does a bunch of stuff with dependency checking etc
@tolitius you may have a point. but the whole Repl driven development is about mutating the environment. And yes, I get that development is different from production.
@slipset as you mentioned CodeDeploy earlier, what we do is we have Travis build a JAR which gets deployed by CD whenever someone pushes the master branch
Still seems like a lot compared to what I read in https://purelyfunctional.tv/article/the-legend-of-long-jvm-startup-times/
@grav it is a field of an "active research": http://dev.clojure.org/display/design/Improving+Clojure+Start+Time
@grav here’s what I see
(! 679)-> time lein run -m clojure.main -e nil
real 0m2.107s
user 0m1.772s
sys 0m0.266s
That’s outside any project.
but basically, the answer is, lein is doing way more than clojure.main, and that is why it takes longer to start
(! 681)-> lein new app grav
Generating a project called grav based on the 'app' template.
Mon Mar 06 13:17:00
(sean)-(jobs:0)-(~/clojure)
(! 682)-> cd grav
Mon Mar 06 13:17:03
(sean)-(jobs:0)-(~/clojure/grav)
(! 683)-> time lein run -m clojure.main -e nil
real 0m2.704s
user 0m2.600s
sys 0m0.283s
With a small, new app — pretty much no dependencies.what exactly it is doing will depend on your setup, you plugins, your project, the command you are running etc
Ah, okay, so I just tried without a project, and that took ~3 secs. So I guess I’ll have to take a look at the deps
Not defending, nor explaining lein startup times, I generally have my repls running for days. In that respect, the startup time doesn’t matter too much to me.
@slipset unless you change protocols. then all bets are off: bouncing repl works though.
there is a nice isomorphism between deployments and clojure's epochal time model. a load balancer is like some kind of mutable reference, an identity, versions of your software are like immutable values. clojure generally provides two ways to mutate mutable references, something like reset!
which just sets the value of the reference, which corresponds to deploying a new artifact, and something like swap!
which takes a function from old value to new value, which would correspond to something like applying a binary patch to get a new artifact (which most people don't do)
When using core.match regex matching ,can I also immediately assign the result of the match for extraction? Or does that mean using :<<
?