This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2017-08-31
Channels
- # aleph (38)
- # beginners (91)
- # boot (4)
- # cider (20)
- # clara (11)
- # cljs-dev (4)
- # clojure (179)
- # clojure-greece (1)
- # clojure-italy (16)
- # clojure-portugal (1)
- # clojure-russia (1)
- # clojure-sanfrancisco (1)
- # clojure-spec (183)
- # clojure-uk (50)
- # clojurescript (111)
- # core-async (24)
- # cursive (4)
- # datascript (11)
- # datomic (29)
- # fulcro (120)
- # gorilla (2)
- # jobs (1)
- # keechma (2)
- # keyboards (26)
- # leiningen (4)
- # luminus (7)
- # lumo (15)
- # off-topic (2)
- # onyx (31)
- # parinfer (12)
- # portkey (1)
- # protorepl (1)
- # re-frame (50)
- # reagent (106)
- # remote-jobs (1)
- # ring-swagger (2)
- # rum (10)
- # spacemacs (17)
- # sql (16)
- # test-check (1)
- # yada (2)
Has anyone ever encountered tricky issues with deadlocking at startup with the clojure.lang.RT class intializer? (Here’s a stack trace that illustrates what I’m talking about https://pastebin.com/1w2bqLun) Here’s what’s going on: Main thread defines an top-level var (which is initialized in the RT class loader) whose value is taken from spawning another thread and blocking on it. That second thread tries to use clojure.lang.RT in normal use (in this case, invoking contains?) which blocks on the RT.java class loader completing. Which won’t ever happen because the two threads are blocking on each other.
Figured this out. TLDR: “user” namespace is treated specially by clojure. Swapping repl init namespace to something else (e.g. foo.user) loads it outside of the clojure.lang.RT class loader and breaks the deadlock.
my usual solution has been to take user.clj off of the classpath and have a post-init task in leiningen load it manually
(or use Boot which seems to subvert the user.clj
loading altogether -- which some may consider a bug 🙂 )
@dinoleif I kind of have a related issue in jira I made about this: https://dev.clojure.org/jira/browse/CLJ-2185
what are you using as a http server with clojure nowadays when http-kit is kinda dead project?
aleph
Pedestal, data driven webservers ftw! 🙂
So I'd like to call a public, static java method from a symbol similiar to calling a clojure a method. That is how could I pass 'Integer/parseInt
(possible read from an .edn file) to a function and have it execute? resolve
apparently doesn't work on java interop
Hum, I think there was a function that could wrap java methods as clojure functions, so you could pass them around
Hum, the class seems problematic. I was thinking of memfn, but that won't work on static
basically I'm creating a program that accepts Java plugins, and I need to load them from a .edn file. The easiest way to do this would be to have my main program call a static method in the plugin (that's basically what I do with clojure plugins). Unfortunately this seems complicated.
I'm letting them run arbitrary code anyway, so I'm probably shouldn't be worried about using eval. Thanks
(defmacro run
[f & args]
`(~(edn/read-string f) [email protected]))
(run "(fn [%] (Integer/parseInt %))" "12")
Sorry, I meant:
(defmacro run
[f & args]
`(~(edn/read-string f) [email protected]))
(run "Math/max" 12 34)
You can also have it this way if you prefer to give it a symbol instead of a string:
(defmacro run
[symbol & args]
`(~symbol [email protected]))
(run (edn/read-string "Math/max") 12 34)
So I've been working on this some more, and whenver I run this code: (run (edn/read-string "java.util.Date."))
, I get this exception: clojure.lang.ArityException: Wrong number of args (0) passed to: Symbol
. Why is that? It doesn't seem to be very different.
I did get it to work with eval, though I would be curious to know why this example doesn't work, but no stress if you don't have time.
Is there a way to tell environ to load changes from a project profiles.clj
without restarting the repl?
The author suggested not to structure the app that way https://github.com/weavejester/environ/issues/16#issuecomment-54326836
I had some what similar need. He pointed me to that explanation https://github.com/weavejester/environ/issues/24
in defmulti/defmethod, is there a way to NOT call the multi-method, but to call the dispatch function, to know what it's resolving it?
It's often a good idea to pull the dispatch function out as an actual function so you can test it independently
I have a basic style question on clojure functions. I find it common to need to check a number of preconditions (arg validation etc) before actually executing the body of a function. In languages like groovy/java/x I prefer a number of early if (!condition) return
statements in lieu of deep nested ifs for readability. In clojure (with my limited knowledge of it) I tend to end up with just this kind of nested if structure using if
and when
.
I am aware of {:pre x}
but pre throws an assertion exception which is not always desirable, the method might just come to the conclusion the data is not applicable but that we are still not at an error condition, i.e. the desirable behavior would in my case be to just skip executing the method.
What would be the idiomatic way in clojure to perform these kinds of precondition checks? Or are nested conditional statements it?
There are a bunch of libraries that do this kind of thing
The upcoming spec in core can be used for this too
@alexmiller : the problem I'm having with -is reloading / redefihning defmulti / defmethod at the repl
so I 'know' what dispatch function should be called, but I need to test if it actually is being called
I think there Java API methods you could poke on the Multimethod instance
@alexmiller ok, spec could be an option...but wouldn't a spec :pre still throw an assertion exception?
Yes - you would want to call s/valid? In the code
ah, missed the thread. Thank you, I'm just about familiar enough with spec to do this
There is also s/assert but maybe that's the same as pre for you
@mbjarland no, you can get plain data from it’s functions
it’s a detailed map with explanation info where the spec failed
it’s really worth looking into, still trying to wrap my head around it 🙂
@nicoschneider right, but you would still end up with logic within your method body with an if (or similar) to check that the data returned from the spec is valid?
valid how?
there’s a way in spec to constrain the relationships between function input and output
@mbjarland what do you mean by “skip execution of the method”? you would need to return some values to the caller
it’s really that general so any validation you could think of can take place
@hmaurer good point, in the particular case I'm on right now this is a side effecting method printing things to the console, so the returned value is secondary, but yes in a general case true and then we end up with an if or when (returning nil)
Same issue with first if I recall. nth 0 prolly is much faster than first. That's...odd, to say the least.
@mpenet the first
will become slower for everyone, if you add extra if
there, last - will not. So I can agree with first
in this regard.
last in general should give you slow (linear) expectations
In general, we don't have "special cases". We have traits and collections that implement those traits. The API lib is built on those traits
last is a sequence function that traverses the sequence
If you want fast access to the insertion point, use the stack API (peek, pop, etc)
@alexmiller what is the difference between last
and reduce
from the "generality" point of view?
is there an intuition rule to categorize function either as general (last), or special (reduce), w/o looking up the source code?
sort of similar to "functions operating on collections, take them as last arg, functions for scalars - as first arg"
I don’t see reduce as a bunch of special cases
I really see it as two cases - you are something that can be sequentially traversed or you know how to reduce yourself
both of those have many implementations, but they are the same operation
Let s put it this way: when would anyone want to use first/last on vectors then? Makes the impl a bit pointless
transient support (again, something trait-like, although not done as well) does add a special case to reduce for perf
reduce (being the bottom of many things) has more pressure on it than most other functions
both first and last are part of the sequence abstraction. sequences are logical lists. you should reason from there.
generally, most code shouldn’t use either first or last. you should think in collections.
@alexmiller I understand "usually don't use last", can you elaborate about first
? Do you mean "use destructuring (in loop)/reduce instead"?
Sure but that's counter intuitive to have poor impls of these for vectors. Would it have any bad implications/cost to do something reasonable in that case?
if you particularly need access to the ends of a collection, it’s usually because you are using it as a stack or a queue, etc. choose a data structure that’s good at those things, then use the ops that are designed for that usage.
it is absolutely not counter intuitive. it is exactly about making operations have intuitive meanings and performance implications.
i agree with you but I can't help but see the irony in having to say "it is absolutely not counter intuitive" :)
yeah, I regret writing that already :)
coming from scala, where every possible operator is implemented for every possible collection, I found clojure's consistency on performance very refreshing
As I said I can somewhat understand why last is like this, doesnt make much sense to use it on a vec. But first is way more common/widespread. Ultimately lot of people are probably using it the wrong way and just expect the impl to be more forgiving
To be clear, I am not arguing that vector should be slow on first. What I care about is the expectations you should form about operations.
and that everything should start from a consistent model of operations and collection traits
in that framework, there is opportunity to provide polymorphic implementations with better performance
@alexmiller playing devil's advocate, if the claim is "last is defined to be linear", constant time is technically O(n)
which is covered by what I just said - you should have expectations based on the op, but no one is going to complain if you’re faster
so it wouldn't be incorrect to have last work constant time in vectors and still claim that it's linear, altho I understand the rationale of worse is better to encourage users to not rely on non promised performance optimizations
I’m not claiming worse perf is better
I’m claiming that having a strong conceptual model and an implementation based on traits/interfaces is tremendously valuable
and I’d say that’s more important than having an op be faster than the expectation you should have for that op
to give an example where this has come up in a very nuanced way - we rewrote range to be reducible in 1.7
because the case of all long start/end/step is a) the 99% use case and b) highly optimizable, we did so in LongRange. In those constraints, it’s possible to compute the count of a LongRange in constant time (which is what the Counted interface implies). We struggled over whether to make LongRange implement Counted (normal Range is not - too many special cases) and ultimately did. I can justify that via implementing the extended trait of Counted.
oh, reduce is "bunch of special cases" in clojurescript:
(cond
(implements? IReduce coll)
(-reduce ^not-native coll f)
(array? coll)
(array-reduce coll f)
(string? coll)
(array-reduce coll f)
(native-satisfies? IReduce coll)
(-reduce coll f)
(iterable? coll)
(iter-reduce coll f)
:else
(seq-reduce f coll)))
and those similar things exist in Clojure - but I consider them to be polymorphic implementations under an abstraction, not special case. but maybe that’s splitting semantic hairs.
@mpenet the first
will become slower for everyone, if you add extra if
there, last - will not. So I can agree with first
in this regard.
@alexmiller I understand "usually don't use last", can you elaborate about first
? Do you mean "use destructuring (in loop)/reduce instead"?
no, I mean usually you have a collection and you transform it through a series of sequence or transducer operations to another collection.
if you’re accessing or updating individual items in a collection, you should use a collection operation (get, nth, contains?, update, etc). first/last are only really collection operations on a list or a seq, not on a vector.
so, first
is interesting b/c its part of ISeq which includes first/next/more
where more is really derivative of next
it is tempting to say that the perfect number of operations in an interface is 1 and this interface has several. ISeq could conceptually be a composite of “has a first item” and “has more items” which could be separate smaller interfaces
and vectors could provide a more optimized implementation of the smaller “has a first item” interface
is all that worth doing to save a few ns? that’s a matter of taste and design.
coming back to intuition and readability question:
operating on/from the sequence head, random (key/index) element access, and operating on/from tail should use different data structures, and it should be obvious by looking at the code?
Basically, you need to pick one of those 3 realms, and only then appropriate abstraction's interface:
eg. make it obvious you are working with the tail by using peek
, and then choose vector or queue, etc. under the hood all you want.
I would start with: what ops do I need to do on a data structure. Then, choose a data structure that can do those things well. Then, use the best expression of those ops (peek, not last).
if you followed that, you would never get to the point of asking why first is not faster on a vector
and I would say the “realms” are a little different: indexed access, list/seq like access (first/rest), FIFO, FILO, etc
both lists and vectors work great for FILO (stack) ops using peek/pop
but lists have a head insertion point and vectors have tail insertion point
I actually don’t know which of those is faster off the top of my head. both are fast. :)
well I will agree that vector has the potential for more variability
based on a quick test, I’d say lists are faster as stacks :)
If I need to reverse vector, what is the best way to do it? Size is < 100, or even < 10. Does it even matter?
or call nth
a decrementing range
Hi, is there a shorter/nicer way to achieve (and num (pos? num)) ?
(some-> num pos?)
Hi. Anyone familiar with clj-http? I want to dump the certificate chain when connecting to an HTTPS server and can't find a clue how to do that. I guess, I need to somehow get at the connection object and then do sth like https://stackoverflow.com/questions/7199129/how-to-get-server-certificate-chain-then-verify-its-valid-and-trusted-in-java but how to get the connection? Or is there a better way?
@sky I'd try settings "javax.net.debug" system property - see http://docs.oracle.com/javase/7/docs/technotes/guides/security/jsse/ReadDebug.html
My coworker released a library for making life a bit easier with verbose Hiccup forms https://github.com/ayato-p/kuuga . Thought it may be interesting.
what is a globally accepted word to designate types which can be deref
ed and add-watch
/`remove-watch`ed ?
@leonoel IRefs https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/IRef.java
thanks, that is indeed the least common divisor, but the name kind of overlaps with refs (the concrete type)
I will stick with reference, it seems to be the most commonly used in what I've read so far
I think using the interface name is the least ambiguous. It depends on your audience I guess.
But one thing I often find with names, is that you fall easily in the cognitive dissonance trap. Where a programming constructs is called with a word which metaphorically describes it, but concretely doesn't. Reference is overloaded, people come to the table with their own preconception of a reference. If you say IRef, people say what's that? And they go look it up, and now have a concrete name for a concrete clojure construct, which is not overloaded in their head.
Is there an easy way to allow function calls in arguments to a macro? (e.g. reduce to immutable types)
E.g. reduce '({:a 1} (do-stuff 2))
to the result: '({:a 1} {:stuff 2})
Hmm, ok.
for exceedingly simple cases you can have your macro call eval on its arguments, but that will (depending on use of the macro) very quickly run in to issues
Yeah, it won't work in this case. That's what I'll need to do. I was hoping I could get this to happen at compile time, but that's alright.
eval will execute within the context that exists at the time of macro-expansion. If you want to have it eval at that time, it works.
You can have the macro return a form which executes the argument. Like a macro could return a form which has normal evaluation order, only useful if you want a sort of DSL, otherwise there's not point and a normal function is best.
But you could also write
(def a 120)
(defmacro tt [a b]
`(~a ~b))
(macroexpand-1 '(tt + a))
Now you see it expands to (+ a) instead of (+ 120). But the end result is the same, when you run (tt + a) you get 120 in both cases.
I can't really think of a reason when evaluation at macroexpansion instead would be useful
Is it considered non-idiomatic to have a function with arity 2 and 3, like this:
(a b)
(a c b)
in general it's a bit strange and a potential pitfall for callers of the function, but clojure.core/reduce uses this approach when inserting an initial argument https://clojuredocs.org/clojure.core/reduce
there’s a few others too, like make-array
@joshjones thank you! I just realised even defn
takes that approach with docstrings
or fn, with optional names
or condp, with the magic :>> arg
Does anyone using cljfmt know if there is a way to align assoc
like so:
(assoc {} :x "x"
:a "z")
Where the default is:
(assoc {} :x "x"
:a "z")
I don't see any way of getting this indentation with :inner
or :block
. Am I missing something?I think there needs to be a way to control the amount of indentation, rather than where the indentation occurs.
my workaround is just to move :x
down to the next line
I don’t think cljfmt as is is clever enough for the one you want