This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2017-11-15
Channels
- # beginners (97)
- # boot (54)
- # cider (13)
- # cljs-dev (3)
- # cljsrn (9)
- # clojure (64)
- # clojure-berlin (1)
- # clojure-brasil (119)
- # clojure-dev (3)
- # clojure-france (5)
- # clojure-greece (1)
- # clojure-italy (5)
- # clojure-madison (1)
- # clojure-russia (15)
- # clojure-spec (25)
- # clojure-uk (57)
- # clojurebridge (5)
- # clojurescript (45)
- # code-art (1)
- # community-development (17)
- # cursive (24)
- # datomic (83)
- # emacs (11)
- # fulcro (70)
- # hoplon (7)
- # immutant (3)
- # leiningen (19)
- # luminus (5)
- # lumo (25)
- # onyx (123)
- # other-languages (7)
- # pedestal (2)
- # re-frame (12)
- # ring (15)
- # ring-swagger (51)
- # shadow-cljs (89)
- # spacemacs (23)
- # sql (4)
- # unrepl (57)
- # utah-clojurians (1)
- # vim (1)
hey, if anyone could please help me with my issue in calling cljs files from the lein repl I just posted about it in the leiningen channel. thanks. 🙂
@michael.lombardo what are your questions?
Not saying I can answer them, but I'll listen to them. 🙂
I am just having a problem removing particular keys from an array map. I am not sure which would be the correct function to use.
@michael.lombardo dissoc
is the function that removes keys - but remember that this doesn't change the original map, it creates a new one without those keys
you can also use select-keys
if you'd rather explicitly say the ones you want
If I have an agent
whose work is basically to select/read from non-blocking channels and drop the messages in a core.async/chan
, should I use send
or send-off
?
I know send-off
should be used for potentially blocking I/O operations. I am doing non-blocking stuff, is it ok to use send
?
It seems like, right? Since I’m not blocking the fixed thread pool threads
I agree with you, but I would like to see if someone would not agree and show me the reasons 😅
let’s do it then, for now
@lvbarbosa it’s OK to use send
if you don’t attempt the send unless/until the channel read completes, and the function passed to send does a non-blocking write (eg. put!
)
just clarifying, since this is #beginners
and all, that just because it’s a channel doesn’t make your operation non blocking
Thanks @noisesmith, I did not realize that the >!
could block
it’s parking - which can look like blocking depending how your code is structured
is there a possibility to change the keybindings of the repl that is being invoked by lein repl?
for example, I find repeating commands/ searching the history kind of tedious. In bash and other readline applications i have bound arrow-up to reverse history search of whatever is before the cursor.
Hi @mail185 I use rlwrap lein repl
at the command line. rlwrap
gives you the arrow-up functionality for recalling earlier commands. Works on OS X and Linux
@manutter good idea, thanks for the reply. just added alias repl="rlwrap lein repl"
to my .bashrc
that breaks tab completion, doesn’t it?
or does the rlwrap forward the tab key to the jreadline in the lein repl?
@noisesmith just tried it, tab-completion seems fine.
Hey -- am slowly getting used to writing a small sample -main program and interacting with the REPL (via CIDER and Leiningen). Is there any writeup or explanation of REPL stack levels and such, e.g. when the program wants to exit (but really don't want to (System/exit...) just yet, or would need to hook that and substitute throwing an exception, etc.)? I've worked on CLIs/debuggers in the past that were stack-based, but am not sure the Lein REPL is really set up for that.
it doesn’t do “sub repls” - that’s not how we organize things at all
if you have a -main, and it exits, the vm exits (if you don’t have threads still running)
if your repl is running, -main exits and your repl stays running
I guess if you prefer to use System/exit you could have an optional :prod flag to -main that tells it to explicitly exit, and leave that arg out in the repl
or make -main a small wrapper that calls a secondary main (that you can use from a repl) and also exit explicitly when that exits
Hmm, okay. Would project.clj handle passing the :prod flag in the non-REPL case then? Though I think your final suggestion makes the most sense, since I could then just use (main "arg1" "arg2" ...) in the REPL. (BTW, is there a way to tell the REPL to wrap that up for me, so I can just type <some-run-command> " arg1 arg2 ...", without having to quote the args myself?)
Or, if you application is all built with Component, then your -main
is likely to be something as simple as (component/start (build-system))
which you can execute in the REPL directly.
I tend to have a (comment ...)
form at the bottom of a lot of my files which has the forms I would need to evaluate in the REPL to get a system up and running.
One of the nice things about that workflow is you can run multiple "applications" in a single REPL.
ISTR seeing someone (you?) talk about that on this slack a few days ago? Maybe in a discussion about Atom v Emacs?
For working in the REPL, I don't need to deal with port
and server
so they're hardcoded into the REPL comment. I just place the cursor on each of those forms in turn and hit the "evaluate" hot key, and I have a web app up and running in my REPL and I can develop it by live-eval'ing code into that.
If I do something that means the component needs to be restarted, I can just eval the component/stop
form, then eval the def
again.
(I don't both with New Relic monitoring when I'm running the code locally in the REPL, for example)
That'll definitely be useful when I work on more levels of the stack...right now I'm still just learning the Clojure equivalents, roughly speaking, of C's main().
I would recommend using -main
as just a thin wrapper around the function that is your application -- easier to work with in the REPL (and potentially callable from other code). Then -main
just handles & args
conversion to the arguments that the "application function" would use.
(and if you need fancier arg handling than a few positional arguments, look at clojure.tools.cli
)
Thanks again! On another topic: I've often gotten "CompilerException java.lang.RuntimeException: Unable to resolve symbol: ..." (e.g. for _main) when it turns out the problem is my .clj code file was malformed (missing a close paren or something). Is there some way (maybe this is a #cider question?) to notice and discover "compiler" errors when running cider-jack-in (to start the REPL within CIDER)? I'm probably not asking the right question here (my project.clj has ":main ^:skip-aot ...", which I guess would disable Ahead-Of-Time compilation)....
so this is more of a leiningen question than a clojure question (I think?) - how do i add paths to the classpath? when i set the $CLASSPATH env variable leiningen yells at me and then ignores it.
have you tried :jvm-opts
with the -cp
flag?
@james-clojure When you eval code into the REPL, you will get compiler errors displayed if there's a problem. Clojure compiles all code. It compiles it when you load the namespace.
cider-jack-in
just starts the REPL, it doesn't load any code.
I have noticed that for eval'ing code directly. But the REPL that starts up via cider-jack-in
will have my code in it if it's correct, but won't be able to find it if not, and I'm not noticing any difference in the REPL window that tells me something's wrong.
One mistake I made was to (comment ...) something out near the top of the file, but forgot to add a trailing paren (I'm still new to paredit-mode in Emacs, so don't blame it!). Took me reindenting the entire file to notice the problem. These are among many beginner's mistakes I'm making...been awhile since I Lisp'ed to any significant extent....
We specify clojure.main
as the :main
namespace and avoid AOT completely. Then we use the -m myapp.core
arguments when starting the JAR to tell clojure.main
which namespace to look in for -main
. That also avoids the problem with cider-jack-in
trying to load your main namespace at startup I think.
It's been so long since I've using Leiningen (and Emacs) that I've sort of forgotten some of these problems... 😐
What are you using @seancorfield?
We switched to Boot two years ago and I switched from Emacs to Atom/ProtoREPL just over a year ago.
:thinking_face:
Boot doesn't auto-load your main namespace at startup anyway, which also prevents this sort of issue (we only specify clojure.main
as an entry point when building an uberjar).
My team mate is still an Emacs user tho' 🙂
This made me curious about Boot
I've been an Emacs users for a few decades now but have often had teammates that used vi/vim or whatever was the canonical editor on VAX/VMS. It's good to be tolerant of that sort of thing. 😉
I should give it a try in the next few days
Reading https://www.reddit.com/r/emacs/comments/5jaui7/atom_vs_emacs/ is making me LOL -- "...emacs has a small enough memory profile...", which I guess is true by today's standards. (I go back to before it was parodied as Eight Megs And Constantly Swapping.)
I was an Emacs user back in the 17.x / 18.x days... just after 19.x came out I went off to IDEs but came back to it in the pre-release builds of 24.x after getting started with Clojure.
@james-clojure "Small enough memory footprint" nowadays means does not need a rendering & javascript enginge to run
Yeah, a Chromium clone IIRC. What I don't have a good feel for are the advs/disadvs of that versus all the Emacs code that does the corresponding stuff (rendering and such) -- performance, code reuse, maintainability, etc.
so, I've looked at atom as an emacs replacement because I want simple things like an autocomplete popup that doesn't push all the other text down the page
i am afraid to admit this in a lisp-y place like this. but my daily driver text editor is terminal vim
You could always write an electron app that serves as a renderer for emacs -daemon
I don't really think of Emacs as "lisp-y" -- a Lisp is its extension language, but when I first tried it out, it wasn't.
When I first started looking at Clojure (2010) I was mostly using Eclipse for other stuff but I started with TextMate for Clojure, then tried Sublime Text for a while. I was using a tiny Linux Netbook when traveling (and a big Mac desktop at home) but the hot keys seemed different enough between Linux/Mac in ST that it drove me mad. I even tried Eclipse + CCW for a while (but it ran like a dog on the Netbook). That's when I switched to Emacs. It was an identical experience on Linux/Mac and relatively lightweight. Then I replaced the Netbook with a Windows 8 convertible (Dell XPS 12) -- running Emacs. I still use that (although it's running Windows 10 Fast Ring Insider builds now) and I put up with the fact that Atom has different hot keys on Mac/Windows now 😐
I have a function like this:
(defn generate-times
[]
(do-stuff)
I want to refactor the above to accept 2 arguments, but still support being called without arguments:
;; works
(generate-times)
;; works
(generate-time arg1 arg2)
What would be the best way to do this? multi-arity
or default values
for the args?Would default values make sense?
eg. could you come up with default values that work with (do-stuff)
. or would (.. [] (do-stuff) [arg1 arg2] (do-other-stuff))
make more sense?
Yes, I have default values that work for it. multi-arity
just seemed odd because the same logic would be in both blocks and the only different is one of the values. for example:
(defn generate-times
[]
(5 + 10)
[x]
(x + 10)
Which made me feel a default value would be nice.you can call one arity from the other. So it's kind of like default values.
I'm not sure if there's a community preference.
what does calling one arity from another look like?
(defn generate-times
[]
(generate-times 5)
[x]
(x + 10))
this is almost right but each arity needs a set of parens around it
and the infix should be prefix.
whoa - that is sexy
yeah, I guess that would do it. As you mentioned though, does anyone have any idea about the best practice here?
I think multi-arity is cleaner.