This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2020-05-05
Channels
- # announcements (7)
- # babashka (20)
- # beginners (130)
- # bristol-clojurians (1)
- # cider (14)
- # clj-kondo (7)
- # cljdoc (14)
- # cljs-dev (15)
- # cljsrn (16)
- # clojars (11)
- # clojure (190)
- # clojure-dev (4)
- # clojure-europe (7)
- # clojure-italy (9)
- # clojure-nl (3)
- # clojure-romania (6)
- # clojure-uk (51)
- # clojurescript (44)
- # component (4)
- # conjure (28)
- # cursive (1)
- # data-science (4)
- # datascript (1)
- # datomic (30)
- # duct (4)
- # emacs (1)
- # figwheel (4)
- # fulcro (56)
- # graalvm (4)
- # helix (51)
- # jackdaw (2)
- # jobs-discuss (12)
- # joker (4)
- # lambdaisland (1)
- # local-first-clojure (1)
- # meander (73)
- # mid-cities-meetup (2)
- # nrepl (4)
- # off-topic (43)
- # pathom (56)
- # re-frame (37)
- # reagent (26)
- # shadow-cljs (161)
- # slack-help (9)
- # spacemacs (1)
- # tools-deps (18)
- # xtdb (18)
I almost never use loops because collections are just easier to work with, and this thing with the position of recur is very obscure
I can try to give better code examples if that's the goal, sorry that I reacted that way to the question, seemed like a tangent 🙂
No worries. I want to read the docstrings and understand. Could be a macroexpansion problem. Can you recreate with just a plain goloop and no hooks involved?
I can try but I don't have access to easy sandboxing, takes a while to create a new shadowcljs app and configure everything in the build.
I keep planning to learn clj and deps.edn and have some aliases for bootstrapping minimal cljs apps, but I never get around to it, too much other stuff to do
If you want to play around I think “shadow-cljs browser-repl app” will get you a repl
the go macro rewrites its body, it's not hard to end up with a situation where the "tail" is no longer a tail after the rewrite
@ashnur the go compiler might have a better chance with a simpler form with fewer branches:
(defhook use-take
[channel on-take]
(let [cancel-signal (hooks/use-ref false)]
(hooks/use-effect
[channel on-take]
(go-loop []
(if-some [msg (when (not @cancel-signal)
(<! channel))]
(do (ontake msg)
(recur))
(reset! cancel-signal true)))
#(reset! cancel-signal true))))
I think that would behave the same as your originalthe when combines the check on cancel-signal with the channel read, as it returns nil if its first arg is falsey
thanks, it's a bit confusing because I haven't had this working in any form yet, and the code I shared was a rewrite of an example I got, and .. and.. : D well, I am trying, and if it wont work, I will try to get at some simpler example
the rule of thumb is that go / go-loop are weird macro things, and they make chained callbacks on channels look like sequential code
so if they do something you don't understand when compiling, a good first try is to do less nesting (especially less nesting of macros)
the CSP part is not new to me, only clojure/clojurescript core functions and macros and their own ways of doing things 🙂
the rewriter is less likely to get confused when rewriting simpler forms
I turned the stack of go-loop / if-not / let / if-not / do (all macros) into go-loop / if-some / do
Yeah, I tried your version, it says the same thing. I will try to get at an isolated example now.
oh that would explain it
I might missed this in the docs, but is there a way to download a new dependency without restarting the REPL while using tools.deps CLI?
not with the default set of deps - there are libraries that do this but they tend to be a bit hacky
I mean, even using a dep that you've downloaded for another project isn't simple - it's not the downloading that's complex, it's making the vm add new things to the classpath
@ander There is a branch of tools.deps.alpha
that supports that, via a function call add-lib
. I use it a lot. You can see how to use it in my dot-clojure
repo: https://github.com/seancorfield/dot-clojure/blob/master/deps.edn#L147-L164 so I can just do clj -A:deps
and then I have a REPL I can dynamically add new dependencies to.
In addition, the weird-looking DynamicClassLoader
incantation there means I can do clj -A:deps:socket:rebl-11
and have Cognitect's REBL start up with a Socket REPL on port 50505 and both will support add-lib
(since it needs a DCL).
I'm hoping to find time this week to do a new video for my YouTube channel that shows a dynamic REPL workflow where I start from a minimal new deps.edn
project and add dependencies and build a web app all inside a running REPL with no restarts...
Oh wow, thanks for that! I'll give it a shot tonight. The premise for that video sounds great, I'd love to see it
You have add-lib
working? 🙂
Yep! Your dot-clojure
is a great help as well. I have a lot to learn, and I can get caught up in getting my environment just right
Feel free to DM me with any questions about the dot-clojure stuff or REBL or anything in my videos 🙂
Are there any good solutions for rename refactors? Or move refactors, or argument reordering? clj-refactor
in emacs seems quite dead; is cursive good for this?
The only rule of thumb to use it is that your code must compile before you perform a refactor on it
With code that compiles, its always worked for me. But I don't have mixed clj/cljs projects
@jings.bill Not sure where you're looking but https://github.com/clojure-emacs/clj-refactor.el/commits/master looks pretty darn active to me...
I guess that was harsh. I said it was dead because it hadn’t worked for me and I was never able to find a workaround; googling has found reports from others that it has issues if e.g. there’s cljs in the tree. That was the basis for my judgement; I guess it was premature.
I think the clojure-emacs
team are most active on Gitter and IRC. Not sure where they hang out here on Slack -- maybe ask in #emacs or #cider ? I bet if you ask some of the team, they'd be happy to help you get it working...
(I've never used any automated refactoring support -- I prefer to keep my editor/toolchain as lean as possible and free of any "magic")
Maybe that is well. It is difficult to give up once one comes to rely upon it.
It makes a lot of basic housekeeping tasks straightforward and anxiety free.
This is wonderful. Thank you
clojure-lsp
has given me even more useful tools than i was looking for in the first place
https://clojurians.slack.com/archives/C053AK3F9/p1588644858480300 so, I tried that example
first I thought it might be the helix macro, but people say the same code that doesn't work for me, works for them
it's a bit weird to be told that it's a non-deterministic process that decides if my code that is the same (to my very limited knowledge) as other functional code
one good news is, which it took me to sleep before, is that just using (go (loop instead of (go-loop works fine
Hi all. Python programmer here. Have tinkered with Clojure very briefly in the past and have been intrigued by it. Just bought a Clojure book (Getting Clojure) and am starting fresh. Have even dusted off my old Emacs config (vimmer by trade, but have switched back and forth a few times). Looking forward to getting stuck in.
At the risk of opening a can of worms... If you're used to vim but have some emacs knowledge too you might find https://www.spacemacs.org/ interesting. It's a whilst since I've used Emacs as my main editor for my Clojure but it is definitely my favourite of the assortment of Emacs options.
there are also excellent options for vim. and often best to not juggle too many things while learning the language.
Yeah, have tried Spacemacs in the past and did like it, but I'm too much of a tinkerer and tore it all down to a bare Emacs config a few times. Have done that vim too recently, as well as looking at VS Code, etc. Definitely looking for an environment where I can just learn the language - I hadn't actually thought about vin tooling. It never seemed to be that great in the past. Worth a go now??
I use neovim with vim-clojure-static plus vim-sexp, I've used both fireplace and iron.nvim
I like iron expecially lately, a compromise where the repl is easy to send code to, but it doesn't try to be an IDE
How comparable is it to Cider, etc?
but many people love fireplace as well
fireplace offers more IDE style features, and fireplace uses the cider tooling
I find it too "magic" and brittle
but that's just my opinion
Never heard of fireplace or iron. Will check both out. Want to avoid too much tinkering at this stage.
Hi, I'm having some trouble with reify, wanted to use it to mock out a kafka consumer in a test (I'm aware MockConsumer exists but it doesn't implement some functions), simplified down the following to just the bit that complains:
(reify
org.apache.kafka.clients.consumer.Consumer
(poll ^org.apache.kafka.clients.consumer.ConsumerRecords [_ ^long delay]
(org.apache.kafka.clients.consumer.ConsumerRecords. {(TopicPartition. "topic-name" 0)
[]})))
There are two methods in consumer that look like
/**
* @see KafkaConsumer#poll(long)
*/
@Deprecated
ConsumerRecords<K, V> poll(long timeout);
/**
* @see KafkaConsumer#poll(Duration)
*/
ConsumerRecords<K, V> poll(Duration timeout);
I'm therefore trying to add the hints to point to that first one however my code current errors with
Syntax error (IllegalArgumentException) compiling reify* at (form-init1303277116252072083.clj:1:1).
Mismatched return type: poll, expected: org.apache.kafka.clients.consumer.ConsumerRecords, had: java.lang.Object
If I don't include hints I get errors telling me to hint, the return type hint seems to make no difference, and I get the same error with or without it.
Fully qualified things just to prove out that I'm using the correct types everywhere but I don't need it like that.
Anyone know what's going wrong? Thanks!reify type hints the return type on the method name, instead of the args https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/reify
ahh okay, so I have to swap poll
with the type hint like (^org.apache.kafka.clients.consumer.ConsumerRecords poll [_ ^long delay] ...)
Seems to be compiling thanks!
yup, try to resist doing that anywhere else, pretty sure it's only reify that puts the type hint in front
also, I find it much more readable if you use import (in fact that's all import does - just referencing the class causes the load, but the import makes it more readable)
mm yeah, I think that's what caught me out as I'm used to doing it the other way around, I wonder what the reason for the difference is. @noisesmith > Fully qualified things just to prove out that I'm using the correct types everywhere but I don't need it like that Yeah I do agree, just was trying to make sure I wasn't putting the wrong types in anywhere, as I thought the error might have been because I'd had mismatched types from the wrong import
Hi. Why does the last line give an error? i.e. why cannot I use qualified symbol although the symbol exists in the corresponding namespace?
(def x 5)
x ;; 5
user/x ;; 5
(in-ns 'test)
(clojure.core/refer-clojure)
(refer 'user)
((ns-map 'test) 'x) ;; #'user/x
x ;; 5
test/x ;; CompilerException java.lang.RuntimeException: No such var: test/x
I don't think refer does what you think it does
using refer doesn't put the var in your ns, it just makes it so your ns will look it up if referenced in that ns
when you use test from another ns, they don't check the ns-map, they check the ns-publics
(ins)test=> (ns-publics 'user)
{x #'user/x, array-of #'user/array-of}
(ins)test=> (ns-publics 'test)
{}
(ins)test=> (def y 6)
#'test/y
(cmd)test=> (ns-publics 'test)
{y #'test/y}
it's rare that you need this, but there is the function ns-resolve
that looks up 'x
not based on being owned by the ns, but rather the way the ns would look it up
Clojure is really a beautiful language, I wanted to ask how you could make a file-seq while excluding some directories, so I went and look at the source code, and it was a trivial task to perform. Such a beautiful language.
i am also finding that using the source TM is often worthwhile - even if i don't initially understand much of what i see the first time :)
question: I have a 75mb (big?) XML file which I want to convert into CSV and later a database. The XML is 6 levels deep. I have sometimes identical tags on level 2 and level 4 and level 6. Over the recent days I tried to break open the structure using xml-zip. So far I find it extremly challenging. I wonder if it would be better to use clj-xpath. Any opinions?
it depends on the transformation you’re trying to do. I would porbably use something like https://github.com/clojure/data.csv and just use normal clojure data transformations
75mb shouldn’t be too much to handle unless you’re processing a lot of xml files frequently or are running in a constrained environment
after parsing the csv file, I personally would prefer something like https://github.com/redplanetlabs/specter over clj-xpath
I've been going through the Clojure Koans and enjoying that as an intro, does anyone know of a collection of more advanced problems/puzzles for Clojure?
In deps.edn
, how can we have a local git repository?
Try searching for :local/root on this page, and see if it answers your question? https://clojure.org/reference/deps_and_cli
I believe :local/root can point at anything local, whether it happens to be a clone of a git repository or not. i.e.. the local files need not have anything to do with git.
So basically you would copy the repos locally and put it to the correct commit?
I believe so, yes.
If you want to specify a commit in the deps.edn file, you can put in the URL and use :git/url instead, assuming there is URL that you can use to point to, which I suppose could be a private repo if you did not want it to be public.
I have a route defined as (POST "/saml" [:as req] handler)
. Its basically a cut-n-paste from https://github.com/quephird/saml-test. Anyways, everything seems to work fine up until I get the POST response. I get a 404 /saml not found. But if I allow all origins in :cors-allowed-origins
then it works. I guess my question is why can't my app find the route /saml
on a POST. If its a CORS issue, wouldn't the error have been related to cors instead of not found? Why does it work when I allow all origins?
@mario.cordova.862 CORS uses an OPTIONS request so the most likely problem is that you have your cors middleware composed in the wrong order.
(although if changing the allowed origin makes it work, there may be another issue at play here)
Can you show how you are building your middleware stack and how your app/routes are added into that stack?
(def app
(-> (apply routes [home-routes
model-routes
saml-main-routes
(saml-routes sso-config)
app-routes])
(wrap-base-url)
(wrap-cors :access-control-allow-origin (cors-allowed-origins)
:access-control-allow-methods [:get :put :post :delete]
:access-control-expose-headers ["Location"])
(wrap-json-response)
(wrap-json-body {:keywords? true})
(wrap-multipart-params)
(wrap-session)
(wrap-params)
))
Move cors to the end. It usually needs to be the outermost middleware
Hmm, what is (cors-allowed-origins)
? That may actually be too restrictive.
(but, regardless, cors can be problematic in various ways if it isn't the outermost middleware in my experience)
It returns a vector of allowed origins. So something like [[#"localhost:8080"] [#"
I think you should be returning a vector of regexes, not a vector of vectors.
Seems if I add "null" to the allowed origins it works. Since the redirect was sending null in the origin header.
Hmm, that seems... odd...
that would be very easy for an attacker to exploit