beginners

Getting started with Clojure/ClojureScript? Welcome! Also try: https://ask.clojure.org. Check out resources at https://gist.github.com/yogthos/be323be0361c589570a6da4ccc85f58f.
2020-12-24T00:02:13.346900Z

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.

dpsutton 2020-12-24T00:10:14.347400Z

use -M -m

dpsutton 2020-12-24T00:10:24.347700Z

(or ignore the warning for the time being)

2020-12-24T00:29:01.349500Z

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.

2020-12-24T00:55:47.350100Z

clojure.main is a java class provided by clojure that runs the clojure compiler

2020-12-24T00:56:21.350600Z

you can pass it a clojure namespace, it will find and load that ns (if possible) and run the -main if it exists

2020-12-24T00:56:40.350900Z

otherwise it executes a repl on stdio

2020-12-24T00:59:48.351400Z

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

2020-12-24T01:01:28.352100Z

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

2020-12-24T01:36:18.354300Z

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).

2020-12-24T01:37:14.355300Z

do you want a repl, or to run the -main from a specific namespace?

2020-12-24T01:37:39.355800Z

I don’t want a repl, I just want a headless nrepl to connect to.

dpsutton 2020-12-24T01:39:18.358Z

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]"

dpsutton 2020-12-24T01:39:31.358400Z

(yours from above i just added the -M at the appropriate place

👍 1
2020-12-24T01:39:37.358500Z

then you probably want to run the nrepl.server main, or whatever that's called

2020-12-24T01:39:54.359200Z

oh, ok, nrepl.commandline then

2020-12-24T01:40:09.359600Z

I’ll be connecting from vscode with Calva, so I think I need the cider.nrepl stuff. Still trying to figure all that out.

pez 2020-12-24T08:25:10.409100Z

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.

pez 2020-12-24T08:25:38.409800Z

That is one impressive collection, @jr0cket !!!

practicalli-john 2020-12-24T12:01:40.410600Z

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.

2020-12-24T01:40:45.360300Z

yeah nrepl is a bit complex, cider exponentially moreso

2020-12-24T01:42:06.361Z

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.

FHE 2020-12-24T06:41:44.371700Z

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.

clyfe 2020-12-24T09:41:15.410400Z

@factorhengineering What do you want to build?

FHE 2020-12-25T07:00:32.448900Z

@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...

FHE 2020-12-25T07:01:05.449100Z

@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).

clyfe 2020-12-25T09:33:43.449800Z

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).

FHE 2020-12-26T22:25:44.005900Z

@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.

FHE 2020-12-24T06:42:29.372Z

Also hiccup. Pretty sure I want to use hiccup.

FHE 2020-12-24T06:46:44.373100Z

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.

practicalli-john 2020-12-24T07:25:08.404500Z

@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/

2020-12-24T07:35:08.404700Z

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.

2020-12-24T07:36:00.404900Z

And be sure to use clj-kondo with your editor, either Emacs or VSCode.

practicalli-john 2020-12-24T07:36:36.405100Z

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

👏 1
2020-12-24T07:44:13.405500Z

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.

practicalli-john 2020-12-24T07:45:08.405700Z

.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.

Panagiotis Mamatsis 2020-12-24T12:09:11.413300Z

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!

2020-12-24T14:00:36.413500Z

Eagerly

2020-12-24T14:59:00.413700Z

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.

2020-12-24T15:01:42.413900Z

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.

Panagiotis Mamatsis 2020-12-24T15:53:14.414100Z

Thank you so much for the explanation! I honestly find myself learning Clojure much quicker than originally anticipated!!!

Panagiotis Mamatsis 2020-12-24T15:54:10.414300Z

Initially I was afraid of touching all these parentheses...now I am swearing myself why I haven't learned Clojure earlier!

FHE 2020-12-24T16:18:30.416600Z

@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?

FHE 2020-12-24T16:21:30.419900Z

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).

practicalli-john 2020-12-24T16:25:30.420Z

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.

practicalli-john 2020-12-24T16:28:31.420200Z

There are several libraries that can help create graphics and games http://www.quil.info/ https://github.com/oakes/play-cljc

FHE 2020-12-24T16:55:25.424500Z

@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?

2020-12-24T18:50:50.425300Z

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

practicalli-john 2020-12-24T19:00:27.425800Z

@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.

2020-12-24T19:04:29.426700Z

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?

2020-12-26T19:22:36Z

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..

2020-12-26T21:51:23.003800Z

Not an issue that I knew about before. Looks straightforward to fix.

2020-12-26T21:52:13.004100Z

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.

2020-12-26T22:02:10.004400Z

Does this mean you can reproduce it or/and should I post it somewhere else? And thanks for the info -- and your help! :)

2020-12-26T22:27:38.006100Z

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.

👍 1
1
2020-12-27T02:26:57.010Z

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

🏎️ 1
popeye 2020-12-24T19:13:11.428Z

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?

popeye 2020-12-24T19:14:07.428500Z

whether nil and vars both passed to % ?

dpsutton 2020-12-24T19:16:30.430500Z

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

🙌 1
dpsutton 2020-12-24T19:17:21.431300Z

if the notation #( ... % %2 etc) gets confusing its a bad use of it. Rewrite it and give your parameters proper names

popeye 2020-12-24T19:54:22.431800Z

Hello Team, I wanted to learn architecture of clojure, like how memory handled , Any documentation available? Can anyone suggest me please?

2020-12-24T20:02:25.432700Z

https://www.clojure.org/about/rationale is maybe the best place to start

2020-12-24T20:04:18.434800Z

It lays out a lot, including listing memory management as something to be provided by the platform (jvm in this case)

👍 1
2020-12-24T20:05:37.436800Z

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

phronmophobic 2020-12-24T20:41:31.438100Z

@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

🙌 1
Andrew Byala 2020-12-24T21:31:21.439400Z

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.

2020-12-24T21:38:43.441200Z

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)

2020-12-24T21:39:27.442Z

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)

Andrew Byala 2020-12-24T21:41:38.443Z

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!

2020-12-24T21:42:07.443700Z

right, if no initial arg is provided, the function is called with 0 args to get an init

Andrew Byala 2020-12-24T21:42:10.444Z

Thanks, @noisesmith! In general, does that mean that my reducing function has to support arities of both 1 and 2?

2020-12-24T21:42:13.444100Z

but you don't need to generate an init

Andrew Byala 2020-12-24T21:42:27.444600Z

Oh. So both xf and f need to be transducers?

2020-12-24T21:42:50.445100Z

@abyala you can use completing to generate an arity 1 of identity

2020-12-24T21:43:25.445800Z

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

2020-12-24T21:46:38.447Z

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

Andrew Byala 2020-12-24T21:49:04.447700Z

I read that several times, but this discussion has helped get more pieces to fall into place for me. Thanks for the help!