Trying to learn “command line tools”. I get a warning if I use lower-case -m
but upper-case -M
gives an error. Wondering what I’m doing wrong here.
use -M -m
(or ignore the warning for the time being)
Hadn’t thought of that, I figured it was an either-or thing. Still trying to decipher the documentation. -M
seemingly executes “clojure.main” (not sure what that means) while -m
executes the main in an explicit namespace.
clojure.main is a java class provided by clojure that runs the clojure compiler
you can pass it a clojure namespace, it will find and load that ns (if possible) and run the -main if it exists
otherwise it executes a repl on stdio
clojure.main itself is very small, it uses RT to execute the compiler: https://github.com/clojure/clojure/blob/master/src/jvm/clojure/main.java#L37
it ends up loading up the clojure.main
namespace (same name, slightly confusing) and running the main
function there: https://github.com/clojure/clojure/blob/master/src/clj/clojure/main.clj#L616
Thanks @noisesmith. -m
claims to run -main
in the passed namespace so I’m trying to figure out why I’d want one instead of the other (or both).
do you want a repl, or to run the -main from a specific namespace?
I don’t want a repl, I just want a headless nrepl to connect to.
clojure -Srepro -Sdeps '{:deps {nrepl/nrepl {:mvn/version "RELEASE"} cider/cider-nrepl {:mvn/version "0.25.5"}}}' -M -m nrepl.cmdline -b 10.0.0.190 -p 34343 middleware "[cider.nrepl/cider-middleware]"
(yours from above i just added the -M
at the appropriate place
then you probably want to run the nrepl.server main, or whatever that's called
oh, ok, nrepl.commandline then
I’ll be connecting from vscode with Calva, so I think I need the cider.nrepl stuff. Still trying to figure all that out.
If you run Calva Jack-in, you can see the command line that Calva builds. You will also see the warning, since we are unsure how to deal with the coming API break. But we'll figure it out.
That is one impressive collection, @jr0cket !!!
Thanks. I borrowed some from Sean, but yes, I did spend a bit of time over the last few months creating and organising this user-level collection of aliases.
yeah nrepl is a bit complex, cider exponentially moreso
ok, thanks everyone. I’ll work with this a bit and read more about calva and dependencies on cider.nrepl and see if I can advance my learning on the topic.
Hi, all. Can anyone please give me a recommendation for what tooling I should use (and how to set it up)? I did a bit of cljs 6 months ago and last year, but every time it feels like I'm starting over again and things have changed. This time I feel more overwhelmed than ever at the number of options. I'm vaguely aware of: leiningen, figwheel, figwheel-main, deps.edn, another thing with 'deps' or 'edn' and a '.' in the name, shadow.cljs, reagent, om, om next, compojure, bidi, chestnut, etc. It's just too much. Every time I try to figure out what to use I find more and more tools or whatever they should be called.
@factorhengineering What do you want to build?
@didibus Thanks. I JUST noticed your replies. (The Slack interface is not great.) I will have to figure out what Luminus and clj-kondo do. So...many...names...
@claudius.nicolae (copied from below) the things I want to create first are (1) educational games that can be run in the browser or stand-alone, with the standalone option maybe required because I want to be able to prevent small children from accidentally exiting the game or messing up the computer in any way (i.e. locking out a lot of special keys and maybe some areas of the screen for the mouse or force fullscreen, with the exit sequence being something that would not happen by accident (kind of like vim LOL) and (2) a utility that can do basic manipulations of an HDMI output (think inverting the picture, but more involved than that).
Read: https://clojure.org/guides/deps_and_cli https://clojurescript.org/guides/quick-start https://figwheel.org/tutorial https://reagent-project.github.io/ http://day8.github.io/re-frame/re-frame/ Start with:
{:deps {re-frame/re-frame {:mvn/version "1.1.2"}}
:aliases
{:repl {:extra-deps {org.clojure/clojurescript {:mvn/version "1.10.758"}}
:main-opts ["-m" "cljs.main" "-c" "myapp.core" "-r"]}
:fig {:extra-deps {com.bhauman/figwheel-main {:mvn/version "0.2.12"}}
:main-opts ["-m" "figwheel.main" "-c" "myapp.core" "-r"]}}}
Use via:
clj -M:repl # cljs plain repl, or
clj -M:fig # figwheel repl, code reload on the fly (incl assets)
PS: Once you are comfortable with the above, consider my tooling https://github.com/tape-framework/doc/blob/master/docs/Tutorial.md (warning: pre.alpha).@claudius.nicolae Thanks. The code above is a little hard to follow with my current level of familiarity. I do see re-frame in there though, whereas I have found myself being steered away from re-frame in favour of...something else I can't recall right this second.
Also hiccup. Pretty sure I want to use hiccup.
The only thing I know for sure is that I want to use Emacs (Doom) with Cider. I also want to try .cljc files for the 1st time, since I love the idea of targetting anything, but really cljs might be enough since browser and maybe mobile are probably enough so feel free to steer me toward just cljs again instead of cljc if it looks like I'm taking on too much.
@factorhengineering For building Single Page Apps with ClojureScript, I suggest using Figwheel-main as it's easier to use than shadow-cljs. You can use JavaScript libraries with either tool, although shadow-cljs is arguably more focused on using npm packages I use figwheel-main for landing pages / single page apps along with Bulma CSS and find it very easy to create nice websites https://practicalli.github.io/clojurescript/ If you use shadow-cljs, set aside time to read the user guide, it's very detailed and should be followed closely https://shadow-cljs.github.io/docs/UsersGuide.html Reagent is the most common library for react.js style apps in ClojureScript and arguably the easiest. Content can be written in hiccup and processed into htlm by reagent. Reagent components are just ClojureScript functions. To configure a Clojure or ClojureScript project, you can use the classic Leiningen build tool or the newer Clojure CLI tools (deps.edn) approach. These tools define project paths and libraries as dependencies. Figwheel-main can use either of these tools, I believe shadow-cljs is only used with Clojure CLI tools (deps.edn) I use Clojure CLI tools as the configuration is just data and it feels simpler to use. In general, either tool can be used with Clojure or ClojureScriptas it does not affect the ClojureScript code you write. The tool choice determines which commands are used to run a repl, run the app, package and deploy the app. https://practicalli.github.io/clojure/ There are many Clojure aware tools, so recommend using what ever is most familiar to you. What ever you choose, read the docs and ask questions in that tools community https://practicalli.github.io/clojure/clojure-editors/
I would say you want to go with tools.deps for Clojure dependencies and build tools, shadow-cljs for ClojureScript dependencies and build tools, VSCode with Calva as your editor (or Emacs with Cider if you know Emacs), and I'd look at Luminus https://luminusweb.com/ for your "web framework". I'd go with the Luminus defaults as well.
And be sure to use clj-kondo with your editor, either Emacs or VSCode.
Lots of examples here of using Clojure CLI and aliases https://github.com/practicalli/clojure-deps-edn Specifically, I created a series of middlewear aliases for running nREPL with Cider/Calva https://github.com/practicalli/clojure-deps-edn#middleware
And if you don't want Luminus, well it would be: reitit, ring, jetty, reagent, re-frame Luminous is just a lein template that sets them up, but since I said to use tools.deps, might be simpler to set them up yourself and not use Luminus.
.cljc
file do not target any platform.
A file with a .cljc
file extension should not contain any code that is platform specific.
.cljc
file contains code that can be used from .clj
or .cljs
code, usually as a library or common code refactored out during development.
Good morning everyone and many seasons greetings! I wanted to ask a question. How Clojure evaluates each of a function's arguments? I mean, is it evaluating eagerly or only when needed? Thank you in advance!
Eagerly
Yes, eagerly, with a minor caveat that eagerly evaluating parameter expressions that return lazy sequences often returns a "lazy sequence" object, and not all elements of the lazy sequence are evaluated before the function is called.
e.g. (reduce + (range 100))
, at the time of the call to reduce, (range 100)
is eagerly evaluated first, but eagerly evaluating the expression (range 100)
does not create the entire 100 elements in memory.
Thank you so much for the explanation! I honestly find myself learning Clojure much quicker than originally anticipated!!!
Initially I was afraid of touching all these parentheses...now I am swearing myself why I haven't learned Clojure earlier!
@jr0cket Thanks. So I can essentially just forget about all of the other tool names I mentioned and be 'fully equipped' if I choose Leiningen/deps.edn + FigwheelMain + Reagent --xor-- shadow-cljs + deps.edn?
In case it matters, the things I want to create first are (1) educational games that can be run in the browser or stand-alone, with the standalone option maybe required because I want to be able to prevent small children from accidentally exiting the game or messing up the computer in any way (i.e. locking out a lot of special keys and maybe some areas of the screen for the mouse or force fullscreen, with the exit sequence being something that would not happen by accident (kind of like vim LOL) and (2) a utility that can do basic manipulations of an HDMI output (think inverting the picture, but more involved than that).
This is enough to give you a very good start. Once you can create working projects and have an editor connected to the REPL you can be very productive in Clojure / ClojureScript There are other interesting libraries and tools to learn about as they are needed. Clojure takes the approach of using specific libraries for specific tasks. Being fully equipped is completely dependent and what you need to be equipped to do. When you have specific things to achieve, then the community can help guide you if you need it.
There are several libraries that can help create graphics and games http://www.quil.info/ https://github.com/oakes/play-cljc
@jr0cket I almost didn't notice your offshoot thread replies. Thanks! I forgot Slack does that. Ha. Thanks. Using an extra library is an extra step I'm not sure I want to get into yet. I was thinking I would do my games from scratch at first since the first ones will be very simple, and just to learn, but I imagine when I want something with physics simulation I would reach out to a library. Do you have any idea what libraries or basic tooling would be best for my other task? ...for, let's say, changing an HDMI output to invert the output image or similar things?
Hi all, sorry if this has been asked and/or answered before, there's some licensing-related discussions to be found online, but nothing definitive in this regard afaics, so here goes: Do I need legal advice to determine whether code emitted by clojure/clojurescript compiler constitutes derivative work of (parts of) the compiler as defined by the EPL¹? I'm probably missing and/or misinterpreting something, but I would expect compilation result to incorporate at least some parts of compiler code (not as separate module) in general case -- macro expansion comes to mind as obvious example -- which afaics would make the situation not necessarily unambiguous or at least the answer not obvious to me. Thankful in advance for possible pointers to more information ¹ https://www.eclipse.org/legal/eplfaq.php#DERIV
@factorhengineering I've wrote a simple tictactoe game with scalable vector graphics (SVG), using the same hiccup syntax as for other web content. Changing the actual HDMI signal coming out from your computer sounds really complex. I assume you need some low level drivers or maybe there is some operating system API that can be used. Way beyond my experience and I suspect most people's experiences.
Also, is there some conceptual reason why vector-of :int cannot (should not/need not?) be made transient or might this change in the future?
Also, is this a known issue or am I missing something?
(ns rrb-test
(:require [clojure.core.rrb-vector :as fv]))
(let [v (vector 1 2 3)
t (transient v)]
[(v 1) (t 1)])
;; => [2 2]
(let [v (fv/vector 1 2 3)
t (transient v)]
[(v 1) (t 1)])
;; => [2 nil]
This is with clojure 1.10.1, org.clojure/core.rrb-vector 0.1.2, zulu openjdk 11.0.9.1 -- I'd expect results above to be the same for vector and rrb-vector.
I didn't find anything whch would explain this on jira or ask.clojure, and github page of rrb-vector claims it supports transient vectors, but since I've never done anything with transients yet, I'd rather ask before posting an issue for something trivial or known..Not an issue that I knew about before. Looks straightforward to fix.
Be warned that there are subtle bugs that I do not know how to fix if you get into lots of subvec and catvec operations on core.rrb-vector vectors. Perhaps they are difficult to hit, but I would not use that library in anything that you were betting your job on.
Does this mean you can reproduce it or/and should I post it somewhere else? And thanks for the info -- and your help! :)
I can reproduce it, and it appears I had started to work on it after someone else reported it a while back, but I had somehow forgotten about it. I will create a ticket for it in the JIRA system if there isn't one already.
Issue created here, and I have committed fixes for it to official code repository (the problem and fixes were pretty straightforward). There will probably be a new release soon-ish if the build box passes all tests. https://clojure.atlassian.net/jira/software/c/projects/CRRBV/issues/CRRBV-30
Team I have below code in my production (reduce #(if-let [outcome (get-in kg [(keyword %2) :employee])]
%)
nil
vars) I did not what will be the value passed to % can anyone help me in this?
whether nil and vars both passed to % ?
while you're learning, rewrite the reducing function as a function literal taking two args (fn [acc var] ...)
. This might help your confusion. Can't quite tell from your snippet but i think nil
is your initial arg? If so acc
will be nil and var
will be the first element of vars
, then acc
will be the result of the first invocation of your function and var
will be the second element of vars
and so on
if the notation #( ... % %2 etc)
gets confusing its a bad use of it. Rewrite it and give your parameters proper names
Hello Team, I wanted to learn architecture of clojure, like how memory handled , Any documentation available? Can anyone suggest me please?
https://docs.oracle.com/javase/specs/jvms/se7/html/jvms-2.html#jvms-2.5.3
https://www.clojure.org/about/rationale is maybe the best place to start
It lays out a lot, including listing memory management as something to be provided by the platform (jvm in this case)
It is an old document, so some of the landscape it is situating itself in has changed in the decade plus since it was written, but as a description of what clojure is and what it does it is great
@popeyepwr , I would also recommend https://download.clojure.org/papers/clojure-hopl-iv-final.pdf as a great resource that covers many of the key ideas behind clojure
Hey, everyone! I've been teaching myself Clojure, using https://adventofcode.com/ as a good way to test my skills. I'm trying to figure out transducers and the transduce
function, but I can't figure out the required arity of the reducing function f
.
The following reduce
function works correctly, where line
is a sequence of navigational directions (`:e`, :ne
, :sw
, etc.), and directions
is a map of the navigational direction to an [x y]
coordinate.
; Works fine
(reduce (partial mapv +) (map directions line))
I'm trying to represent this with the transduce
function, passing in (map directions)
as my xf
. If my reducing function is conj
or str
, I see that I'm getting back a sequence of [x y]
coordinates. I just can't figure out the shape of the function to inject in which will essentially do (mapv +)
on each coordinate with the previous coordinate.
(transduce (map directions) SOMETHING line)
Can anyone help? Most of the online instructions focus on the transducer itself, not the reducing function.what happens if you use (partial mapv +)
as the function? also, I think it's better if you explicitly provide [0 0]
as the init value (it's the identity arg for (partial mapv +) over collections of length 2)
I think (partial mapv +)
will work because it will do the right thing with 1 arg (return a vector of that arg if it's a collection of numbers)
Ah ha! I had tried (partial mapv +)
by itself, and that fails with "Wrong number of args (1) passed to: clojure.core/mapv". But If I combine that with the initial value of [0 0]
, then it works!
right, if no initial arg is provided, the function is called with 0 args to get an init
Thanks, @noisesmith! In general, does that mean that my reducing function has to support arities of both 1 and 2?
but you don't need to generate an init
Oh. So both xf
and f
need to be transducers?
@abyala you can use completing
to generate an arity 1 of identity
no, f shouldn't be a transducer, it needs at least arity 1 and 2 (for completion, and step) and it needs arity 0 if you don't provide init
this is all described in the doc string (which is a bit dense)
(ins)user=> (doc transduce)
-------------------------
clojure.core/transduce
([xform f coll] [xform f init coll])
reduce with a transformation of f (xf). If init is not
supplied, (f) will be called to produce it. f should be a reducing
step function that accepts both 1 and 2 arguments, if it accepts
only 2 you can add the arity-1 with 'completing'. Returns the result
of applying (the transformed) xf to init and the first item in coll,
then applying xf to that result and the 2nd item, etc. If coll
contains no items, returns init and f is not called. Note that
certain transforms may inject or skip items.
nil
I read that several times, but this discussion has helped get more pieces to fall into place for me. Thanks for the help!