This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2017-05-19
Channels
- # ai (3)
- # aws (1)
- # beginners (94)
- # boot (26)
- # cider (3)
- # cljs-dev (99)
- # cljsrn (86)
- # clojure (263)
- # clojure-dusseldorf (4)
- # clojure-greece (22)
- # clojure-italy (2)
- # clojure-quebec (1)
- # clojure-russia (12)
- # clojure-spec (71)
- # clojure-uk (123)
- # clojurescript (92)
- # core-async (4)
- # cursive (13)
- # data-science (2)
- # datomic (123)
- # docker (2)
- # emacs (15)
- # events (1)
- # graphql (2)
- # hoplon (71)
- # jobs-discuss (7)
- # lumo (5)
- # off-topic (12)
- # om (6)
- # onyx (97)
- # other-languages (4)
- # overtone (2)
- # pedestal (1)
- # re-frame (20)
- # reagent (33)
- # remote-jobs (1)
- # ring-swagger (1)
- # rum (5)
- # slack-help (6)
- # uncomplicate (1)
- # unrepl (33)
- # untangled (48)
- # vim (23)
- # yada (21)
sequentiality is not a hard requirement, it just needs to advance in the same direction (decrease in this case)
i know someone who had a similar problem in c++ (unique ids) and they just decided to use the current time multiplied by the hardware thread index as the unique id
we do have uuids if we need to go that far
for a moment I considered to use (clojure.lang.RT/nextID), but then again, I need to find cljs alternative too (also make it negative), and the same argument applies: too much obscure code for a negative int
I'd use datascript's fn, but I try to keep dependencies at zero. which brings me to next question: how do you depend on a few library's functions, w/o depending on the library in project.clj? I went with config hash-map, which gets passed all over the place under the hood. Are there other alternatives?
I want to package code as a lib foo
, which uses fns from lib bar
, but do not include it as a dependency, rather ask to supply particular functions at client setup time
@misha make a function that takes the implementation as an arg, and supply a simple reasonable default
I tried datascript with react native, and it is very slow on iphone 5. I moved it to a separate thread, but RN adds like 50ms to a messages between threads, + datascript is not instantaneous itself, so I decided to build a cache layer to be used in a main thread, for fast reads and optimistic updates, which will talk to a db-thread
@noisesmith there are no alternative implementations: I need 4 particular datascript functions, but want to avoid bumping up dependencies.
normal clojure dependency resolution makes it simple for the end user to select their version
db-thread then will have all the time in the world to: sync with datomic, transact stuff, etc.
this isn’t something you need to solve
or just :dependencies [[bar “3”] [foo “1"]]
the default rule is to use the first provided, and closest to the top level
that’s why you don’t get somebody else’s version of clojure.core - because everyone puts clojure as their first dep as lein puts it there
so it overrides the various clojure.core versions referenced by libraries
it’s also possible to use a :provided scope for a dependency, which declares that you never ship that lib and the user will always provide it
but really just letting people override versions in the normal way suffices for this
I did not find a good/any description of :provided
when I was looking some time ago, and that sounds like the best option so far (as long as I will put it in a readme, hehe)
that would just be annoying - people would ask why they have to add a dep by hand for something you use
or no? would people always be using the lib already if they use yours?
yes, they would, since it is a caching layer specifically for datascript. zero value w/o one. on the other hand, I am always annoyed when I need to go and bump version all over the util-libs I have, instead of just do it in a client application
Hello everyone, I’m new to clojure, could anyone tell me how to avoid use exceptions in clojure? For example, I have an function to check user input params and block the coming steps when the param is invalid, how to refactor the following code?
(defn check-params
"Check my params"
[params]
(if (:required-key params)
params
(throw (Exception. "Missing required keys"))))
@sailxjx I prefer returning an ex-info instance. That way you can have a function that check if the returned value was an error and fetch extra information is necessary (logging) for example.
Return it. Check out the instaparse project. They use that approach as well. You can the check the type of the returned value as see if it is an exception. If so then you know the processing failed
@leonoel this blog post explains it better than I could in a single message: http://yellerapp.com/posts/2015-06-22-exceptions-vs-failure-values-a-battle-to-the-death.html
especially if you're just interested in the "stop computation on error" feature, as is precisely the default behavior of exceptions
@leonoel monads? sorry I had to delete that message because it was the wrong blog post 😅, please see the editted link
nevertheless, I never said that any other idea was bad, nor that my idea was the right one. I simply said: "I prefer to return an ex-info", which is just a personal opinion
I get your point about the exception mechanism and I agree that there is no point in reinventing it if that would be the case. Nevertheless in some cases, you are dont want an exception to be thrown, because an error can be an expected behavior. Just like the name says, an exception is an exception to the normal flow of a program. But if the program expect the computation to fail should you still throw?
There are some pretty sound reasons not to use exceptions for flow control—one of which is that error data isn't explicitly surfaced in your enclosing APIs which means client code tends not to bother handling errors. The Either monad (and variants) is a pretty good way to fail out of a set of nested might-fail functions in the presence of a known error condition without adding too much cruft to your code, or using the nuclear option of unwinding the stack with an exception.
@carocad this post is more pragmatic but not really advocating returning ex-info instead of throwing it, right ?
right. The only advice there is not to return nil as error since the user of the functions would not know why did something fail. Throwing and returning ex-info are more of an opinion. I prefer returning them but ymmv 😉
wrapping the value in an either monad is basically the same strategy : you force the caller to care
yes but if you throw an error then it will throw you away the flow of the program even if you expected an error to happen. For example:
(sequence (comp (map f1) (filter f2) (map f3)) a-sequence-that-might-fail
If either f1, f2 or f3 fail for a single element then your complete computation is thrown away because you will go to the catch statement.
nevertheless if you know that one of those operations might fail the you can simply do:
(sequence (comp (map f1) (remove failure?) (filter f2) (map f3)) a-sequence-that-might-fail
The second options lets you decide how to handle the error. You might ignore it or you might throw it. Again, it depends on the flow that you want to encourage of your api
yeah, every programing language struggles with that question. Precisely because it get very subjective about who should decide what and how 😄
Hi, how can ring get the form data from a request, I currently can get query-params
, multipart
, keyword-params
, but I don't know how to get the js formdata.
(def svc-app
(wrap-routes main-routes
#(-> %
wrap-reload
keyword-params/wrap-keyword-params
cookies/wrap-cookies
params/wrap-params
mp/wrap-multipart-params)))
I found if I send the POST request using x-www-form-urlencoded
, I will get the form-params
, but if I send the POST request using js/formData
the form-params
will like this:
:form-params {"------WebKitFormBoundaryu7BKnalMAs1Vg5qP\r\nContent-Disposition: form-data; name" "\"token\"\r\n\r\n91827fc3227c5ba631ba53435327374273c45fa0\r\n------WebKitFormBoundaryu7BKnalMAs1Vg5qP\r\nContent-Disposition: form-data; name=\"statement\"\r\n\r\n1212\r\n------WebKitFormBoundaryu7BKnalMAs1Vg5qP--\r\n"}
This is the result when using x-www-form-urlencoded
:
:form-params {"token" "91827fc3227c5ba631ba53435327374273c45fa0", "statement" "(financial/query-latestinfo \"300182\")"}
I found if I send the POST request using x-www-form-urlencoded
, I will get the form-params
, but if I send the POST request using js/formData
the form-params
will like this:
:form-params {"------WebKitFormBoundaryu7BKnalMAs1Vg5qP\r\nContent-Disposition: form-data; name" "\"token\"\r\n\r\n91827fc3227c5ba631ba53435327374273c45fa0\r\n------WebKitFormBoundaryu7BKnalMAs1Vg5qP\r\nContent-Disposition: form-data; name=\"statement\"\r\n\r\n1212\r\n------WebKitFormBoundaryu7BKnalMAs1Vg5qP--\r\n"}
at a clojure repl, is there . away to type in the name of a java class and get the documnetatio nf said class ?
@qqq I don't think it's possible via reflection. Some environments support javadoc documentation for given symbol (e.g. cider-doc
) - for standard java classes you can still use javadoc
function (which will only open online documentation)
I wouldn't say that - Cursive certainly has internal mechanism how to show javadoc for given class. not sure about cider, but in cider it also works for non-JDK classes for which you add sources to the classpath
what I meant to say: "the standard way 5toget docs for a class is via javadoc; and you can figure out how to display it later"
(j/with-db-connection [conn db-spec] (j/execute! conn (j/drop-table-ddl :letters))) gets me d.font=> PSQLException ERROR: statement cannot follow a schema change in a transaction org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse (QueryExecutorImpl.java:2455) how do I drop a table in jdbc ?
(execute! db sql-params) (execute! db sql-params opts) The :transaction? option specifies whether to run the operation in a transaction or not (default true).
lxsameer: migratus these days
Oh, I doubt it. IIRC it’s tooling is built around a fairly simply protocol, but cassandra may have unique requirements
never used it either, maybe you might want to ping #juxt people (I am just aware of it because of alia really)
I use joplin, if you plan to use it be sure to have a look at https://github.com/juxt/joplin/issues/8#issuecomment-152650634 . Apart from that it is alright
@U0ALP2929 i don't want to use it any more but I'm going to check the out for sure, thanks
We talked about the bad points of joplin but what I like about joplin is that I can use it from my code, as a library. It means it is very easy to add things like logging etc. with your migrations, which can be useful for debugging/monitoring etc. But I nearly dropped it several times, due to the issue above. (note, I use it on a personal project, not at work)
Hi, how can I get all routes under some /path
in compojure
? for example, I want to match all /path
, /path/a
, /path/a/b/c
, /path/v/e/r/y/long
and so on to run in one handler? Or, maybe a wildcard matches such as /path/*
?
i never seem to have a need for macros, am i doing clojure wrong
@michaellindon The author of book Clojure Programming says: You can go a long way before you start to use macros in clojure.
@cmal one of the main selling points of Clojure is the ease with which one can create macros... seems like I'm missing out on one of the main advantages of the language. Either my applications rarely need them or my brain is not wired to think in macros
macros tend to be a modification of a reasoning model (in my experience). So it would just mean your reasoning model is in line with the base patterns of the language.
thats good to know. It felt like I was missing out on some superpowers by not using macros
CompilerException java.lang.RuntimeException: Unable to resolve symbol: ct->tensor in this context, compiling:(/home/chrisn/dev/cortex/src/cortex/verify/tensor.clj:138:17)
user> (defprotocol test-proto
(test-fn [arg0 arg1 arg2 arg3
arg4 arg5 arg6 arg7
arg8 arg9 arg10 arg11
arg12 arg13 arg14 arg15
arg16 arg17]))
test-proto
user> (test-fn 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17)
CompilerException java.lang.IllegalArgumentException: No single method: test_fn of interface: user.test_proto found for function: test-fn of protocol: test-proto, compiling:(*cider-repl cortex*:51:7)
user> (defprotocol test-proto
(test-fn [arg0 arg1 arg2 arg3]))
test-proto
user> (test-fn 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17)
CompilerException java.lang.IllegalArgumentException: No single method: test_fn of interface: user.test_proto found for function: test-fn of protocol: test-proto, compiling:(*cider-repl cortex*:56:7)
user> (test-fn 1 2 3 4)
IllegalArgumentException No implementation of method: :test-fn of protocol: #'user/test-proto found for class: java.lang.Long clojure.core/-cache-protocol-fn (core_deftype.clj:568)
user>
I have a somewhat noob'ish question if anyone feels like entertaining it! I'm working on a transpiler-of-sorts, and it uses clojure.walk/postwalk to assign types to expressions, starting at the leaves of the tree (that comes from edn) and going up. as far as I can see... when I modify leaf nodes and then try to 'access' those leaf nodes from their parent in the tree, they aren't modified
so... is postwalk sort of creating an immutable copy and the tree you're accessing doesn't change as you traverse it?
here's the source for reference: https://gist.github.com/anonymous/a7c1e7f4f9a7cf3bce3209c8a40fac09#L121
by modify leaf, i mean... when it's at the bottom of the tree, it uses with-meta to add metadata, and then i'm trying to basically progressively move that metadata up the tree
(clojure.walk/postwalk #(if (number? %) (inc %) %) {:foo 1 :bar {:nested 41}})
=> {:foo 2, :bar {:nested 42}}
i've been confused because when i get to the bit where it looks for child nodes to have metadata ([here](https://gist.github.com/anonymous/a7c1e7f4f9a7cf3bce3209c8a40fac09#L134)) it isn't finding that metadata set
but if i log the places that postwalk traverses, i know that the metadata has been set... somewhere
whoah. okay, was in a totally different bug land than i expected 🙂 til that list? is not a very robust way to check for general listiness, seq? covers all the bases in this case
haha no worries, I'm in a lot of slack communities so its good to occaisionally get reminded that one exists 😄
@tmcw postwalk creates a new collection, the new collection it created has your new metadata
we don’t really update things in place, other than vars, atoms, refs, agents
and a hash map is none of those
with-meta returns the hash-map but with different metadata, not changing the metadata on the item you were looking at
gotcha, i'm more wondering... the function that's called for each node by postwalk - is it called on the new tree (and thus has the modifications of previous traversal steps) or are the methods always called on the old, original tree
it should be on the new one, but I wouldn’t be surprised if there was a subtle metadata bug - those happen a lot
it might save some trouble to define a two-way transformation into a node structure that explicitly shows that data (at the cost of hiding the “real value” under a sub key of course)
similar to how clojure.tools.analyzer.jvm represents the AST https://github.com/clojure/tools.analyzer
because they found it more reliable to describe everything about an ast as data - in terms of printing, less gotchas where you unexpectedly lose metadata, etc.
but someone who works on that project might have a better answer than I
got it, cool! i'll consider that if i end up needing to store / debug information more in this tree ast
that's a bummer about not being able to trust metadata, was pretty hopeful about that part of the language
I think the intended use case was suppose to be "about" data, and never to be used in a way that affects the identity/equality of the value. Not sure if that pertains to this use case or not.
it’s not robust in that many people use functions that don’t preserve metadata - clojure.core probably fixed this in most cases by now, but random other libs likely haven’t
this means to use metadata reliably you need to agressively re-apply metadata after using the data
ok. i'd call that a matter of transparency rather than robustness, fwiw. metadata behaves the way it's designed to behave, i hope, since i'm using it a lot.
@mobileink yeah, I meant that as "using metadata to represent ASTs isn't a very robust approach"
(into-array String [“id” “text”])
there’s extra parens in the fail case
lein difftest
makes such things more obvious in my experience
i'm not sure the parens are... real? like if I add (first
, then the 'actual' result becomes 'module', same as the expected
clojure.test does not insert fake parens
nil means “no difference”
the difference is the two 0
maybe someone did (symbol “0”) which is not equal to 0 but prints the same (and is an abomination btw)
but the symbol function totally lets you do that
peregrine.circle=> (symbol "0")
0
peregrine.circle=> (= 0 *1)
false
you could add a test that the 0 there is not a symbol - narrow down to the failure
Hey folks, I was wondering if I could get some tips on pre/post conditions. When looking at http://blog.fogus.me/2009/12/21/clojures-pre-and-post/ and in practice, when the precondition fails all you get is an AssertionError. Any way to get a better report of the error, especially the location where it happened?
It'd be nice if it told you the function or ns where it occurred.
stack traces will tell you both the function and ns
and when assertion errors are thrown you should get stack traces
well, I thought so, but maybe I am doing something wrong. Here's an example:
(defn constrained-fn [f x] {:pre [(pos? x)] :post [(= % (* 2 x))]} (f x)) => #'enhanced-hickory.core/constrained-fn ((try (constrained-fn #(* 3 %) 2) (catch Exception e (.printStackTrace e)))) java.lang.AssertionError: Assert failed: (= % (* 2 x))
ah, wait...
there’s extra parens around that try…
(try (constrained-fn #(* 3 %) 2) (catch Throwable e (.printStackTrace e))) => nil java.lang.AssertionError: Assert failed: (= % (* 2 x)) at enhanced_hickory.core$constrained_fn.invokeStatic(form-init6196173666840420140.clj:1) at enhanced_hickory.core$constrained_fn.invoke(form-init6196173666840420140.clj:1) at enhanced_hickory.core$eval15641.invokeStatic(form-init6196173666840420140.clj:2) at enhanced_hickory.core$eval15641.invoke(form-init6196173666840420140.clj:1) at clojure.lang.Compiler.eval(Compiler.java:6978) at clojure.lang.Compiler.eval(Compiler.java:6941) at clojure.core$eval.invokeStatic(core.clj:3187) at clojure.core$eval.invoke(core.clj:3183) at clojure.main$repl$read_eval_print__9983$fn__9986.invoke(main.clj:242) at clojure.main$repl$read_eval_print__9983.invoke(main.clj:242) at clojure.main$repl$fn__9992.invoke(main.clj:260) at clojure.main$repl.invokeStatic(main.clj:260) at clojure.main$repl.doInvoke(main.clj:176) at clojure.lang.RestFn.invoke(RestFn.java:1523) at clojure.tools.nrepl.middleware.interruptible_eval$evaluate$fn__996.invoke(interruptible_eval.clj:87) at clojure.lang.AFn.applyToHelper(AFn.java:152) at clojure.lang.AFn.applyTo(AFn.java:144) at clojure.core$apply.invokeStatic(core.clj:657) at clojure.core$with_bindings_STAR_.invokeStatic(core.clj:1963) at clojure.core$with_bindings_STAR_.doInvoke(core.clj:1963) at clojure.lang.RestFn.invoke(RestFn.java:425) at clojure.tools.nrepl.middleware.interruptible_eval$evaluate.invokeStatic(interruptible_eval.clj:85) at clojure.tools.nrepl.middleware.interruptible_eval$evaluate.invoke(interruptible_eval.clj:55) at clojure.tools.nrepl.middleware.interruptible_eval$interruptible_eval$fn__1041$fn__1044.invoke(interruptible_eval.clj:222) at clojure.tools.nrepl.middleware.interruptible_eval$run_next$fn__1036.invoke(interruptible_eval.clj:190) at clojure.lang.AFn.run(AFn.java:22) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) at java.lang.Thread.run(Thread.java:745)
and an assertion error is not an exception
sorry for the span
yeah, needed to catch the Throwable
not Exception
so to get usable info from pre/post I need to wrap it in a try/catch somewhere? That seems to be the answer.
enhanced_hickory.core$constrained_fn
- that’s your namespace and function, right at the top
Yeah, what I was hoping for was a better message without wrapping the call.
(constrained-fn #(* 3 %) 2) java.lang.AssertionError: Assert failed: (= % (* 2 x))
also, with assert (as opposed to :pre and :post) you can provide a string describing the issue
^that
AssertionErrors are meant for catching things during development, I would skip the try/catch and use the file / line info from the stack trace to see which code I need to fix
I'm in the cursive repl.
w/o the try/catch all I see is this:
(constrained-fn #(* 3 %) 2) java.lang.AssertionError: Assert failed: (= % (* 2 x))
no, it just dumps the assert
@markbastian if that’s all you see, clojure.repl/pst will show the whole trace
Yeah, that's my whole issue. I was expecting better reporting (the whoe stack trace)
usually clojure.repl is in scope so you can just run (pst)
when in doubt, (use ‘clojure.repl) is a good idea when developing after switching namespaces
in lein repl i get at least the function that fails the constraint even though i don't get a stack trace
ah, that's cool
meaning pst
So, pst def solves the problem for now. Thanks!
yeah- assertion errors and pre / post are mainly for dev time, it’s totally legit to turn off assertions in production
if you get an uncaught error in an app, you should get a stack trace unless someone is over-eager with a try/catch
i wonder if there's a setting you could set or maybe they could update that. you could try #cursive
Proposal: "The Clojure community should dump slack in favor of something to be named later." Please respond by selecting one of the following, where 🐓 means "dunno", or "undecided" or "no opinion". 👍 👎 🐓
hahaha! wait, you didn't vote! seriously, low response rate (let's give it 24 hrs) means it is not perceived as an issue. which would be good to know since clearly some do think its an issue.
my guess is most of us just haven't even thought about it, and probably don't much care. but you never know what real data might show.
@mobileink : I just cast the deciding vote, takikng it from 2-2-1 to 2-3-1; get hacking, dude
the other problem is that with the 10k limit, and the inability to pin posts, few ppl will see mobileink's voting system before it vanishes
if the poll disappears, I would vote to move off of slack. but i would be unable to vote in this case. Slack's limitations prevent me from complaining about slack's limitations
@john: just wanted to gauge slack response. proposing a specific alternative would bias the tesult.
@qqq: methodologically, is it ok if we take all the people who did not see it before it vanished as "yes"?
@mobileink : personally, I would be okay if you took all the people who voted 'no' and interpreted them as 'yes' 🙂
I think if we had a better system, for wiki links . ;pinning stuff in discussion, people would also provide answers
right now, it's an "eh, wasted effort"; whereas if we knew that it had long term value, we would be more likely to write wiki like responses
it'd also be useful to be able to answer questions by poiting at wiki docs instead of retyping ansers to repeat questions
yeah, hence the poll. you and me (and others) would like to see more, but if the vast majority of users are satisfied with what we have, it would be a waste of time to try to sell them on sth else.
i think the way to bridge this is by writing a slackbot that (1) archives everything and (2) starts auto answering questions
better than nothing, i admit. but undeniably hackish. slack search does not talk to it akaik. and, frankly, i am far too lazy to go grubbing around the web to find old slack msgs.
There is a discord channel that got started today https://www.reddit.com/r/Clojure/comments/6c4z91/a_discord_for_clojurians/
hswick: jumped right there as well, good job in putting that up (if it wasn't you, good job in sharing 😄) !
It wasn't me. Someone named hagus, but thought I should share since jumping from slack was coming up. The discord group seems cool, I'm digging it
totally
so far we have a response rate of 9 out of approximately 10,000. Hear me, O People! I am compelled to say that I am a little dissapointed by your lack of enthusiasm. Vote - use it or lose it, and be condemned to program in Java for the rest of your sorry life! heheh.
our local clojure meetup was “clojerks” for a while
I first attended just so I could say I was an official clojerk
it’s “clojure pdx” now, but seattle’s was still called seajure last I heard
@mobileink I think it was extensively debated before and "clojurians" won, so I probably shouldn't complain