beginners

Getting started with Clojure/ClojureScript? Welcome! Also try: https://ask.clojure.org. Check out resources at https://gist.github.com/yogthos/be323be0361c589570a6da4ccc85f58f.
Andrew Byala 2020-12-30T00:15:38.359100Z

Thanks for the information and the links. I'm working my way through a course on building APIs using Reitit, and once I get past whatever's blocking me right now, I'll try to build a sample API with this pattern in mind.

Sam Ritchie 2020-12-30T00:46:50.360Z

One thing you can do is expose a namespace that requires all of the defmethod-containing namespaces and make it so users require that

Sam Ritchie 2020-12-30T00:47:44.361700Z

Right now it sounds like they are requiring the namespace with the defmulti- maybe stick the defmulti somewhere else, then in this top level NS require all of the namespaces that extend the defmulti

phronmophobic 2020-12-30T01:09:44.362400Z

it seems like there is an implicit dependency between the code calling the multi method and the namespace implementing some corresponding defmethod. it seems like the "right" answer is to make the implicit dependency an explicit dependency (ie. make it so there's no way to call the the multi-method with args you expect it to handle without requiring the namespace that provides the implementation for those args). it's hard to offer more specific advice without knowing a little more about the use case.

Sam Ritchie 2020-12-30T01:15:09.363300Z

@sova this will have the same problem, I believe

dorab 2020-12-30T02:00:30.363500Z

Yikes! I just checked and on my MacOS machine, /opt/intel (where MKL is installed) is around 3GB. Perhaps 22GB is required during installation but not after the installation is complete?

FHE 2020-12-30T02:55:27.364800Z

Hi. Can someone please tell me how to stop a live webpage or whatever it's called?

FHE 2020-12-30T02:55:58.365500Z

I'm trying to learn how to make a webapp and from advice here I turned to Luminus.

FHE 2020-12-30T03:00:47.370100Z

I created a Luminus project using the simple line on the Luminus front page (`lein new luminus myproject`), but after that generated a huge, complicated project folder I figured I need more a guide, so I want to follow through their 'Your First Application' page instead ( https://luminusweb.com/docs/guestbook.html ). That required creating a new project (with lein new luminus guestbook +h2 +immutant), but that threw the error (among others) "Address already in use: bind". I think the problem is the first project is still 'live'.

seancorfield 2020-12-30T03:06:07.370600Z

Just running lein new should not start a web server. What did you run after that?

seancorfield 2020-12-30T03:09:39.372500Z

Unless you are working through the Web Development with Clojure book that is based on Luminus, I would avoid Luminus until you understand the basics of web development in Clojure. Luminus is very complicated -- as you've discovered -- and with +h2 +immutant you are just adding even more pieces that you will need to understand.

seancorfield 2020-12-30T03:10:58.374100Z

Start with just Ring. Build a minimal web server that says Hello, World! when you visit it in a browser. Add Compojure so you can define some routes for GET/POST requests. Add Selmer so you can display HTML pages from Django-like templates, and render data into those pages.

seancorfield 2020-12-30T03:13:33.376700Z

See https://github.com/seancorfield/usermanager-example if you want something that is Ring + Compojure + Selmer + Component + next.jdbc which is the next step from the above. The README there also links to that same example but using Reitit and Integrant instead of Compojure and Component. Reading both of those will give you a good sense of how a basic web app can be written and for some different options for route definition and initialization/lifecycle management.

πŸ‘ 1
1
seancorfield 2020-12-30T03:13:37.377Z

@factorhengineering ^

FHE 2020-12-30T03:23:31.377700Z

From the Luminus front page:

$ lein run
Started server on port 3000

FHE 2020-12-30T03:24:29.378500Z

...and when I point my browser to http://localhost:3000/ I see a local webpage that is the template project.

FHE 2020-12-30T03:25:32.379500Z

I just want to terminate that...so that the NEW project can start a new one (webserver process?)

seancorfield 2020-12-30T03:29:26.380Z

You stop it the same way you stop any process running at the command-line.

seancorfield 2020-12-30T03:29:51.380500Z

@factorhengineering If it's Mac or Linux, use control-c. If it's Windows, use control-z.

FHE 2020-12-30T03:33:37.381500Z

I have a lot of cmd windows open. Guess I'll have to comb through them all and find the one for that project.

FHE 2020-12-30T03:39:43.382400Z

Found it. [Ctrl]+[c] worked to kill it. Successfully ran the 2nd project. Thanks.

FHE 2020-12-30T03:41:50.384300Z

@seancorfield I got conflicting advice on how to start. I took the Luminus suggestion because I had come across about 50 proper names for bits of tooling/libraries/frameworks/unknowns and Luminus seemed like it included a lot.

FHE 2020-12-30T03:47:43.389100Z

Combing through and trying to learn and make sense of a big complicated pre-made project (template?) might not be the best way, but after days and days and days spent just trying to figure out how to set myself up to finally actually start coding in ClojureScript again (I did the quick start guide and completed a very simple webpage with cljs a year or two ago) for something like an actual webapp, I'm just exhausted trying to figure out what each of those 50 bits do and how to put them together.

FHE 2020-12-30T03:49:37.391Z

If things were clearer I would try more of a piecemeal approach, as you suggest, but for now I'm out of patience with that and have to try bending an all-singing-all-dancing sample webapp to my design instead.

seancorfield 2020-12-30T03:49:39.391100Z

Yeah, web dev in Clojure is "simple" but not "easy".

FHE 2020-12-30T03:50:33.392500Z

I mean, unless you insist going with Luminus at this stage is an absolutely terrible idea....

seancorfield 2020-12-30T03:51:39.393700Z

At work, as we've built each new web app, we've refactored parts of previous apps into libraries that allow us to assemble things a bit faster, but we still essentially start with Ring + Component + a routing library (mostly Compojure but we use Bidi on one) + Selmer for HTML templates + next.jdbc for DB access...

seancorfield 2020-12-30T03:53:27.395500Z

I think if you're going to persist with Luminus, and especially if you want to get into ClojureScript as well, you would definitely be doing yourself a favor to buy the book https://pragprog.com/titles/dswdcloj3/web-development-with-clojure-third-edition/ -- the 3rd ed is still in beta but it's mostly finished at this point (I bought one of the early betas and you get updates as they are released).

FHE 2020-12-30T03:53:38.396Z

'Component' is a thing? That makes 51 I've come across.

seancorfield 2020-12-30T03:53:54.396300Z

And for just $26 for the ebooks, that's a bargain.

seancorfield 2020-12-30T03:54:24.396900Z

Component is the oldest and probably most widely used lib for initialization/lifecycle management.

FHE 2020-12-30T04:02:08.398800Z

...and I'm just running into the name now, after Leiningen, Shadow-cljs, deps.edn, tools.deps, boot, datomic, datascript, postgres, hiccup, quill, play-cljc, tailwindcss, nvm, bulma css, clj-kondo, reagent, om, om-next, rum, graal, truffle, cdk-clj, oz, re-frame, petrol, keechma, nativescript, fulcro, crux, hoplon, chord, couchbd, rest, spec, netty, aleph, pedestal, lacinia, hx, hxframe, reitit, http-kit, compojure, bidi, ring, pathom, clj cli tools, chestnut, luminus, h2, immutant, analemma, monet...and that's just writing down the ones I think there's a chance I might want at some point!

seancorfield 2020-12-30T04:02:32.399400Z

So I just ran:

clojure -X:new :template luminus :name guestbook.core :args '["+h2" "+immutant"]'
(which is the Clojure CLI equivalent of your lein new ... command) and then dropped into the new project and did lein run... and it pretty much downloaded the entire internet before it started up an app on port 3000 πŸ™‚ (edited to say port 3000 -- I just noticed it is nREPL that is started on port 7000... it's been so long since I started a process that used nREPL!)

FHE 2020-12-30T04:02:40.399600Z

forgot figwheel and figwheel-main!

FHE 2020-12-30T04:02:44.399800Z

in my list

FHE 2020-12-30T04:04:42.400900Z

Ha ha yes. I'm on a 4k screen at 125% display element size and couldn't believe the downloads didn't fit in a full vertical strip cmd window.

FHE 2020-12-30T04:06:34.402100Z

I'm also looking everywhere in that project folder to try to find the html (or hiccup) file for the webpage it's showing me, and I can't find it. Crazy.

seancorfield 2020-12-30T04:08:12.402500Z

HTML pages are in the resources folder

seancorfield 2020-12-30T04:08:26.402700Z

seanc@DESKTOP-30ICA76:~/clojure/guestbook.core$ tree resources/
resources/
β”œβ”€β”€ docs
β”‚Β Β  └── docs.md
β”œβ”€β”€ html
β”‚Β Β  β”œβ”€β”€ about.html
β”‚Β Β  β”œβ”€β”€ base.html
β”‚Β Β  β”œβ”€β”€ error.html
β”‚Β Β  └── home.html

FHE 2020-12-30T04:11:17.403600Z

I did find that there, but nothing with all the text on the page served up.

FHE 2020-12-30T04:11:26.403900Z

By the way, what does your page read?

seancorfield 2020-12-30T04:11:49.404500Z

The resources folder also has the CSS etc (under public) and the SQL file used by the migrations library...

seancorfield 2020-12-30T04:12:00.405Z

Congratulations, your Luminus site is ready!
This page will help guide you through the first steps of building your site.

Why are you seeing this page?

The home-routes handler in the guestbook.core.routes.home namespace defines the route that invokes the home-page function whenever an HTTP request is made to the / URI using the GET method.
is what I see in the browser.

seancorfield 2020-12-30T04:12:56.406Z

Apparently that's from the docs/docs.md file...

FHE 2020-12-30T04:13:24.406600Z

OK. Same as mine. Good. I thought it would look different than the vanilla project (not guestbook with h2 etc).

seancorfield 2020-12-30T04:13:52.407600Z

Which in turn comes from this function in guestbook.routes.home:

(defn home-page [request]
  (layout/render request "home.html" {:docs (-> "docs/docs.md" io/resource slurp)}))

FHE 2020-12-30T04:13:58.407800Z

I don't see where that html text is coming from though! I've looked at all the /src clj files and all the html files in the folder you mentioned.

seancorfield 2020-12-30T04:14:37.408500Z

home.html has

{% block content %}
  <div class="content">
  {{docs|markdown}}
  </div>
{% endblock %}

seancorfield 2020-12-30T04:14:46.408900Z

and "extends" the base.html template

FHE 2020-12-30T04:14:57.409200Z

I did notice " <div class="content"> {{docs|markdown}} </div>" in one of the .html files, but had no idea where to look from there.

seancorfield 2020-12-30T04:15:38.409900Z

base.html is the "wrapper" with all the &lt;html&gt; &lt;head&gt; ... &lt;/head&gt; &lt;body&gt; .. &lt;/body&gt; &lt;/html&gt; stuff and it contains:

&lt;section class="section"&gt;
          &lt;div class="container"&gt;
              {% block content %}
              {% endblock %}
          &lt;/div&gt;
      &lt;/section&gt;

seancorfield 2020-12-30T04:15:52.410300Z

that's how the content from home.html is pulled in.

seancorfield 2020-12-30T04:17:07.411100Z

This is leveraging Selmer to have a common wrapper page and to override just certain segments of it in "derived" pages.

FHE 2020-12-30T04:17:54.411800Z

How does {docs|markdown} or {% block content %} refer to anything??

seancorfield 2020-12-30T04:19:12.412800Z

In Selmer {{var}} renders whatever value is associated with the key :var in the data (hash map) passed to the render function.

FHE 2020-12-30T04:19:33.413600Z

and why on Earth would the html be in a .md file (which I just found)??

seancorfield 2020-12-30T04:19:34.413700Z

{{var|foo}} applies the filter foo to the value of var before rendering it as a string.

seancorfield 2020-12-30T04:19:59.414500Z

So the markdown filter takes Markdown as input and produces HTML as output.

FHE 2020-12-30T04:20:13.415100Z

It's so obfuscated. What's wrong with an actual html file, and what's wrong with just stating the path and filename of it?

seancorfield 2020-12-30T04:20:21.415300Z

("filter" in Selmer is really a transform -- it doesn't actually filter the input)

seancorfield 2020-12-30T04:20:33.415700Z

Yeah, this is exactly why I tell beginners not to use Luminus πŸ™‚

FHE 2020-12-30T04:21:11.417Z

But seriously, beyond just being terrible for learning, why would even an advanced user want to use markdown that contains html?

seancorfield 2020-12-30T04:22:00.418Z

I'm familiar with most of these libraries after years of using Clojure and even I have to hunt around in the source tree for a Luminus project to figure out what it's doing -- because it is using a bunch of libs I don't know and it wraps up the ones I do know in "unusual" code (i.e., stuff I haven't yet read).

FHE 2020-12-30T04:22:17.418700Z

...and isn't HICCUP the best practice anyway? The Clojure way for generating html?

FHE 2020-12-30T04:22:42.419300Z

I was looking forward to using that.

seancorfield 2020-12-30T04:23:26.420300Z

The markdown doesn't contain HTML. Markdown is a formatting style that can be rendered to HTML. Hiccup turns Clojure data structures into HTML. I find it horrible for collaboration -- I use Selmer so I can use HTML files with substitutions in so that my UI/UX folks can work on the same templates... they could not work with Hiccup.

seancorfield 2020-12-30T04:25:07.421Z

We do also use Hiccup at work, but only for rendering XML that we need to send to a search engine.

FHE 2020-12-30T04:25:54.421800Z

OK most of the .md file might not be html, but it does contain some (`<a class="level-item button" href="https://luminusweb.com/docs/html_templating.html">learn more about HTML templating Β»</a>` and &lt;p class="title is-5"&gt;Organizing the routes&lt;/p&gt;

seancorfield 2020-12-30T04:27:10.422500Z

Sure. Markdown can contain HTML for finer control over formatting than raw markdown provides. That's "standard" with markdown.

FHE 2020-12-30T04:27:37.423Z

The lightbulb brightens a bit more..

FHE 2020-12-30T04:27:48.423400Z

...from about 2% to 2.1%. lol

seancorfield 2020-12-30T04:29:01.425300Z

Some people prefer markdown to HTML when they can get away with it πŸ™‚

FHE 2020-12-30T04:30:42.427400Z

I've never used it. I just helps get bullets or something, is all I know. Seems like kind of a waste of time IMHO.

seancorfield 2020-12-30T04:30:46.427600Z

With that Luminus project example, you know you're in for a lot of learning when the top-level dependency list is:

:dependencies [[cheshire "5.10.0"]
                 [clojure.java-time "0.3.2"]
                 [com.h2database/h2 "1.4.200"]
                 [conman "0.9.1"]
                 [cprop "0.1.17"]
                 [expound "0.8.7"]
                 [funcool/struct "1.4.0"]
                 [luminus-immutant "0.2.5"]
                 [luminus-migrations "0.7.1"]
                 [luminus-transit "0.1.2"]
                 [markdown-clj "1.10.5"]
                 [metosin/muuntaja "0.6.7"]
                 [metosin/reitit "0.5.10"]
                 [metosin/ring-http-response "0.9.1"]
                 [mount "0.1.16"]
                 [nrepl "0.8.3"]
                 [org.clojure/clojure "1.10.1"]
                 [org.clojure/tools.cli "1.0.194"]
                 [org.clojure/tools.logging "1.1.0"]
                 [org.webjars.npm/bulma "0.9.1"]
                 [org.webjars.npm/material-icons "0.3.1"]
                 [org.webjars/webjars-locator "0.40"]
                 [org.webjars/webjars-locator-jboss-vfs "0.1.0"]
                 [ring-webjars "0.2.0"]
                 [ring/ring-core "1.8.2"]
                 [ring/ring-defaults "0.3.2"]
                 [selmer "1.12.31"]]
πŸ‘€

seancorfield 2020-12-30T04:32:00.428800Z

(That's a fraction of what we have in our apps at work tho' -- where we have over 108K lines of Clojure across over three dozen subprojects that we build over a dozen apps from)

FHE 2020-12-30T04:33:58.431Z

It seems like my choices are (a) go from scratch and deal with an endless amount of made-up-name tooling bits and do an epic walk through at least their documentation introduction (to try to figure out what they do and what is in competition with what), and try to cobble them together (and possibly do a whole lot of things manually that could be helped by some unknown tool in the meantime), or (b) start with a super-complicated example and embark in an epic search through the project structure (and maybe documentation on the dependencies once in a while) if I want to make a small change to make the thing look more like the webapp I want.

FHE 2020-12-30T04:34:09.431400Z

What a choice.

FHE 2020-12-30T04:36:21.433600Z

Have you heard much about chestnut? One of those many many cutesy tooling/library/framework/unknown names I came across, but supposed to maybe be some kind of all-singing starting points like Luminus.

FHE 2020-12-30T04:37:04.434900Z

...but maybe a bit simpler? I mean I don't see how it could be more complex!

seancorfield 2020-12-30T04:37:05.435Z

I had heard of it but didn't know what it was. I just looked it up. It's another project template.

seancorfield 2020-12-30T04:37:38.435700Z

I have never used a project template -- other than the bare minimum lib and app -- in a decade of working with Clojure.

seancorfield 2020-12-30T04:39:19.437100Z

I don't do anything with ClojureScript. We looked at it in 2013/2014 and it was pretty horrible, especially in terms of tooling. That's improved a lot and we may try it again next year. I may build a smallish SPA with cljs and I'll start with re-frame and shadow-cljs and see how it goes.

FHE 2020-12-30T04:41:49.438200Z

Why shadow over leiningen (and I think figwheel/figwheel-main? it is in competition with (does the same things as) that too, yes?)?

FHE 2020-12-30T04:42:38.439Z

or over deps.edn?

FHE 2020-12-30T04:43:00.439400Z

err...deps.edn + figwheel-main I guess

seancorfield 2020-12-30T04:44:22.441100Z

I haven't used Leiningen since 2015.

FHE 2020-12-30T04:44:34.441600Z

Similar question: Why re-frame over...(let me check my giant list, hoping I've correctly grouped things that are in competition with each other)...reagent, om-next, or rum?

seancorfield 2020-12-30T04:44:49.441800Z

I switched from Leiningen to Boot in 2015 and then to the Clojure CLI in 2018.

πŸ™Œ 1
seancorfield 2020-12-30T04:45:06.442200Z

re-frame adds structure to reagent, in the same way that Redux adds structure to React.

FHE 2020-12-30T04:45:40.443400Z

Uh-oh...item #52 for my lest. Hadn't come across 'redux' yet. Sigh.

seancorfield 2020-12-30T04:46:20.444300Z

Back when I last did cljs, there was Om and Reagent (and Reagent was new). My team built an app with Om and then rebuilt it with Reagent and we liked Reagent better (and I contributed to it a bit back then). re-frame is newer and builds on top of Reagent.

πŸ™Œ 1
FHE 2020-12-30T04:46:21.444600Z

It's like whack-a-mole with these tooling/etc names.

Sam Ritchie 2020-12-30T04:46:37.445300Z

@factorhengineering is this different from the rest of the software ecosystem?

seancorfield 2020-12-30T04:47:07.446100Z

Redux is a JS framework or at least a structured way of working with React when you have a data store and you are managing events and changes, as I recall.

Sam Ritchie 2020-12-30T04:47:21.446800Z

There is not a central planning committee here that is fumbling their planning ;)

Sam Ritchie 2020-12-30T04:47:50.447700Z

Lots of fun and interesting personalities and history behind why all of these exist

seancorfield 2020-12-30T04:47:57.447900Z

My reading of re-frame is that it's basically "Redux" in a cljs context, built on Reagent, whereas Redux is built on React -- and Reagent is a cljs wrapper for React πŸ™‚

seancorfield 2020-12-30T04:49:18.450600Z

@factorhengineering remind me, what's your programming background before Clojure? I'm curious as to what sort of ecosystem you're used to elsewhere...

FHE 2020-12-30T04:49:20.450800Z

I just +1d two really helpful comments of yours above. I thought I had to choose between re-frame, reagent, om-next, and rum. Good to know re-frame subsumes reagent.

FHE 2020-12-30T04:49:47.452Z

Also nice to hear your lein-to-boot-to-cljcli experience.

Sam Ritchie 2020-12-30T04:49:57.452400Z

@factorhengineering still better than the energy bar situation here in Boulder! 100s of choices. (Didn’t mean my comment to be negative, I am smiling with you since of course you’re right that this is bewildering)

FHE 2020-12-30T04:50:06.452700Z

Why does Luminus only mention lein and boot then, btw?

FHE 2020-12-30T04:51:07.453800Z

It's so nice to be laughing with other people about this instead of crying that on hour 100 or so of my latest foray into cljs I still haven't written a single line of it.

seancorfield 2020-12-30T04:51:10.453900Z

Luminus predates the Clojure CLI and hasn't adapted to it yet.

Sam Ritchie 2020-12-30T04:52:12.455200Z

I think many folks find a build setup (after much struggle with cljs for example), and then that becomes their personal project template for new work

seancorfield 2020-12-30T04:52:34.456300Z

I have harassed the maintainers of project I use to offer CLI support or I've sent them PRs. I haven't had much incentive to do that with Luminus πŸ™‚

seancorfield 2020-12-30T04:54:35.457300Z

The only thing that makes me sad about shadow-cljs is that it sort of expects node.js to be installed. And every time someone installs node.js, a kitten dies 😞

seancorfield 2020-12-30T04:56:25.458Z

Maybe I'll start with figwheel-main instead since it supports the Clojure CLI and doesn't seem to require node.js?

seancorfield 2020-12-30T04:56:40.458400Z

(everything has changed since I last looked at cljs!)

FHE 2020-12-30T04:57:59.458800Z

What's wrong with node.js?

FHE 2020-12-30T04:58:27.459300Z

I did try to use shadow.cljs about 6 months ago, but that fizzled. So complicated.

FHE 2020-12-30T04:59:21.460400Z

Had a kind soul here link me to his personal walkthrough on setting up a simple thing, and further walk me through it, but I was just typing in set-up commands without them making sense. πŸ˜•

FHE 2020-12-30T05:01:33.462300Z

A-a-nd I just created yet another project without editing the previous one at all. Ha. I just decided to take chestnut for a spin, hoping it might split the different between from-scratch and uber-sample-project.

FHE 2020-12-30T05:03:18.464100Z

Ran lein new chestnut projectnam +re-frame<-- That extra argument based on your hint, @seancorfield. The default is Reagent, but with the argument it can do re-frame instead.

FHE 2020-12-30T05:03:54.464800Z

It looks a bit simpler than Luminus. It only downloaded a quarter of the internet.

FHE 2020-12-30T05:04:57.465600Z

@sritchie09 Of course I have to poll you too... πŸ™‚ What do you use? Do you deal with ClojureScript at all or only Clojure?

FHE 2020-12-30T05:06:22.466900Z

Hey the /src folder in a chestnut project is further divided into /clj /cljs and /cljc. Cool. I like the idea of cljc.

seancorfield 2020-12-30T05:12:38.470300Z

@factorhengineering I just tried figwheel-main:

seanc@DESKTOP-30ICA76:~/clojure$ clojure -X:new :template figwheel-main :name hello-world.core :args '["--reagent"]'
...
seanc@DESKTOP-30ICA76:~/clojure$ cd hello-world.core/
seanc@DESKTOP-30ICA76:~/clojure/hello-world.core$ clojure -M:fig:build
...
[Rebel readline] Type :repl/help for online help info
Opening URL <http://localhost:9500>
(browser opens at this point)
ClojureScript 1.10.773
cljs.user=&gt; (js/alert "Am I connected?")
nil
(browser shows that alert) I edited src/hello_world/core.cljs per the comment in the browser and saved it
[Figwheel] Compiling build dev to "target/public/cljs-out/dev-main.js"
[Figwheel] Successfully compiled build dev to "target/public/cljs-out/dev-main.js" in 0.464 seconds.
[Figwheel] Outputting main file: target/public/cljs-out/dev-main-auto-testing.js
This text is printed from src/hello_world/core.cljs. Go ahead and edit it and see reloading in action.
(sure enough, I see new text in the browser immediately!)
cljs.user=&gt; (require '[hello-world.core :refer [app-state]])
nil
cljs.user=&gt; (swap! app-state update :text str " More text!")
{:text "New text! More text!"}
(see the text change in the browser in real time)
cljs.user=&gt; (swap! app-state update :text str " More text!")
{:text "New text! More text! More text!"}
(browser updates to show new text!) OK, this seems fun. I think I'll go down this path when I need to build a cljs app.

seancorfield 2020-12-30T05:35:13.471600Z

Hmm, pity that by default the test runner uses the same port as running the app. Luckily adding

:ring-server-options {:port 9555}
to test.cljs.edn fixes that (but it took me a bit of grepping to figure that out)

FHE 2020-12-30T05:56:23.472Z

@seancorfield Reading through your posts now...

FHE 2020-12-30T05:57:36.473400Z

About to give up for the night, but in the meantime, if you feel like taking a quick peek at chestnut and seeing whether you think it's (a) good and (b) good for a newbie, that would be much appreciated (as has been the whole discussion with you tonight).

FHE 2020-12-30T06:00:02.475700Z

By the way, I ran lein new chestnut +re-frame +http-kit +bidi +garden (heard re-frame better than default reagent, heard http-kit better than default jetty, heard bidi better than default compojure, and garden for clj(s) css syntax)

FHE 2020-12-30T06:01:50.477300Z

Running the command in the readme.md file it generates (

clojure
(go)
(cljs-repl)
) does not seem to work the way it says it should, though. Nothing to see on localhost:10555 (nor localhost:3449).

raspasov 2020-12-30T06:07:43.479700Z

@seancorfield @factorhengineering I am a fan of figwheel-main, esp. for browser-based React app it’s a no-brainer; after a lot of React experience (+ React Native) I eventually settled on managing my own state and doing direct React interop from Cljs… but for a first project something like Reagent might be easier

raspasov 2020-12-30T06:10:33.480900Z

@factorhengineering I fully support @seancorfield’s suggestion to go easy on the frameworks to start; just like @seancorfield said following what’s described at https://github.com/seancorfield/usermanager-example should be enough to get you going

Gleb Posobin 2020-12-30T06:12:23.481400Z

Have you tried shadow-cljs? How is it lacking compared to figwheel?

FHE 2020-12-30T06:27:42.485300Z

I also just ran lein new projectname fulcro (before seeing your comment, @raspasov). It downloaded almost nothing (far less than chestnut and far, far less than luminus). The folder-and-file structure seems at least a bit less complex than chestnut's and luminus' as well. Would be interested in your opinion on that too, @seancorfield, if you feel like littering your computer with yet another project folder as I have many times tonight.

Gleb Posobin 2020-12-30T06:31:27.490500Z

Fulcro is hard to get into, I have been coding in clojure&cljs since March, and have decided to rewrite my re-frame app in fulcro 10 days ago, struggling a lot right now. Unlike re-frame&reagent, where you can be productive after a ~day of reading their docs. It is a lot to take in even without having to learn the rest of the stack and the language itself.

seancorfield 2020-12-30T06:31:40.490800Z

Based on what I just tried this evening: shadow-cljs relies on node/npm/npx, figwheel does not -- that's a huge win for figwheel for me.

FHE 2020-12-30T06:33:08.492Z

I see your suggestion, @raspasov, so I gather that the https://github.com/seancorfield/usermanager-example (and https://github.com/PrestanceDesign/usermanager-reitit-integrant-example) are even lighter starting points than all 3 of the 'frameworks' I've set up projects using (luminus, chestnut, fulcro)? I don't see a lein command for setting them up, though, so I would have to figure out how to start with them (just git commands I guess)...and now that I look further I see I would have to figure out how to install the 'clojure cli' too?

Gleb Posobin 2020-12-30T06:33:40.492200Z

It is very easy to use js libs from shadow though, I think figwheel might have some troubles with that?

seancorfield 2020-12-30T06:34:22.493200Z

@factorhengineering both of those usermanager examples assume you're using the official Clojure CLI rather than Leiningen.

seancorfield 2020-12-30T06:35:10.494400Z

You could manually add a project.clj file to them and use lein if you want...

FHE 2020-12-30T06:35:35.494900Z

@posobin I winced at your comment "re-frame&reagent, where you can be productive after a ~day of reading their docs" (but to be fair to myself I'm not even set up to the point of being able to write any code yet, so who knows yet) but regardless you've successfully scared me off fulcro. Thanks for helping me whittle down the options.

seancorfield 2020-12-30T06:36:08.495400Z

@posobin Yeah, I assumed that was the "big difference" but I think I'd rather eschew JS libs for now...

seancorfield 2020-12-30T06:36:24.495900Z

(I find the whole JS ecosystem thoroughly unpalatable)

FHE 2020-12-30T06:37:53.497900Z

I don't necessarily want leiningen. I'm just familiar with it a bit, having seen it make it easy for me to make a bunch of projects with different frameworks appear on my computer tonight (and using it for the initial creation of the project folder for the simple webapp I made last time around).

seancorfield 2020-12-30T06:38:29.499400Z

Based on the last hour of playing around, I have to say that re-frame looks really nice! So I think when I'm ready to do cljs again, it'll be re-frame and figwheel-main at this point πŸ™‚

βž• 1
lassemaatta 2020-12-30T06:39:38.002300Z

I might be wrong, but I have a feeling shadow-cljs can run without npm. If I remember correctly, that's how I ran it last year when doing cljs stuff. Sure, the user guide suggests using the npx thing, but you can install it as a jvm library and invoke it through lein / deps (see https://shadow-cljs.github.io/docs/UsersGuide.html#_library & https://shadow-cljs.github.io/docs/UsersGuide.html#deps-edn)

FHE 2020-12-30T06:39:46.003200Z

and none of that requires leiningen? Based on a couple of command line commands you pasted above it seems like lein commands can be substituted with just slightly more complicated clojure commands.

seancorfield 2020-12-30T06:39:51.003500Z

@factorhengineering my feeling about lein and the Clojure CLI is that the CLI is officially supported, and officially documented on http://clojure.org and that means it'll be more and more popular over time so you might as well install and use it for projects that support it (or even require it).

euccastro 2020-12-30T06:40:04.004Z

reagent+re-frame are probably the most used options currently, so you're most likely to be able to get help with that. both figwheel-main and shadow cljs are well supported as well

dharrigan 2020-12-30T06:40:37.005800Z

I concur, a while ago I put together a very simple little show-and-tell using re-frame, reagent, reitit, next.jdbc - didn't take long at all, and I found it a pleasant experience.

seancorfield 2020-12-30T06:40:50.006300Z

@factorhengineering I don't use Leiningen -- unless I have to in order to help a beginner debug a problem.

seancorfield 2020-12-30T06:41:49.007700Z

@dharrigan I assume with figwheel that you run separate front end and back end REPLs / processes? (I haven't gotten that far with it yet)

FHE 2020-12-30T06:41:50.007800Z

I had a failed attempt at trying shadow-cljs earlier this year. The farther I got into the long usage guide the more the fog rolled in around me. Not totally discounting it, but it kind of makes me want to try something else this time.

FHE 2020-12-30T06:42:08.008600Z

Still...my main issue remains knowing what all the parts and options really are to begin with.

seancorfield 2020-12-30T06:42:17.008900Z

I got the impression that shadow-cljs was somewhat all-encompassing in that it would start both front end and back end pieces together?

FHE 2020-12-30T06:42:48.009800Z

Shadow sounded great. It would need a second stab at it by me though.

seancorfield 2020-12-30T06:43:08.010500Z

@lasse.maatta Ah, good to know. Thanks. So I may yet consider it at some point...

euccastro 2020-12-30T06:43:10.010700Z

that's not how I use it. you can do that with either shadow-cljs or figwheel-main, but you don't have to. whatever ring support is there is just a convenience

FHE 2020-12-30T06:43:18.010900Z

Name #53 to add to my list: next.jdbc

euccastro 2020-12-30T06:43:34.011400Z

#54: crux! πŸ˜„

FHE 2020-12-30T06:43:56.011700Z

crux is on my list already. πŸ˜‰

dharrigan 2020-12-30T06:44:12.012100Z

Hi, yes, that is correct. I admit, I'm not really a "frontend" type of developer, so perhaps there are better ways. However, having separate repls worked very well for me to do a bit of learning.

seancorfield 2020-12-30T06:44:36.012700Z

It sounds nice and simple -- and I'm a big fan of "simple".

dharrigan 2020-12-30T06:44:41.013Z

πŸ™‚

FHE 2020-12-30T06:45:08.014Z

It in the spreadsheet column under 'other', i.e. among those I know the least about or think I am least likely to need. Who knows, though? πŸ˜›

seancorfield 2020-12-30T06:45:10.014100Z

@factorhengineering if you get around to next.jdbc at some point, the #sql channel will be a good resource for you πŸ™‚

seancorfield 2020-12-30T06:45:36.014900Z

(if you want to do anything with an RDBMS/SQL database, you'll use next.jdbc)

FHE 2020-12-30T06:46:32.015600Z

Really? How is it so late on my list then? Ha ha. The whack-a-mole game continues...

FHE 2020-12-30T06:47:53.017200Z

When you say in your...template(?) "This example assumes that you have the https://clojure.org/guides/deps_and_cli installed", is that really a separate installation?

euccastro 2020-12-30T06:48:39.017600Z

https://clojure.org/guides/getting_started

dharrigan 2020-12-30T06:48:41.017900Z

To add to @seancorfield excellent example, I humbly present my own little take, which uses juxt clip and reitit for frontend and backend <https://github.com/dharrigan/startrek> and <https://github.com/dharrigan/startrek-ui>

euccastro 2020-12-30T06:49:09.018800Z

that's where you install it. it is not "separate" from Clojure, but it's separate from @seancorfield's template

euccastro 2020-12-30T06:49:35.019800Z

although you can use Clojure without installing that, so in that sense it is "separate"

seancorfield 2020-12-30T06:49:50.020400Z

Yeah, what @euccastro said. http://clojure.org has the Getting Started guide, the "deps and CLI" guide, and the "deps and CLI" reference -- because the clj / clojure commands are the official CLI from Cognitect.

FHE 2020-12-30T06:50:56.021300Z

Oh wait, I finally found the installation instructions. Powershelling now...

euccastro 2020-12-30T06:52:15.022600Z

in case you haven't seen it, this is pretty crucial too: https://clojure.org/guides/repl/introduction

FHE 2020-12-30T06:52:41.023500Z

I mean...first have to figure out what I'm supposed to set my JAVA_HOME environment variable to....

euccastro 2020-12-30T06:53:19.024400Z

why do you think you have to set that?

seancorfield 2020-12-30T06:54:09.025900Z

@factorhengineering here's your (long) list updated with the stuff crossed out that I think you can safely ignore to get started: Leiningen, Shadow-cljs, deps.edn, tools.deps, boot, datomic, datascript, postgres, hiccup, quill, play-cljc, tailwindcss, nvm, bulma css, clj-kondo, reagent, om, om-next, rum, graal, truffle, cdk-clj, oz, re-frame, petrol, keechma, nativescript, fulcro, crux, hoplon, chord, couchbd, rest, spec, netty, aleph, pedestal, lacinia, hx, hxframe, reitit, http-kit, compojure, bidi, ring, pathom, clj cli tools, chestnut, luminus, h2, immutant, analemma, monet -- plus I would add component, selmer, next.jdbc

FHE 2020-12-30T06:54:12.026Z

"Make sure https://aka.ms/wmf5download (or later, include https://aka.ms/pscore6) and https://www.microsoft.com/net/download (or later) are installed. Also install Java 8+ and set JAVA_HOME in your environment variables. Then run:"

seancorfield 2020-12-30T06:54:53.027200Z

I thought you were on Mac/Linux? Install the Clojure CLI there. Don't try to deal with Powershell.

FHE 2020-12-30T06:55:18.028Z

Oh no. Totally glossed over the .net thing. Ugh. Always so many hoops to jump through. Oh and of course my JAVA_HOME is already set, but it's to JDK 11 even though I jsut installed 8? Sigh.

FHE 2020-12-30T06:55:35.028500Z

I'm on Windows.

euccastro 2020-12-30T06:55:53.029400Z

JDK 11 is fine. why do you want 8?

seancorfield 2020-12-30T06:55:53.029500Z

Even on my Microsoft Surface Laptop 3, I do not use Powershell. I do everything on Ubuntu via WSL2.

FHE 2020-12-30T06:56:06.029800Z

Unless I line up a bunch of new tasks and finally get Linux dual booting on this somewhat new-ish computer.

seancorfield 2020-12-30T06:56:24.030600Z

You do not need to dual boot

FHE 2020-12-30T06:56:26.030800Z

...or that. Find out more about what WSL is all about.

seancorfield 2020-12-30T06:56:57.032100Z

When you were showing your shell stuff above, you had a $ prompt so I assumed it was macOS or Linux πŸ™‚

euccastro 2020-12-30T06:57:25.032800Z

off @seancorfield's list you can probably further cross out either Compojure or reitit, since both do routing

FHE 2020-12-30T06:57:41.033400Z

Is it like a VM, or can you actually shut down and restart and come back to things...like on a part of your disk space theretofore dedicated to WSL/Linux?

seancorfield 2020-12-30T06:58:09.034200Z

Yup, I was just leaving those as both useful options since reitit is data-focused and compojure isn't @euccastro

FHE 2020-12-30T06:58:15.034400Z

Oh that $ was just from me quoting the front page of the luminus website.

seancorfield 2020-12-30T06:59:00.035700Z

@factorhengineering I think in a cmd window or Powershell you can just type bash and it will set up WSL2 for you, as long as your Windows 10 install is up to date?

FHE 2020-12-30T07:00:25.036900Z

BTW I have gathered that the following are in competition: pedestal, reitit (how do people pronounce that??), compojure, bidi (frontrunner AFACT), ataraxy, keechma

FHE 2020-12-30T07:01:02.037800Z

...and I have a bunch more names of things that might be 'routing libraries' too.

dharrigan 2020-12-30T07:01:06.038100Z

@factorhengineering as in route-it

seancorfield 2020-12-30T07:01:19.038500Z

Keechma is a "micro-framework for Reagent" so I wouldn't say it was a routing library.

seancorfield 2020-12-30T07:01:28.038800Z

Nor is Pedestal.

euccastro 2020-12-30T07:01:39.039600Z

@ikitommi said "ray-tit", but it may have been tongue-in-cheek?

FHE 2020-12-30T07:02:00.040600Z

I'm sure I read the git page for something calling itself a routing library referring to those as also routing libraries. Ha.

seancorfield 2020-12-30T07:02:00.040700Z

reitit, compojure, and bidi are comparable. I would recommend reitit or compojure.

dharrigan 2020-12-30T07:02:00.040800Z

Finnish pronouciation?

FHE 2020-12-30T07:02:30.041500Z

Haha after I had kind of settled on bidi (through descriptions alone).

seancorfield 2020-12-30T07:02:52.042Z

@factorhengineering it's probably best to "just pick one" and not worry about alternatives -- pick the most popular one and move on.

lassemaatta 2020-12-30T07:02:59.042100Z

Nope, that's the proper Finnish pronunciation of it

πŸ‘ 1
dharrigan 2020-12-30T07:03:29.042400Z

Ah-ha!

dharrigan 2020-12-30T07:03:30.042600Z

πŸ™‚

Shantanu Kumar 2020-12-30T08:08:36.086100Z

Actual Calfpath link is this: https://github.com/kumarshantanu/calfpath and a comprehensive coverage of routing libraries here: https://purelyfunctional.tv/mini-guide/clojure-routers/

FHE 2020-12-30T07:04:54.043600Z

so confusing.

seancorfield 2020-12-30T07:05:02.044Z

That's being very generous...

euccastro 2020-12-30T07:05:03.044100Z

some of those do routing + more

FHE 2020-12-30T07:05:18.044400Z

How do I know what's the most popular?

seancorfield 2020-12-30T07:05:23.044600Z

Compojure is far and away the most popular.

seancorfield 2020-12-30T07:05:41.045200Z

You can look at stars/watches/forks on github or downloads on http://clojars.org

FHE 2020-12-30T07:06:58.046900Z

OK, I've heard of stars. ...but doesn't that leave out the time element? i.e. favour things that are or were popular at any point in time, not specifically now?

FHE 2020-12-30T07:07:05.047200Z

do stars 'fade'?

seancorfield 2020-12-30T07:07:39.048500Z

compojure has 8.something million downloads on http://clojars.org, bidi has 900K, reitit has 400K

euccastro 2020-12-30T07:07:41.048700Z

my feeling is that it's losing popularity to reitit, in part because the latter is data-based as opposed to macro-based

euccastro 2020-12-30T07:08:05.049600Z

but it's just an unsubstantiated impression

FHE 2020-12-30T07:08:26.050200Z

Is there a d-star/d-time derivative stat? lol

euccastro 2020-12-30T07:08:31.050400Z

reitit will also work in the browser side if you want that

euccastro 2020-12-30T07:10:38.053600Z

if you are unsure you could start with manual routing. for simple websites that should work well enough, and it might help you understand what these libraries are doing

FHE 2020-12-30T07:10:56.054100Z

I might try to hack something---anything--together by twiddling with the chestnut project until I have the patience to figure out WSL (or install .net and fix what version of java my java_home variable points at).

FHE 2020-12-30T07:11:15.054600Z

I'm really foggy on what routing even is.

euccastro 2020-12-30T07:11:36.055700Z

take a ring request, decide what function will handle it

FHE 2020-12-30T07:11:39.055800Z

The current projects I have in mind are both stand-alone.

lassemaatta 2020-12-30T07:12:07.056600Z

FHE, if it's any consolation I remember going through the same kind of "there's too many libraries in this ecosystem (and some of them are obsolete!)" hassle when first learning enterprise java (and later javascript) years ago

FHE 2020-12-30T07:12:13.056800Z

ring request?

FHE 2020-12-30T07:12:29.057500Z

Also, do I need 'ring'? Another name on my list.

euccastro 2020-12-30T07:12:57.058200Z

a ring request being a Clojure map with information about a web request, most importantly the path and any headers

seancorfield 2020-12-30T07:12:58.058400Z

@factorhengineering Ring is fundamental to web apps in Clojure. Pretty much everything else is built on Ring.

seancorfield 2020-12-30T07:13:19.059300Z

This is why I said: start with a bare bones app with just Ring and nothing else.

πŸ‘† 1
FHE 2020-12-30T07:13:35.060Z

Built-in, or separate install (or dependency to add)?

euccastro 2020-12-30T07:14:29.061700Z

https://github.com/ring-clojure/ring

seancorfield 2020-12-30T07:14:36.062300Z

When my Clojure Provo talk is put online -- after my London talk -- you'll be able to see what it looks like to start from a minimal app and add just Ring and build a simple web app. Although I'm sure others have done such videos online.

FHE 2020-12-30T07:15:28.063300Z

Sorry. I don't remember you saying that. I've heard a lot of things lately. It sounds like your usermanager template is close to that, though.

seancorfield 2020-12-30T07:15:59.064200Z

Sure, usermanager = Ring + Compojure + Selmer + Component + next.jdbc

FHE 2020-12-30T07:16:48.065300Z

It mentions just https://github.com/stuartsierra/component, https://github.com/ring-clojure/ring, https://github.com/weavejester/compojure, and https://github.com/yogthos/Selmer. I kind of know what selmer is (from luminus) and ring (now). Not sure about the other 2.

FHE 2020-12-30T07:17:07.066100Z

...or...3? next.jdbc isn't mentioned on that list.

seancorfield 2020-12-30T07:18:04.067700Z

https://github.com/seancorfield/usermanager-example/blob/develop/deps.edn -- it use SQLite for the actual DB (but it easily could be h2 or postgres) and it does depend on http-kit but that is totally optional (it's really just to show how interchangeable jetty and http-kit are).

FHE 2020-12-30T07:18:06.067800Z

Oh there it is, mentioned later. That's to do with the database for the app?

seancorfield 2020-12-30T07:18:34.068400Z

Yes, next.jdbc is the Clojure JDBC wrapper.

seancorfield 2020-12-30T07:18:56.069200Z

(it supersedes org.clojure/clojure.java.jdbc which I used to maintain)

FHE 2020-12-30T07:19:20.070Z

Is there a simple way to describe what component and compojure do?

seancorfield 2020-12-30T07:19:32.070300Z

@factorhengineering you didn't answer my earlier question about your programming background? what languages are you used to?

seancorfield 2020-12-30T07:20:14.072300Z

Component is a library to help you manage the lifecycle (start/stop) of dependencies in your app (such as database connection pools, caches, web servers, etc).

seancorfield 2020-12-30T07:20:30.073200Z

Compojure is a routing library -- it maps URLs to functions in your code.

FHE 2020-12-30T07:20:36.073400Z

I worked on an Android app in Java a long time ago. I've done other Java too, but that doesn't mean I'm heavy into OOP.

FHE 2020-12-30T07:20:46.073700Z

I've done a bit of Python.

FHE 2020-12-30T07:21:05.074700Z

I've done some other things.

euccastro 2020-12-30T07:21:18.075400Z

component manages the lifecycle of stateful things like web servers. in his presentation about this stuff @seancorfield just started the server manually by calling run-jetty. so I'm not sure you need it to get started https://ring-clojure.github.io/ring/ring.adapter.jetty.html#var-run-jetty

FHE 2020-12-30T07:21:25.075700Z

html, css, a bit of js, turbopascal LOL

euccastro 2020-12-30T07:21:40.076200Z

ring is like Python's WSGI

seancorfield 2020-12-30T07:21:52.076400Z

OK, just asking so we can try to relate some of this Clojure stuff back to other stuff you know... but it sounds like you're pretty much a beginner across all languages really, so maybe there aren't going to be good reference points for you?

FHE 2020-12-30T07:22:30.077100Z

I don't recognize 'WSGI', if that confirms my polyglot beginner status. Ha.

seancorfield 2020-12-30T07:23:48.079200Z

OK, my battery is at 12% and my G&T is empty so I'm off to bed (got to be up early to go walking and get my five miles in before work!). Will no doubt chat more with you tomorrow πŸ™‚

πŸƒ 2
FHE 2020-12-30T07:24:57.080500Z

I've messed around a bit with a lot of stuff, like regex and perl, and I've watch about 40 videos on clojure and clojurescript. I feel like I know more about the high-level language design things then how to just actually get going. Though I do have a clojure webapp I made that I use at work a fair amount.

FHE 2020-12-30T07:25:52.081300Z

It's a weird place to be. Motivated but paralyzed. Will try again soon. If not tomorrow then probably on the 1st at the latest.

FHE 2020-12-30T07:26:16.081800Z

Talk to you again soon. Goodnight!

euccastro 2020-12-30T07:47:23.082700Z

@factorhengineering here's a minimal example of a working web application, with manual/no routing: https://github.com/euccastro/minimal-web

euccastro 2020-12-30T07:48:17.083800Z

it just echoes back the ring request generated when you visit http://localhost:3000/echo, or a 404 not found if you visit anything else

euccastro 2020-12-30T07:49:10.085100Z

once you understand that fully we can talk about the next step, which would maybe be to add a routing library

euccastro 2020-12-30T07:49:57.085500Z

it does use deps.edn though, so it requires the Clojure CLI installed

euccastro 2020-12-30T07:51:22.085700Z

(or maybe the next step is to add hiccup or selmer so you don't need to build the HTML by hand; whatever hurts the most πŸ™‚ )

euccastro 2020-12-30T07:53:56.085900Z

there are one or two important things to understand in that example, though, like the use of #'http-handler for REPL-friendliness, and the use of a rich comment block to show example usage

popeye 2020-12-30T08:56:57.087100Z

I have written below code

popeye 2020-12-30T08:56:58.087300Z

(defn count-a-with-regex [body] (let [regex (re-pattern var-regex)] (map (fn [input] (println "input -- " (type input ) ) (dbg (count (re-find regex input)))) (str body))))

popeye 2020-12-30T08:57:11.087500Z

and calling using (count-a-with-regex " Hello world hi world")

popeye 2020-12-30T08:57:40.087900Z

I am passing string but getting converting to java.lang.CharSequence

popeye 2020-12-30T08:58:07.088400Z

why my string is converting to charseq?

popeye 2020-12-30T09:01:35.088900Z

you can test in repl

euccastro 2020-12-30T09:11:54.089800Z

use re-seq

euccastro 2020-12-30T09:12:58.091Z

if you want to count occurrences of the regex in the string

euccastro 2020-12-30T09:14:17.093300Z

re-find gives you a single occurrence. iterating over that (i.e., a string) gives you a sequence of characters

euccastro 2020-12-30T09:16:30.095500Z

if you want to count the characters of a singleoccurrence, re-find is fine

zackteo 2020-12-30T09:52:43.100500Z

Has anyone encountered this issue where code (tests) runs perfectly fine in the repl, even in the case of a fresh repl but once you do lein cloverage it throws a java.lang.IllegalArgumentException: no JSON input found when that is an impossible path to execute (I even have a try catch block :x Am I right to understand that this is the compiler's static analysis that is executing all code regardless of whether it is a possible path of execution or not? Context: https://github.com/zero-one-group/fxl/pull/16/checks?check_run_id=1625450943

popeye 2020-12-30T10:12:42.101Z

@euccastro re-seq returned ([${hello} hello] [${hi} hi] )

popeye 2020-12-30T10:13:11.101600Z

how can i fetch only ${hello} and ${hi}

euccastro 2020-12-30T11:04:12.102900Z

@popeyepwr what is your regex? if it doesn't have groups you should just get the string matches:

(re-seq #"\w+" "one two three")
;; =&gt; ("one" "two" "three")

euccastro 2020-12-30T11:05:31.103900Z

anyway, one way to get only the ${hello} and ${hi} out of your result would be (map first (re-seq ,,,))

popeye 2020-12-30T11:07:51.104900Z

Thanks @euccastro, I know it may be basic question... I am still practising clojure

πŸ‘ 1
euccastro 2020-12-30T11:12:40.105600Z

np @popeyepwr, this is the channel for those πŸ™‚

Klavs Klavsen 2020-12-30T12:33:27.108400Z

(ns clojure-sandbox.core)

(def mylist
  ({:a 1 :b 2 :c 3}
   {:a 1 :b 5 :c 6}
   {:a 7 :b 8 :c 12}
   {:a 10 :b 11 :c 12}))

println mylist
Gives me: Unable to resolve symbol: mylist in this context When trying to compile (alt+enter) in vscode.. The same code ran fine yesterday.. I'm assuming "something" was cached, so this appearently now invalid code wasn't invalid yesterday 😞 Now I just removed a (def foo...) that was in the file - so it only contains the above - and now it fails with: "Unbound: #'clojure-sandbox.core/mylist"] Any tips as to whats up? I'm really not feeling helped with that error 😞

2020-12-30T12:35:46.109600Z

Your code isn't valid. Try putting a ' before the bracket for mylist

(def mylist 
  '({:a 1 :b 2 :c 3}
   {:a 1 :b 5 :c 6}
   {:a 7 :b 8 :c 12}
   {:a 10 :b 11 :c 12}))

(println mylist)

2020-12-30T12:36:34.110Z

You should have got an error when you tried to compile what you pasted though, I think.

Klavs Klavsen 2020-12-30T12:47:24.111200Z

I ran it yesterday and it returned the changed results as it should (all b's had the same content as c in that same map).. Today I opened up vscode and alt+enter and it broke..

Klavs Klavsen 2020-12-30T12:47:37.111400Z

thats really frustrating 😞

Klavs Klavsen 2020-12-30T12:48:03.111600Z

With the ' in front of the list - it runs and ofcourse returns nothing.. Whats wrong with the above ?

Klavs Klavsen 2020-12-30T12:50:00.111800Z

it works as a vector

2020-12-30T12:50:02.112Z

So, without the ' in front of the list. It thinks that its a function call. You CAN call a map as a function, and pass it a key as the argument and get the value back for that key. However in your case it thinks you are calling it with 3 arguments. There isn't a map as a function with arity of 3 arguments. So it errors. > I ran it yesterday and it returned the changed results as it should (all b's had the same content as c in that same map).. Today I opened up vscode and alt+enter and it broke.. Do you have more code that you haven't shown?

Klavs Klavsen 2020-12-30T12:50:10.112200Z

(changing () to [] around the maps)

2020-12-30T12:50:54.112400Z

e.g.

({:a 5 :b 6 :c 7} :a)
;=&gt; 5

({:a 5 :b 6 :c 7} :z :not-found)
;=&gt; :not-found

Klavs Klavsen 2020-12-30T12:51:07.112600Z

no - its just a project created by: lein new clojure-sandbox

2020-12-30T12:51:43.112800Z

Putting the ' in front of the list quotes it, you are saying it isn't a function call, its a list.

Klavs Klavsen 2020-12-30T12:51:48.113Z

(def mylist
  [{:a 1 :b 2 :c 3}
   {:a 1 :b 5 :c 6}
   {:a 7 :b 8 :c 12}
   {:a 10 :b 11 :c 12}
   ])

(map (fn [m] (assoc m :b (m :c))) mylist)
Works

Klavs Klavsen 2020-12-30T12:52:25.113200Z

so doing '({:a ... should make it a list ?

Klavs Klavsen 2020-12-30T12:53:17.113400Z

repl must somehow be running "parts of the old" or something yesterday

2020-12-30T12:53:32.113600Z

If you change the code you will have to resend it to the REPL

Klavs Klavsen 2020-12-30T12:53:39.113800Z

alt+enter doesn't do that ?

2020-12-30T12:54:06.114Z

I don't know VSCode sorry, so I don't know what alt-enter does?

Klavs Klavsen 2020-12-30T12:54:23.114200Z

"evaluate top level form(defun)"

Klavs Klavsen 2020-12-30T12:54:36.114400Z

I was told to run that yesterday πŸ™‚

2020-12-30T12:55:19.114600Z

(def mylist
'({:a 1 :b 2 :c 3}
 {:a 1 :b 5 :c 6}
 {:a 7 :b 8 :c 12}
 {:a 10 :b 11 :c 12}))
=&gt; #'stuarts.2020day16/mylist
(map (fn [m] (assoc m :b (m :c))) mylist)
=&gt; ({:a 1, :b 3, :c 3} {:a 1, :b 6, :c 6} {:a 7, :b 12, :c 12} {:a 10, :b 12, :c 12})

(def mylist
  [{:a 1 :b 2 :c 3}
   {:a 1 :b 5 :c 6}
   {:a 7 :b 8 :c 12}
   {:a 10 :b 11 :c 12}])
=&gt; #'stuarts.2020day16/mylist
(map (fn [m] (assoc m :b (m :c))) mylist)
=&gt; ({:a 1, :b 3, :c 3} {:a 1, :b 6, :c 6} {:a 7, :b 12, :c 12} {:a 10, :b 12, :c 12})
But yes, putting the ' in front of the list to quote it, will work. But I think generally you probably want a vector over a list.

πŸ‘ 1
Klavs Klavsen 2020-12-30T12:57:06.114900Z

Thank you

pez 2020-12-30T13:15:13.115100Z

Calva will use the Clojure REPL to evaluate the form. There is no extra magic there, so something must have been different with the code yesterday, if it compiled w/o error.

Klavs Klavsen 2020-12-30T13:16:12.115300Z

It ran with alt+enter and gave the expected output. I then just opened it today - and it failed compiling.. Sounds to me like some sort of caching of functions going on :(

pez 2020-12-30T13:22:11.115500Z

Calva isn’t caching anything. You could have evaluated some working version of mylist, though. That would make (println mylist) β€œwork”. And that working definition would be gone today, if you have restarted the REPL. This is a quite common problem when getting used to Clojure. I still trip on it at times, for sure.

2020-12-30T14:44:27.122600Z

Hi, I'm trying to get start my first full-stack clj web app. I've followed this guide that combines heroku deployment and datahike for the backend, and was able to generate a web app hosted on heroku: https://nextjournal.com/kommen/datahike-heroku-datalog-clojure-web-app. now I need to figure out how to 1) connect a repl to it, and 2) include figwheel/reagent to the stack for cljs. my app so far is on github: https://github.com/jollyblondgiant/datahike-heroku and attempting to connect to repl by calling heroku run lein repl as described in the heroku/clj guide https://devcenter.heroku.com/articles/getting-started-with-clojure#start-a-repl-on-a-dyno results in an error that "project.clj" doesn't exist. TL;DR I'm trying to start a full stack web app and have some questions: 1. what is your preferred workflow to start a mobile/web app with datalog and reagent? are there better options? what are they and how do I start them up? 2. what is missing from my app as it is that I can't start a repl?

practicalli-john 2020-12-30T15:00:42.127200Z

@andy482 Heroku run will spin up a new container, using the image build during deployment. Not sure why you want to connect a repl to a copy of the app. Do you need a full stack app? There is more scalability in having a backend API and separate front-end apps. Back end and front end have different loads and resources, very inefficient to scale them as one monolithic app

2020-12-30T15:02:10.128600Z

I'm working on day 16 of advent of code, I've arrived at this data structure.

([0 "row"] [1 "class"] [1 "row"] [2 "class"] [2 "row"] [2 "seat"])
Is their an easy way to transform that into this:
[[0 "row"] [1 "class" "row"] [2 "class" "row" "seat"]]
Or should I look at changing the function that creates the initial structure to better collect the results?

2020-12-30T15:03:30.129500Z

I use list comprehension to get those initial results, maybe I can change this?

(defn get-satisfied-rules [rules ticket-items]
  (for [rule rules
        ticket ticket-items]
    (if (satisfies-rule? rule ticket)
      [(first ticket) (first rule)])))
Can I collect the results into groups in the for ?

2020-12-30T15:05:21.131200Z

(group-by first) looks like it almost gets me there

{1 [[1 "class"] [1 "row"]], 2 [[2 "class"] [2 "row"] [2 "seat"]], 0 [[0 "row"]]}

nnichols 2020-12-30T15:06:39.131300Z

Is it possible to use heroku run to invoke a tools.deps alias? You could add + deploy an alias with nrepl (or whaterever) as an extra dependency

2020-12-30T15:09:57.131600Z

what's your preferred workflow for setting up such a system?

2020-12-30T15:14:17.132200Z

Got it!

(let [data [[0 "row"] [1 "class"] [1 "row"] [2 "class"] [2 "row"] [2 "seat"]]]
  (reduce (fn [acc [i rule]]
            (update acc i conj rule)) {} data))
;=&gt; {0 ("row"), 1 ("row" "class"), 2 ("seat" "row" "class")}
Is their a better way?

2020-12-30T15:15:30.132400Z

to your question-- I want to connect to a repl to start adding test data to my app.

2020-12-30T15:16:15.132700Z

if you replace conj with (fnil conj []) you'll get a vector instead of a list

2020-12-30T15:16:37.132900Z

it might be, but I couldn't tell you how as I am pretty nooby still.

2020-12-30T15:18:18.133700Z

oh cool! thanks!

2020-12-30T15:21:20.135300Z

aaah, so my way by saying (update acc i conj rule), if the entry doesnt exist in the map it passes nil to conj and

(conj nil 2)
;=&gt; (2)
but fnil is saying if the second argument is nil to replace the nil with [].

2020-12-30T15:21:21.135500Z

neat!

2020-12-30T15:21:46.135700Z

well, first argument, but yes

2020-12-30T15:21:56.135900Z

yes, sorry first argument!

2020-12-30T15:22:36.136100Z

fnil is quite handy

(ins)user=&gt; ((fnil + 1 2) 2 nil)
4
(ins)user=&gt; ((fnil + 1 2) nil 2)
3

2020-12-30T15:24:00.136400Z

thats like creating a function with default arguments!

nnichols 2020-12-30T15:34:23.136500Z

This is a sample alias you could add to your deps.edn:

:nrepl   {:extra-deps {nrepl/nrepl {:mvn/version "RELEASE"}}
                     :main-opts  ["-m" "nrepl.cmdline"]}
then, after it’s deployed, you could try running it with:
heroku run clojure -M:nrepl
then you should see its connection info pop up

euccastro 2020-12-30T16:04:35.136700Z

if you have the DB locally in your dyno you will lose it whenever you update your app

euccastro 2020-12-30T16:04:56.136900Z

you need an external DB, at which point you should be able to connect to it from your dev machine

euccastro 2020-12-30T16:08:30.137100Z

oh wait, IIUC you're using a Heroku postgresql backend, right? that'll work, but you should figure out how to connect to that [P.S.: I meant to the postgres DB, not to the Heroku app] from a REPL in your own dev computer. you should be able to

2020-12-30T16:20:02.137500Z

lol that's why I came here; thanks though

2020-12-30T16:49:14.137800Z

this gets me a repl!! thanks so much! I'm going to make sure there's a note that you helped get past this spot. is "nick from clojurians-slack" fine for credit?

βœ… 1
nnichols 2020-12-30T16:55:20.138100Z

Nice! Glad it worked out. Since my first name isn’t all that unique I usually use my GH username: nnichols

euccastro 2020-12-30T17:33:48.138500Z

IIUC you should be able to use the very code you're using in production Heroku, just find the environment variable(s) you use to access Postgres here: https://devcenter.heroku.com/articles/config-vars

euccastro 2020-12-30T17:36:24.138800Z

if you really want to connect to the Heroku app itself this might work: https://devcenter.heroku.com/articles/debugging-clojure

euccastro 2020-12-30T17:37:05.139100Z

but I've worked with Clojure projects deployed to Heroku for a while and I've never found the need to do that

2020-12-30T18:01:34.139500Z

what's your preferred stack/workflow when starting a new app? I'm embarking on my first and could use advice. Thanks!

practicalli-john 2020-12-30T18:49:10.139800Z

@andy482 this is the basics of my workflow with Heroku https://practicalli.github.io/clojure-webapps/projects/banking-on-clojure/

2020-12-30T18:51:16.140Z

holy cow thanks

practicalli-john 2020-12-30T18:52:05.140200Z

For test data, I would use a test database provisioned against a test app.

practicalli-john 2020-12-30T18:52:30.140400Z

Still lots to add, feel free to ask questions...

practicalli-john 2020-12-30T18:53:27.140600Z

I will be updating the Clojure specs as I got a bit carried away with the design

roelof 2020-12-30T21:04:29.142600Z

Can I do clojure development on Windows or can I better use linux ?

seancorfield 2020-12-30T21:05:12.143200Z

@roelof You can but generally macOS and Linux are better supported by tooling and libraries.

seancorfield 2020-12-30T21:05:59.144100Z

I do a lot of Clojure work on a Windows laptop -- but I run all of the Clojure stuff on Ubuntu via WSL2. I use VS Code on Windows, with the Remote-WSL2 extension which is pretty slick.

seancorfield 2020-12-30T21:06:55.145300Z

(Windows has always been a second-class citizen in the Clojure world -- because most Clojure devs who work on tooling and library use macOS or Linux)

roelof 2020-12-30T21:06:56.145500Z

oke, that is what I do also. Use wsl2

ajoberstar 2020-12-30T21:07:45.147300Z

For non-WSL Windows use, I've been using deps.clj instead of the official Clojure CLI.

seancorfield 2020-12-30T21:07:49.147500Z

I think the combination of VS Code on Windows and running Clojure stuff on WSL2 is really solid. I run VcXsrv (Xlaunch) so that I can run GUI apps from the Linux side (Reveal, mostly, but sometimes also Google Chrome).

roelof 2020-12-30T21:07:59.147800Z

@seancorfield and then as extension use calva

seancorfield 2020-12-30T21:08:33.148900Z

I use Clover -- which is a version of Chlorine, ported from Atom to VS Code -- and I use a plain Socket REPL instead of nREPL.

roelof 2020-12-30T21:08:36.149Z

I then have to figure out how I can easily surround or replace a parentheses

seancorfield 2020-12-30T21:09:37.150Z

Hmm, I thought Calva included paredit and/or parinfer which handled that sort of thing? You could ask in #calva (or #vscode for general VS Code Qs).

ajoberstar 2020-12-30T21:11:10.150600Z

Yeah, Calva does default to Paredit on, I believe. They have nice visual docs on the default commands. https://calva.io/paredit/

πŸ™Œ 2
roelof 2020-12-30T22:13:49.151500Z

thanks all, GN