This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2018-06-13
Channels
- # beginners (36)
- # boot (1)
- # cider (4)
- # cljsrn (2)
- # clojure (137)
- # clojure-brasil (3)
- # clojure-czech (3)
- # clojure-italy (17)
- # clojure-nl (8)
- # clojure-spec (7)
- # clojure-uk (153)
- # clojurescript (84)
- # data-science (2)
- # datascript (13)
- # datomic (30)
- # editors (64)
- # emacs (22)
- # events (6)
- # figwheel (26)
- # fulcro (7)
- # hoplon (5)
- # jobs (5)
- # jobs-discuss (57)
- # keechma (3)
- # leiningen (4)
- # luminus (1)
- # midje (2)
- # off-topic (26)
- # portkey (18)
- # re-frame (4)
- # reagent (10)
- # ring-swagger (3)
- # shadow-cljs (135)
- # spacemacs (5)
- # sql (14)
- # tools-deps (125)
and so yeah - 6 is the max number and that's 2 more than my processor count, it's doing what's documented
Right, I wasn't trying to prevent chunking. I should have pasted the earlier example from my REPL session to be less confusing.
And with (take 100 (iterate inc 0))
I get up to 10 in-flight -- 2 + number of processors
So you get better "parallel throughput" if you operate on a chunked sequence...
seems like it would be more useful to agressively dechunk inputs and make the n an explicit parameter
(also simpler)
Hi everyone. Has anyone here tried to use Cursive with reader literals within the ns form? I'm trying to load some libraries for clj and some for cljs, but I don't think Cursive understands it.
@clojure475 What’s the issue you’re seeing?
(ns common.db
(:require #?@(:clj [[clojure.spec.alpha :as s
java-time :as time]] ; `compare` works
:cljs [[cljs.spec.alpha :as s]
[cljs-time.core :as time]
[cljs-time.extend] ; allows `compare` of `goog.date.Date`s
[goog.date]])
[common.fsm :as fsm]
[client.routes :as routes]))
That said, it’s entirely possible that Cursive might get confused by this, CLJC is hard 😞
Could you file an issue for that, and I’ll look at it? https://github.com/cursive-ide/cursive/issues
how can I write a parametrized (or generic spec)? say I have (s/def ::foo string?) (s/def ::items (s/coll-of ::foo) (s/def ::bar (s/keys :req-un [::items])
but the ::bar
is so common in my codebase that I want a function that takes a predicate (`string?`) or a spec, and returns the new ::bar
spec, that specifies a map spec with :items
key, which should contain a collection of x
(predicate or spec)
you can basically parameterize the spec using (s/merge (s/keys ...) (s/multi-spec ...))
, where you have a set of base keys and then merge into it another spec, which is dispatched based on for example a key's value
i've had quite some success with this with, for example, writing specs for a ::job
, and then adding additional specs based on the job's type
@lmergen interesting, but doesn't this presume I have a special field that indicates the "type" in that entity? because I don't have it and I don't need it there for any other purpose
so basically what you're saying is that you want the spec of ::bar
to mean different things, depending on the context it's called in ?
(one time you want to use a string?
predicate, another time something different -- let's call it a 'dynamic' spec)
I don't need to call it anything or even be in the registry, I just need to use it for validation
but that's optional, I could be doing that. the problem is, again, that spec is macro driven instead of data driven, so generating, or parametrizing specs is difficult
let me think, because i think what you're really looking for is a function that returns a spec without registering it
I know about spec-tools and data spec, that would solve the problem, but I'm trying to avoid it as an extra dependency
How can we connect to a running program with a REPL? I saw some posts somewhere about exploring the state of a production app from a REPL, but I am unaware whether this can actually be accomplished with any clojure application, or does it actually prerequisite the application being started in a very certain way (or even requiring the application to include code that explicitly arranges this ahead of time).
@matan there are a couple of ways: either the Clojure program can start an nREPL server and then you can connect to it with any nREPL client; or you can provide JVM options to the program at start up so it starts a Socket Server REPL and then you can use telnet or unravel etc to connect to it.
We run a REPL inside several of our production processes for this purpose.
(didn't I already answer this question from you in #beginners ?)
@matan It's "just" a REPL. You can do whatever you want in it. There's no difference between a program you start from the REPL and a REPL you start from a program really.
I might find it hard to imagine how I’d use such a REPL running orthogonally to my application. Obviously it has access to the same namespaces, but spinning up extra copies of them is one thing, connecting to up and running atoms and agents quite another
vars in namespaces are globals
it's no different in a distributed repl than a normal one
I'm not sure what you mean.
The process in a REPL is exactly the same as how Clojure runs code anywhere: require a namespace, call a function...
What do you mean by "spinning up extra copies of them"? Namespaces are singletons.
I’ll add a concrete example once in front of a desktop... but basically if I call up a namespace into the REPL, will it redefine all the vars in a separate “copy” that only my REPL is seeing, or will it just grant access to the already initialized copies of them running by the application?
Namespaces are singletons. There is no "separate copy".
If you require a namespace that is already loaded (and therefore compiled), it is a no-op. Well, perhaps beyond adding the alias to your current namespace.
@carr0t You can start multiple REPLs.
We're talking about connecting to a REPL running inside a program.
Folks, a doubt about spec: I’m trying to validate inputs and outputs of my functions using :pre
and :post
conditions, but I’m seeing that there is spec/fdef
. What’s the difference between using one over another?
:pre
and :post
are tied into the assertion machinery of Clojure (and can therefore be turned off globally). spec/fdef
defines specs for arguments, return values, and the relation between -- and the arg checking is turned on/off via instrument
and the return value/relation checking is done via check
(both in clojure.spec.test.alpha
).
You can use specs in :pre
/ :post
if you want (calling s/valid?
on a spec and a value, for example).
Gotcha.
So, to validate these specs in production what would be the recommended way of doing things?
If you want to validate function arguments (in production), write explicit code in the function that calls s/valid?
or s/conform
.
The assumption is that you use spec mostly around system boundaries. So you might use spec for validating/conforming incoming API or HTTP parameters, or around data you get from a third party service.
And those tend to be places where you want the check to "always happen".
So is not recommended to turn on the assertion machinery in production?
Depends who you talk to. I personally think that if you're going to use assertions at all, you should leave them on in production as well.
But I generally do not like assertions.
They throw Error
rather than Exception
which means you need to catch Throwable
if you want to deal with them in your program.
I see, well, the problem is when they throw and return http 500 error on you
A program can prevent that by catching Throwable
and responding with something more friendly -- but if you're using assertions for "this can never happen" checks, then you probably want the program to crash and burn at that point.
Whereas data coming in from APIs, HTTP parameters, 3rd party services, perhaps even your legacy database... should all be "expected" to be invalid so the check should be part of your normal program execution logic.
Well, this is a new service I’m writing which will talk with an external service provider API. But the discussion was quite enlightening. Thanks! 🙂
While you're developing, it can be very handy to have function specs enabled (via instrument
) and to check
the behavior of key (pure) functions. But instrumentation can be quite a performance overhead so you may well not want it on in production.
Like most things, it's a trade off. For example, clojure.java.jdbc
has specs for nearly all functions but they are optional, and running database access code with all of them instrumented is substantially slower -- but they can be a help during development to make sure your calls into that library are valid.
I need to take the first n elements of a collection where the sum of those elements is no greater than x. Can anybody think of a nice way of doing that? I was looking at medley
’s take-upto
, but that can’t carry state about the prior elements. The predicate needs to have reduce
like flavor. I was thinking about maybe creating a lazy sequence of the sums and feeding that into take-upto
but I couldn’t work out how.
@lee.justin.m You could always use reduce
and stop with a reduced
value when you have the appropriate number of elements.
@seancorfield oh cool i didn’t know about reduced
. i’m not sure how that works but great!
I suspect that when reduced
and reduced?
were added in Clojure 1.5, no one thought to update the docstring for reduce
(which had been around since 1.0). It took up until Clojure 1.7 for the bugs to be shaken out so that all reducing functions respected reduced
.
Hello everyone, for those of you who use emacs: How do you automatically format your clojure code? cider-format-defun
seems to not work and cider-format-buffer
changes the cursor position. Ideas?
do people think it is appropriate for the clojure
executable to print "Downloading: ..." messages to stderr? is this by design or a bug?
it is by design
you are welcome to criticize the design :)
can we at least count on the status code returned from the executable to be non-zero if an actual error occurred?
[i.e., i had some code that was checking for the combination of an empty stderr and a zero status code to indicate success]
i could relax that check to be just the latter if stderr is used this way intentionally]
if there is a failure in building the classpath, you will get status code 1
[it's a bit of an abuse of stderr but i can understand why it was done this way (since there really isn't any other stream to send it to and we want the actual contents of stdout to be the literal classpath and nothing more)]
I don’t think stdout is the classpath - we write all that to a cache file
hmm, that's not what i'm seeing. 2>/dev/null suppresses the "Downloading ..." messages but the classpath is still printed
or do you mean specifically with something like clojure -Spath
?
yes, the errors were separated for exactly this reason
so we use plumatic/schema to coerce json back and forth from our internal schema, which works awesome for all our backend clojure services. unfortunately our frontend is javascript instead of clojurescript. wondering if anyone has found any good solutions for coercing json into more structured schemas in javascript
I am using joi in js: https://github.com/hapijs/joi/
thanks for the lead! does that let you define custom coercions like date strings -> moment.js objects?
awesome thanks, looks like there are some extensions already for that
so i see how you can use this to take a json parsed object and convert it to a joi schema, but i don’t see how you might do the reverse. convert a schema to json
do you use it for that as well?
got it
thanks again :thumbsup:
yeah from what i could tell it’s specific to json but language agnostic. i’m more looking for something javascript specific that can for example coerce datetime strings into moment.js objects automatically
clojure has spoiled me
i guess thats what i’m having trouble finding then heh
you could probably use shadow-cljs to create a library that uses plumatic/schema
and then call that from javascript
yeah thats not a terrible idea actually
at the very least i would find it interesting to try in my spare time
the other thing that’s cool about that idea is that it allows you to slowly eat the javascript front end incrementally
:thumbsup: