This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2020-05-23
Channels
- # announcements (5)
- # aws (9)
- # babashka (60)
- # beginners (561)
- # calva (8)
- # cider (17)
- # clj-kondo (1)
- # cljsrn (12)
- # clojure (36)
- # clojure-dev (3)
- # clojure-europe (3)
- # clojure-france (10)
- # clojure-greece (8)
- # clojure-italy (6)
- # clojure-spec (3)
- # clojure-uk (6)
- # clojurescript (30)
- # community-development (2)
- # conjure (15)
- # datascript (24)
- # figwheel-main (49)
- # fulcro (29)
- # helix (72)
- # off-topic (20)
- # pathom (7)
- # rum (7)
- # shadow-cljs (23)
- # spacemacs (6)
- # sql (8)
- # timbre (1)
- # xtdb (10)
nah, you both have slightly different profile pictures, so not a bot that just copied an avatar, so I suspect you are both spammers
it showed up as a double join in the slack ui "Nicole Kathrine joined #beginners along with Nicole Kathrine." but if I click on each name and view full profile and click the '...' I can see the member id which is different for each one
Both deleted!
Please do not engage with spammers. Just let the Admins know and we'll deactivate them and clean up.
When using lein's :profile
mechanism - does providing a :user
profile override whatever exists at .lein/profile.clj
?
Hey folks. I just installed Emacs (for the second time. I tried it for a week or two last year) and Doom, and I am going to try to see what CIDER involves, because I heard Emacs+CIDER is the best way to do Clojure and ClojureScript.
...but I don't know what other tools I need, besides having tried Leiningen and FigWheel when I tried CLJS for a hot minute last year and went through the http://clojurescript.org quickstart guide and then wrote one tiny (but useful to me) program.
I have heard of npm and shadow.cljs as well, but I don't know if I need those, and if either of those tools would be instead of either Leiningen or FigWheel or along with them or what. ...and if there are other tools I should use (instead or in addition). Can someone please give me a quick breakdown of what tools do or even just recommend a set?
Note: I want to focus on clojurescript right now, but I am pretty sure I will want to do Clojure soon.
Cursive or VSCode is more beginner friendly in my opinion, but I won't stop anyone from learning Emacs (which is the editor I use)
You have two choice of tool for ClojureScript, either figwheel-main with tools.deps or shadow-cljs
In theory though, you don't need anything else but Java and Clojure. Clojure now comes with a dependency manager called tools.deps. With it you can add a dependency on Clojure and ClojureScript.
But because using the ClojureScript compiler directly is difficult, and because people want a good in-browser REPL with hot-reload, everyone ends up adding either shadow-cljs or figwheel-main to their setup.
I'm taking the same approach with Blender, and being farther along the curve I'm happy with my choice there.
The difference between the two is that figwheel-main works directly with tools.deps and is "closer" to the standard ClojureScript compiler. Shadow-cljs has more magic on top and handles everything itself to make things easier.
Hey @factorhengineering. The tooling can certainly be confusing. There are many tools and they overlap in slightly different ways
Leiningen is an alternative to tools.deps, it can also be used with figwheel-main, but I would say it is losing popularity, especially for ClojureScript, I wouldn't bother with it.
It is true yes. But you can happily use shadow-cljs for ClojureScript and tools.deps or lein for Clojure.
Leiningen going away? Wow. In my quest to pick a language to learn, a huge thing in the plus column was supposed to be that while other languages need a confusing array of tools, in clojure(script?) you only need one: Leiningen.
I did come across the fact that figwheel was replaced with figwheel-main. ...but that change made it cljs only?
At this point VS Code, Atom, and neovim all have really solid clojure offerings at this point — use whatever you’re most comfortable with.
Figwheel is a tool specifically for helping with developing ClojureScript applications
I just spent, seriously, about 20 hours over multiple days figuring out how to install Emacs and Doom. I'm going to stick with it for a while at least. lol
The stock ClojureScript compiler doesn’t handle hot reloading, or a bunch of other things that are nice to have for development
I had worked with figwheel, figwheel-main, and shadow-cljs for a TUI template. Shadow-cljs was by far the easiest, most streamlined, and best documented experience but they’ll all work… eventually 😄
The important thing is that figwheel only handles making ClojureScript development nicer - it doesn’t handle installing dependencies, or building a class path, or any of the things that a tool like leiningen does for you
and is CIDER a given? I'm assuming all the options available to me (given Emacs as a starting point) involve CIDER
Shadow-cljs is an all-in-one solution - it handles dependencies, build configuration, compiling, development things like hot reloading
> figwheel [...] doesn’t handle installing dependencies, or building a class path, or any > of the things that a tool like leiningen does for you ...but that extra stuff could be handled by the (relatively new?) tool.deps, though, yes?
Cider handles connecting emacs to an nREPL server. Shadow has built in support for creating an nREPL server when watching a build to let you interact with the running app.
Yes, you can use leiningen or tools.deps with figwheel to build a project and manage dependencies
It’s just a protocol for connecting to a REPL. It’s what CIDER and a lot of other tools use
nREPL is a networked REPL. It’s what lein starts when you run lein repl
but liliactown’s right. Not particularly important.
I'm not quite getting what tools.deps does. It's in direct competition with Leiningen? ...and shadow.cljs also can take their place?
• you can use shadow-cljs to build, manage your deps, and do hot reloading • you can use leiningen / tools.deps + figwheel for building, managing your deps, and doing hot reloading
(as someone who has done Clojure for a decade but has hardly touched ClojureScript, this is fascinating because the cljs ecosystem has changed dramatically over that time and I wouldn't have the first clue what to recommend to a beginner!)
Tools.deps just installs dependencies and builds a class path. Leiningen does much more; it has a whole plugin system
shadow.cljs is easier/better, but leiningen/tools.deps + figwheel has the advantage of also working with Clojure?
(tools.deps is "just" a library -- it's used by the "Clojure CLI" and you'll see references to deps.edn
which is "just" a description of dependencies -- like the :dependencies
vector in Leiningen's project.clj
file and :aliases
which are a bit like Leiningen's profiles)
It’s also fine to have shadow-cljs for ClojureScript and another project setup (leiningen or tools.deps) for Clojure
When you (or was it didi...?) said Leiningen was losing popularity, was that just for ClojureScript development, or for Clojure as well?
Leiningen is the oldest and still most popular build tool for Clojure.
The Clojure CLI / deps.edn
is newer but it is official -- from the core team -- whereas Leiningen has always been a community project.
Use whatever the tutorials you are following suggest and see how you get on, would be my advice.
There's some fundamentals to understand: 1. ClojureScript dependencies are supposed to be deployed to a Clojure repository such as Maven. 2. tools.deps lets you declare dependencies from Clojure repositories such as Maven. 3. JavaScript dependencies are not in Maven by default, but in NPM. 4. Some people have gone through the trouble of uploading JS dependencies to Maven, this is known as the cljsjs repo. 5. ClojureScript and JavaScript dependencies that are in Maven can be declared with tools.deps and used directly from ClojureScript without issues. 6. If you need to use a JS dependency that is not in Maven, things get complicated, because JS dependencies have no common standard. 7. Shadow-cljs is specialised in handling JS dependencies not found in Maven, and making them easy to use. 8. The ClojureScript compiler can also pull down npm dependencies, and use them, but it often requires more fiddling then shadow-cljs. 9. Beyond dependency management, there are other things we want our build tools to do for ClojureScript. Some of those things are: hot-reload of ClojureScript, HTML and CSS. Simple dev server to serve our website from. And manage various compilation configurations for dev, prod, etc. 10. Figwheel-main handles all the things in #9 but doesn't manage dependencies at all. It leaves that up to tools.deps and ClojureScript to do so. 11. Shadow-cljs handles all the things in #9 and also handles JavaScript dependencies from NPM.
(Thanks to @didibus @lilactown and now @seancorfield for coming to my rescue BTW. I'm a little burnt out from the EMacs and Doom installation being so hard to figure out. lol)
So for a newbie who wants to do CLJS but probably also CL, would you recommend shadow.cljs or lein(+figwheel in the CLJS case)?
and then when you want to learn CLJ (note the J, it’ll help with googling - CL means something else)
and then coming back to lein later (and never coming back to fig)? OK. I guess my hope of learning one set of tools for both is not quite the best option. Good to know.
Ignore that wall of information -- not relevant for the questions you are asking at the moment.
Nothing like git, no.
Just ignore all that npm/maven stuff -- not important for where you are right now.
https://whimsical.com/GMjukovFXrYzG4d8TcGk7P does this visual help?
If shadow handles all the things mentioned in points 9. and 11. above, then what is tailwind?
@jayzawrotny Actually I don't see how that applies at all. 😕
tailwind is a CSS framework and completely unrelated to any of the tools discussed so far. shadow does not give you any out of the box styling for your website
Aww bummer, I was trying to visualize the relationship between emacs, cider, shadow-cljs, your app, and nrepl. Then show how the various build tools overlap. Anyone have any suggestions to make it more clear?
@seancorfield If that Maven/NPM info isn't applicable to me now and shouldn't affect my choice of tooling, then sure I'll ignore it. 🙂 ...but I really don't mind considering the end game when deciding on what to learn.
Part of the problem is that there is a HUGE ecosystem in the background of all this (Clojure/Script) but it only really becomes relevant when you start to think about publishing libraries really. So it's all a bit confusing when you're getting started.
Maven is where Clojure(Script) libraries get published. NPM is where JavaScript libraries get published
All of the tools allow you to install Clojure(Script) libraries. Different tools have different ways of handling JavaScript libraries
@jayzawrotny It seems like you linked me to a diagram on a completely different subject TBH. Is the image supposed to me about accounts and passwords??
@lilactown Are there any NPM libraries in particular you think I would miss if I miss out on NPM?
@jayzawrotny If I click on the whimsical link instead of the preview window or whatever that is, yes I get a completely different image, and yes it's helpful. 🙂 Is there a reason the lein and figwheel boxes are kind of just floating in the middle, though?
I can’t predict the future, but often what happens is: • You have a problem with your CLJS app you want to solve • You google for a solution • You might find a solution in JavaScript that says, “use this library” • That library is installable via NPM
OK, so learning shadow.cljs and, later, Leiningen is really best. OK. I mean I'll have to learn the CL vs CLJS differences at that point anyway.
So focussing on CLJS then, is there any reason to go for a thing I came across called Tailwind? I think it's for CSS but I just heard from didbus in the big list that shadow.cljs (and figwheel for that matter, but it seems like I don't need to bring up figwheel since it's not in the running anymore) does CSS.
Hum, the tools don't matter too much. Its best you just find a good tutorial. They all do the same thing, and you can change from one to another pretty easily, so you're not locked in to your choice.
Then again, I heard of Tailwind when I was trying to figure out what CIDER was and watched part of a YouTube video of a person using Emacs+CIDER+shadow.cljs+Taliwind. Wha?
For example, this guide seems pretty straightforward to get started with: https://betweentwoparens.com/start-a-clojurescript-app-from-scratch It shows making a small reagent app. Uses tools.deps and figwheel-main. There's probably another good one that would use shadow-cljs as well out there.
One last tool I've heard of, and maybe it's just built right into CLJS anyway is...I'm blanking on the name but it's for writing HTML as CLJS.
@jayzawrotny Aww...the Venn diagram disappeared.
If you use reagent, a react wrapper for cljs, it will make use of hiccup syntax to build your components.
Hiccup is "just" a library.
hiccup isn’t exactly what they want... they probably saw reagent, which reuses hiccup’s syntax for describing elements in a component
Right, I just wanted to clarify it isn't some separate tool they need to learn 🙂
@lilactown Doesn’t your hx lib use hiccup as well?
So much churn 🙂 And we wonder why beginners get so confused?
I've tried to learn cljs several times over the last five or six years -- and it's different every time 😞
The syntax is called hiccup, and hiccup is also a library for parsing hiccup, but there are other libs that parses the hiccup syntax as well (some with various slight additions to the syntax as well)
The "hiccup" library for ClojureScript is called hiccups
as I recall?
Ya, ClojureScript is hella confusing :p, JavaScript is hella confusing to me as well, which is part of half my confusion with ClojureScript. I honestly am impressed at people who are learning to program with JavaScript ecosystem first
And I remember learning reagent
at one point and there was a hiccup syntax library for that too -- with yet another different name?
ClojureScript is relatively stable, but it’s also feeling the pain of keeping pace with the rate of development w.r.t. web UIs in general
Relatively stable now. It certainly wasn't several years ago.
I help maintain a 3 yr old, 50k LOC ClojureScript app at work. There are many different decisions I would make today given what the state of the art is and the collective wisdom we have gained since starting it
JS still feels like a huge moving target, but browsers compatibility seems much better now
I just relearn CSS, and flex and grid layouts are a god send. I used to do table layouts or floats which were so confusing
developing a web UI that meets the needs of todays users is just a beast of a project, and requires a lot of 3rd party code to be economical. that means churn as 3rd party solutions meet their limits or lose support
Ah, sablono
is what I'm thinking of from when I was doing ClojureScript...
...we built a p.o.c. with Om and then rewrote it with Reagent and we started using Sablono because of its Hiccup-like syntax.
But there is also a hiccups I think. But it seems Sablono and the baked in reagent parser are the most used ones
Yes, I mentioned hiccups
above.
When we first tried cljs, it was 2013 I think. The Wild West.
Like FHE tho' I have no idea what I'd start with today if I was just trying to learn cljs, even after a decade of Clojure.
I'd start on http://clojurescript.org but I don't think that gets me very far (does it?) and beyond that it's still pretty crazy...
I just got started with it, first time. I did raw ClojureScript with no tools first and only tools.deps. Then I added figwheel-main, and then I went with rum for UI components.
I was reading that the other day. The guide is ok but it’s missing a lot of goodness like reloading, serving public files + reloading CSS, releases vs dev watching builds, and simple npm deps support. I’d still pick shadow well over the other options for now.
Relying a lot on pure ClojureScript and cljsjs for now, as I don't need anything fancier from npm yet. I suspect when I do, I'd either try the new bundle thingy (though that version of ClojureScript is not working on figwheel-main right now). Or I'd move to shadow
Ya, I think it's a bit the struggle with being hosted. Like most of my learning I'm having to do for ClojureScript are really about learning the JavaScript host
I've seen a few people start out now with babashka instead. Because getting started with it is most straightforward.
Choice is kind of one of Clojure's strength honestly. Like Clojure often call it "reach". It runs on so many platforms, it can leverage so many existing tooling and framework and libs, and it adds more of its own to the mix.
Probably most people don't even know if they want to learn Clojure or ClojureScript first 😝
And then the language itself is all about given you infinite power. Quite the opposite from say Pythons attitude that there should be only one way to do anything. This power manifests itself in even more choices.
For me, that's the fun of it. I like trying lots of different things or ways for doing the same thing 😝. And I even like coming up with my own. Its a way to be creative. But it's definitely more confusing.
That’s true. Everyone talks about all the roads that leads to Rome. No one discusses that one-way dirt road near where I grew up.
I would highly recommend shadow-cljs for your position given that it can interact with cider out of the box, is a standalone tool, is fully featured, and well documented.
OMG Emacs is driving me bananas right now. I'm practicing using it to document all the installation steps I have to do on a fresh computer (my wife's) to install everything, and I do NOT understand the undo system. I mean I thought I did, but suddenly both the undo command AND the redo command both undo and I can't redo all the things undo destroyed. Sorry. Off topic.
I've got Emacs, git (for installing Doom), Doom (not required, I know, it just sounded good), adoptOpenJDK V8 so far
Next going to figure out where to put the cljs.jar file, and figure out what the heck using CIDER entails (I know it comes as part of clojure-mode in Doom Emacs if not vanilla Emacs).
I just noticed this thread. I did download the cljs.jar file linked to directly from http://clojurescript.org with text to the effect of "you need the standalone CLJS JAR file". I just parked it somewhere and haven't done anything with it, though.
I did install node.js and then created a project using a command using npx that is in the shadow.cljs installation instructions. With all the other things that were automatically install, any chance it would have automatically installed cljs.jar?
@jayzawrotny gotta have that Venn. appreciated even if imperfect. 🙂 By the way, what would the block diagram at the top look like for Lein+FigWheel vice shadow.cljs?
Ultimately you would be running figwheel through lein and it would be creating a cljs repl you could connect to through cider in emacs. But if I recall, the process wasn’t as streamlined as shadow’s.
OK. I barely noticed this thread thing btw. Seems good as long as a person doesn't open more than one side thread. lol ...and as long as the discussion wouldn't benefit from extra people chiming in.
Is there any way to save a http://whimsical.com image to refer to later?
A core thought often seen throughout Clojure is to build the simplest tool that solves one problem well. Shadow solves cljs really well, lein solves clj but can do cljs with a plug-in like figwheel, deps.edn only does deps.
@factorhengineering Hmm actually it would be more like this in terms of functionality.
@factorhengineering If you are already familiar with an editor that has a decent Clojure/Script integration, I wouldn't bother trying to learn Emacs as well..
(I used Emacs 20 years ago and moved on to other things, then came back to it when I learned Clojure... but switched to Atom back in 2015 and I've been very happy with that decision 🙂 )
@vale You're totally correct, but I'm just trying to start with the end in mind, meaning I want the in-the-end best set-up and not the at-first best set-up. I feel like doing anything else wastes time learning things I won't continue to use.
As for other editors, I used NotePad++ just trying to get syntax highlighting when I gave CLJS a shot last year...and I didn't even get that to work. lol
i'd just learn setting up a clojure project first, then add cljs to the mix and finally switch to emacs if still interested
setting up cljs and emacs sounds overwhelming to me and i've been using clojure for years
I mean I did get a cljs program (webpage with a bit of text manipulation programmatic magic I needed) up and running, and I did use Leinigen for that (and I also set up FigWheel but didn't really make any use of it). Baby steps for sure, but I don't feel like I need to avoid CLJS.
i don't think you need to throw away lein for shadow-cljs, you can use them together
there's even a shadow-cljs template for lein https://github.com/shadow-cljs/lein-template
I do like the idea of keeping as much in common as I can between working on CLJS and working on CL. ...but no-one above recommended or even mentioned using Leiningen and shadow.cljs together, iirc.
You can use shadow-cljs for your cljs and lein for your clj parts. That shouldn’t cause issues.
Is there any way to save a http://whimsical.com image to refer to later?
So my next step is CIDER...or is it? I guess I don't need to get into that until I get partway into shadow?
I still have that lingering question on tailwind and hiccup (unless I missed the answer). Does shadow.cljs do what they were once needed for?
While it is a nice idea to use the same tools for both, I wouldn’t recommend it. Having two host langs with their own ecosystems... you really want to dive into one or the other, learn it well, and then learn the other one.
@krzyzowiec Yeah. thanks for that last push. I was almost there. Yep...Leiningen you're going to have to wait. lol
Trust me on this, I went down the same path as you. It was very confusing, but siloing them into the Java path and JavaScript path made it very simple. I use Lein when in Java land.
(this is why, having done Clojure for a decade, I still don't do ClojureScript -- it is a very confusing and constantly-changing ecosystem as far as I'm concerned!)
It’s easier for a JS dev since you are already familiar with that ecosystem. You know NPM and package.json, webpack, etc, so you just pick up the CLJS bits
OK. I won't push for libs yet, but good to know for when I need them. Same thing for Java interop. I feel like I have a slight clue about that just knowing what the word interop means, and I may have even used a tiny bit of it in my program way back.
Right now I want to write a program to help my 1-year old learn letters and numbers and words.
I also want to write a program for display on a 3-D TV but that is planar but with different scene elements assigned to different eyes.
The point being to make sure that both eyes are working in order to play the game or whatever the activity is.
That would be to try to correct my 4yo's strabismus, to try to do more for her than just wait for some temporary glasses to hopefully fix it and hopefully be only temporary.
I’ll be honest with you, you’re in for a slog from the sound of it. If you want to learn how to build native apps on mobile devices as well... it takes a while. I’d actually suggest fully learning JavaScript first. Go learn NPM, React, React Native, and then come back and learn CLJS after.
The challenge is that you absolutely have to know JS and React very well to build something nice to begin with, and then learning Clojure and its build tools at the same time... it would make anyone’s head explode
I did a program in JavaScript once, also around a year ago. I really picked CLJS in order to avoid what I heard were terrible things about JS.
I would rather not learn JS any more if I can help it. ...just reserving that for when I need to do interop.
Hmm. The problem is that there is a wealth of resources for learning JS related things, and a dearth of learning material for CLJS. So when you inevitably have to learn React, where do you go? I learned React using JS, so I only had to translate what I already knew. Your experience may be different, of course, but I don’t think disliking the host language is a good thing because that environment is critical to know. JS has flaws, but it has improved a lot.
I mean I didn't hate making that little webpage I did with JS, but still...I want to use the better tool where I can.
I'm going to press on with CLJS, but based on what you said I won't be hesitant to get into JS if it seems at all like it will be a good idea. Thanks for the help.
I have to say, a quick Google for building a simple browser app with ClojureScript which uses shadow-cljs does not return anything very good.
This is the best I found: https://www.rockyourcode.com/tutorial-clojurescript-app-with-reagent-for-beginners-part-1/
I am constantly amazed by how terrible people are at imagining how differently other people's experiences and knowledge can be from their own.
Ya, I'm actually surprised at the lack of guides here. I would have expected to see a lot more.
...which leads to 'from scratch' videos that start with 5 tools already up and running and no doubt customized and optimized for the task 11 different ways.
It’s like a rite of passage lol. I learned by reading source code and project templates on github.
If I could ever get through all the tooling set-up and get to the point of actually writing code again, yes, then reading other people's code sounds reasonable.
@jayzawrotny Apparently I can't have 2 side threads at once. If you have posted anything in ours since my last post, can you please post it here in the main thread?
Small question @factorhengineering, any reason why you want to start straight up with ClojureScript? Is it the appeal of building cool useful things right away? Because to learn Clojure I think starting with simpler things like command line applications is probably more approachable. You can even avoid all tooling and just install Clojure and notepad
I don’t know how other people feel, but I am so far from being an expert right now that I’ll wait on writing guides lol. I would like to do something eventually though. It is not a good situation for a newbie.
It's kind of cute that the http://clojurescript.org quick start guide states "On Windows you will need http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html and the https://github.com/clojure/clojurescript/releases/download/r1.10.758/cljs.jar." without the slightest hint of where to put the cljs.jar.
@factorhengineering You can track threads on the left sidebar which will change color when threads have been updated.
krzyz, I actually might not agree. I think anyone might be able to write a great guide for how to get from where they were just a short time ago to where they are now.
...or maybe it's just a personality thing, and some people are just better at teaching. The one thing I absolutely do not believe, though, is that the more a person knows about a subject the better they are at teaching it. Those two qualities are orthogonal other than the fact that a person can't teach advanced things they don't know yet.
I agree. Folks who are closer to the beginner experience are generally best positioned to write tutorials for beginners.
I have almost no idea what to offer beginners in a tutorial because when I was a beginner and just getting started, everything was very different and a lot of the stuff I had to read/do is definitely not a good way to go these days 😞
I am pretty dang noobish right here, but even I am writing a guide right now. If I could give my own guide (which currently only covers Emacs, git, Doom, and the right version of Java for CLJS (8, right?) to my previous self from 4 or 5 days ago, I would save him hours and hours and hours and hours.
(fortunately, I feel like I am still a complete beginner with ClojureScript, so these sorts of discussions are very helpful to me)
I would never want to learn Emacs as a beginner tho' 🤯
That's another good point, Sean. Even if an expert is good at remembering every little step and possible pitfall they encountered and laying it all out, the landscape may have changed.
Agree, I find it very hard for me now to relate to the beginner experience. I'm so removed from it, so knowing what's the right advice or level of detail to explain is challenging.
Wow! That's awesome. But if I thought it wasn't all that complicated before, now I'm completely overwhelmed! 🙂
Hahah yeah… there’s a lot of overlap and minor feature differences. Any suggestions to make it more clear?
No. I mean it just is complicated. There are so many options, some of which overlap and some of which compete.
@U1UQEM078 Oh right! If I recall, figwheel and figwheel main support it?
Oh you are on windows hum... I think that's an outdated guide for it. On windows you can use either Leiningen or Tools.deps as well now.
Like right now, between chatting with you I have been to 4 or 5 different places on the shadow.cljs website and I have not found a single clue about how to install it.
Interesting... I might reconsider then. Maybe I’ll do a blog and write experiences a day at a time or something. I learned a ton while trying to write a React Native app in CLJS.
It has been like this every...step...of the way. ...except git. That was thankfully straightforward to install.
@factorhengineering https://medium.com/@jiyinyiyong/a-beginner-guide-to-compile-clojurescript-with-shadow-cljs-26369190b786
I think both guides I linked seem mostly up to date. But I only glanced at them quickly
I was going through the Fulcro (a clj\cljs fullstack framework) getting started guide the other day. It’s really good! Covers shadow, writing components, server side, reloading, REPL, and the framework elements etc…
@krzyzowiec So that guide is up to date, unlike the guide didibus mentioned?
Big post incoming. Sorry. accidentally switched to a private chat and meant to post here...
https://app.slack.com/team/UH5SE3NM9 [2:44 AM]
This just about made my cry: https://shadow-cljs.github.io/docs/UsersGuide.html#_installation
Only visible to you
Slackbot [2:44 AM]
Eccentric J is currently in Do Not Disturb mode and may not be alerted of this message right away. If it’s urgent, click here
to send a notification now. Keep in mind, if the recipient has all
notifications turned off, they will only get your message when they’re
back online.
How does Do Not Disturb work? Learn more in this Help Center article: https://slack.com/help/articles/214908388-Pause-notifications-with-Do-Not-Disturb
FHE [2:44 AM]
You will need:
• node.js
(v6.0.0+, most recent version preferred)
• npm
or yarn
Eccentric J [2:44 AM]
Do you not have those already?
FHE [2:44 AM]
along with: "`shadow-cljs` is composed of 2 parts:
• The https://slack-redir.net/link?url=https%3A%2F%2Fclojars.org%2Fthheller%2Fshadow-cljs&v=3 Clojure library which handles all the actual work.
• The https://slack-redir.net/link?url=https%3A%2F%2Fwww.npmjs.com%2Fpackage%2Fshadow-cljs&v=3 npm
package which provides a convenient interface for running most of the build functionality directly from command line.
"
Clojars
https://clojars.org/thheller/shadow-cljs
[thheller/shadow-cljs "2.9.8"] CLJS development tools
Total downloads / this version
271,299 / 518
Coordinates
[thheller/shadow-cljs "2.9.8"]
npm
https://www.npmjs.com/package/shadow-cljs
ClojureScript compiler and JS bundler
[2:45 AM] So now what I thought was 1 installation turns out to be 4 installations.
[2:45 AM] This keeps happening. It's tiring.
Eccentric J [2:45 AM]
You don’t need the clojure library, just the npm module.
FHE [2:45 AM]
So the guide is just wrong?
Eccentric J [2:45 AM]
No the guide is right
FHE [2:46 AM]
"The https://slack-redir.net/link?url=https%3A%2F%2Fclojars.org%2Fthheller%2Fshadow-cljs&v=3 Clojure library which handles all the actual work." ...is not needed?
Eccentric J [2:46 AM]
It’s
included by the npm module, the clojure library is used more if you’re
combining with deps.edn, lein or something like that.
FHE [2:46 AM]
Whoops. I meant to post all of this in the main thread. Can we move it there?
Eccentric J [2:46 AM]
Unfortunately not
Again, sorry for the big post. Thought I was posted all that in this channel all along. Forgot I switched to a private chat 'for a sec'.
automatically install tools, including chocolatey and maybe python and visual studio build tools?
Of course the shadow.cljs guide does not mention whether this is needed during NPM installation
With nodejs being one of the most popular languages\ecosystems shadow-cljs is trying to make it convenient by leveraging node\npm’s distribution for new users.
The line 'Alternatively...install the dependencies yourself' at the bottom is kind of hilarious to me.
The list of installations just keeps growing....but I'll be grateful all these ones are automatic.
Ya, like I said, you'll need to install: JVM, Clojure, Leiningen, NodeJS, NPM (I think comes with NodeJS), shadow-cljs
Being on windows definitely makes a lot of this much harder to setup as well unfortunately.
Sounds like if I don't do it automatically now I might need to manually install a bunch of stuff later. I'm overwhelmed by the amount of things to install already so no to that. lol. I'll just do the auto stuff now I think, even if there's a chance I won't need it.
That’s true. NPM comes with nodejs. You may not need those tools to get started, but there will be fewer surprises should you branch out to other npm modules.
In Windows they like to bundle everything. It’s amazing. In Linux I just grab the one thing I asked for.
Windows doesn't even have a proper command line. Its a huge pain to develop on it. (Haven't tried the new Linux subsystem stuff though)
I hit a roadblock trying to do that on my new-ish laptop a few months ago, though. Windows refuses to give up enough of it's partition's space to allow for a reasonably-sized Linux partition.
I know it seems like you are installing a lot of random things, but essentially you are setting up a JavaScript developer environment AND a ClojureScript one.
With shadow-cljs, you can create projects designed for web browsers, node scripts, react native, and npm modules. It also leverages node and npm as distribution. Also, nodejs is a platform to interpret and run JS on your platform (outside of a browser) and npm is a tool to work with packages. Shadow-cljs is available as an npm package.
Also, 'close all open programs for the duration of the installation'. LOOL I have Emacs and command prompt and Hex Chat (for help with Emacs yesterday) and notepad and about 300 Firefox tabs open (including a Discord channel for help with DOOM).
Hum, ya, plus I feel you probably don't actually need this. But heck no idea :man-shrugging:
Tools like SASS and other transpiler tools use node-gyp if I recall. It’s good to have.
Welp, my wife has only used 1/3 of the space on this lappy, so I guess I'm doing this. See you again in hopefully just a few minutes...
You could just leave things open and see what happens. I doubt it would interfere with those apps.
This laptop is scorching my lap right now because of all the tabs (even with NoScript!). I should at least close Firefox.
Python was a good chunk of it, but the part that took forever was called 'visualstudio2017-workload-tools'.
Well I went to a command prompt and typed 'npm' to try to see if that was installed somewhere in there and...looks like yes!
Heading out for the night. The only other requirement may be java, then you should be able to continue the tutorial and start building a web app with reloading and a REPL you can connect cider to. Good luck!
Actually I installed adoptOpenJDK 8. Oracle with their crazy account creation gate demanding all kinds of personal info. Pffft.
Thanks. @jayzawrotny and anyone else who have maybe already left...?
Well I followed the first instructions at https://shadow-cljs.github.io/docs/UsersGuide.html#_installation and yes, for some reason creating a project with the npx command shown there somehow gets shadow.cljs installed.
The Windows Developer Experience Team is doing an amazing job right now. WSL2 and the new Windows Terminal app are lifesavers for me. WSL2 will get GPU (e.g. ML workloads) and GUI support this year. So you can pretty much never leave the WSL environment.
I might try it. I guess I would have to install that and then re-install for WSL all of the things I just installed for Windows.
By the way, it's WSL2 now, isn't it? I know very little about it, but I did come across that tidbit somewhere.
WSL2 is an actual Linux over a hypervisor. It is way better than WSL1. So make sure you are on WSL2.
why does let take a vector of alternating symbols and values instead of a map, which is constructed in the same way?
Does anyone have a recommendation on texts (and ideally exercises) to thoroughly understand 'recur' ?
Something comparable to the recursion chapters in Practical Common Lisp or the Little Schemer?
@phil634 Personally, I found https://htdp.org to be extremely good material for learning functional programming. It uses Scheme, and of course Clojure doesn't have tail call optimization right now, but you just mentally substitute calling the function name again for recur. It's so good for learning lisp in general that I read it a few times. It goes over multiple forms of recursion.
I think i’ve sorted the specific one, which was making input loop for a turn based game, but it was a bit trial and error
so I was looking for something that really spelled out what was happening using some examples beyond eg for type loops
Essentially it is just looking for the nearest place it can jump to, and rebinding according to what you pass in.
Other than that, I guess you should know it is looking for loop or fn as jump points, you must pass in the same number of args, and you must be in tail position
yeah, it was the rebinding bit that was causing me trouble when change was coming from user input
I'm discovering threading macros and loving them because they make some of my code much easier to follow. But I'm concerned about abusing it. So I have a code style question, if I have some code like this:
(-> person
(assoc :hair-color :gray)
(update :age inc)
(cond-> lucky? (assoc :money "a lot!")))
Mixing two kinds of threading macros. What do you think about this?
@ceronman Stuart Sierra has some great advice on his blog about that: https://stuartsierra.com/2018/07/15/clojure-donts-thread-as and https://stuartsierra.com/2018/07/06/threading-with-style
Thanks a lot, those two posts are very interesting. He suggests mixing ->
and as->
for cases that don't conform. I guess mixing cond->
might be not that bad.
@ceronman Yeah, I will mix ->
and cond->
and I do, sometimes, mix ->
and ->>
or cond->>
if I feel it makes the logic easier to read.
Like all "rules", there are times when it's OK to break them.
I think it's fine as long as it is readable. For an example like that, where complexity is minimal, I don't see a problem.
If you think its easier to read, then I'd say go for it. Chances are its easier for others to read as well.
That examples seem fine to me. I'd say the only no/no is changing the thing being chained
Since here you keep modifying person, its easy to follow. We have a person, and we assoc hair color grey, increment age and conditionally assoc money
If you had a get in the middle of it, that would begin to be less readable, and I would break it up into two threads or possibly use as->
(-> (SomeRequest.)
(.with param1)
(.with param2)
(.with param3)
(.call)
(.response)
(->> (mapv inc)
(filter even?)))
Like in this example, we create a reuqest, make a call, get a response and then process the reponse. I feel its starting to be a lot. So generally I guess my threading macros are either all data transformation on the same logical thing, or all about fetching some data in some nested structure. I'll try not to mix the two, and will try not to change the thing I'm transforming mid-way. If I do, I'll break it up. Like so:
(let [some-request-response (-> (SomeRequest.)
(.with param1)
(.with param2)
(.with param3)
(.call)
(.response))
incremented-even-results (->> some-request-response
(mapv inc)
(filter even?))]
incremented-even-results)
@didibus mapv
/`filter` require ->>
here
(and in your original example above)
Ah yes true, another reason to break it up 😛, but also I was too focus on trying to have good formatting in slack. Why can't it use a monospace font 😛
But, yes, I agree that having one chain of ->
followed by a whole chain of ->>
is a very good sign that it should be two separate expressions.
do the clojure CLI allow you to create a deps.edn project ?, e.g. clojure make-me-a-new-app and it creates the directory structure, deps.edn file etc ?
You need to configure: https://github.com/seancorfield/clj-new
He's using that already.
See his next message.
Oh, assuming the error is not that the alias doesn't exist. Can you paste us the error?
Execution error (FileNotFoundException) at .FileInputStream/open0 (FileInputStream.java:-2).
app (No such file or directory)
Full report at:
/tmp/clojure-4606039658757054282.edn
I thought it would just work out the box, I didn't realiseI thought it was clojure -A:new app name
but that is jujst genereating an error message i dont understand
The argument that Stuart Sierra makes around that is a good one: ->
tends to indicate threading an important "entity" or "collection" as the "subject" because that's how non-sequence Clojure functions work. Then ->>
indicates threading sequences -- the last argument position.
Yes @qmstuart clj-new
will generate a new project with deps.edn
-- what is the error message you get?
Yes, the only time I find I need to mix a lot of -> and ->> is when manipulating strings, because those functions are inconsistent in where they take the argument. I think that's really the only place where I tend to be okay with mixing them heavilly
@qmstuart You should also see a message like this if you don't have the alias set up:
WARNING: Specified aliases are undeclared: [:new]
Without that alias, clojure
will treat arguments as the names of scripts to load and run (so it sees app
and tries to load and run a file called app
as Clojure code).
Hence the No such file or directory
error.
I don't know if this is any consolation, but I used to be a C# dev at a microsoft shop, an what I can say is at first I thought the same, but once you understand the linux/jvm/clojure tools, they become much easier to debug and build on top, where as with the C# tooling if the GUIs are failing you, it becomes really hard to root cause, and the lack of command line for most of them is hard to automate. At least it was a few years ago.
Which I think explains why Windows never gained traction with developers, and why Azure windows is a big failure, and Microsoft is basiclly porting linux to windows now, and porting C# to linux.
I think you'll find far more developers around the world have always used Windows @didibus ... What you said is fairly common from Linux people tho' 🙂
Ah, right. Deployment vs development.
That's why Microsoft has this new embrace Linux strategy 😛, because Azure is their new cash cow. I like Windows as a user OS, though yes I did switch to Linux 😛. Mostly because I find for non Microsoft dev work, no one targets windows, and to be honest, the terminals and shells on windows is a mess in my opinion.
Yes, it can seem pretty overwhelming. I like how Windows 10 has WSL so you can use Windows for a lot of stuff but still use Linux for command-line stuff on the same machine.
(which is like macOS since System X arrived)
Ya, it took me a while for sure. But once things click its pretty nice. When thigns are broken, you can often fix it. In Windows, you have to re-install the OS, or good luck fixing a broken registry.
Interestingly enough, macOS is my least favorite OS. I've yet to try WSL, I will eventually, but I'm waiting for it to stabilize I guess. I'm confused with the whole 1 to 2.
Happy to answers about WSL 1/2 if you want. DM me, or ping me in the #windows channel.
You might find it helpful to start with this deps.edn
file https://github.com/seancorfield/dot-clojure
That would go in your ~/.clojure
folder (overwriting the default one -- if you haven't changed that file, otherwise you'll want to just read my dot-clojure file and add parts of it into yours).
Clojure expects you to work with command-line tools, to be honest.
Ya, I'd say Clojure follows pretty closely with the Unix philosophy of leveraging config files and simple command lines tools that compose
I have a project that I am trying to cider-jack-in to, and it's failing due to what appears to be nrepl looking for a package version and not finding it... for a package that has nothing to do with the project I'm in.
@patrickanium Can you share the error messages?
[nREPL] Starting server via /Users/foo/bin/lein update-in :dependencies conj \[nrepl\ \"0.6.0\"\] -- update-in :plugins conj \[refactor-nrepl\ \"2.5.0-SNAPSHOT\
\"\] -- update-in :plugins conj \[cider/cider-nrepl\ \"0.24.0\"\] -- repl :headless :host localhost
21error in process sentinel: nrepl-server-sentinel: Could not start nREPL server: If there are a lot of uncached dependencies this might take a while ...
22Downloading: origami/origami/maven-metadata.xml from
23Downloading: origami/origami/maven-metadata.xml from
24Downloading: origami/origami/4.3.0-7/origami-4.3.0-7.pom from
25Downloading: origami/origami/4.3.0-7/origami-4.3.0-7.jar from
26java.lang.IllegalArgumentException: Provided artifact is missing a version: [origami/origami nil]
What's in your ~/.lein/profiles.clj
file?
;; put this into profiles.clj in ~/.lein folder
{:user {:jvm-opts ^:replace ["-Xmx3G"]
:plugins [
;; [cider/cider-nrepl "0.21.1"]
[cider/cider-nrepl "0.24.0"]
;; [lein-ancient "0.6.15"]
;; [jonase/eastwood "0.3.3"]
[lein-pprint "1.2.0"]
[lein-try "0.4.3"]
;; [lein-cloverage "1.0.13"]
[refactor-nrepl "2.5.0"]
]
:middleware [cider-nrepl.plugin/middleware
;; refactor-nrepl.plugin/middleware
]
:dependencies [
;; [nrepl "0.6.0"]
[nrepl "0.7.0"]
;;[org.clojure/tools.namespace "0.2.11"]
]
}}
(cider-required-middleware-version)
;; put this into profiles.clj in ~/.lein folder
{:user {:jvm-opts ^:replace ["-Xmx3G"]
:plugins [
;; [lein-ancient "0.6.15"]
;; [jonase/eastwood "0.3.3"]
[lein-pprint "1.2.0"]
[lein-try "0.4.3"]
;; [lein-cloverage "1.0.13"]
]
:dependencies [
;;[org.clojure/tools.namespace "0.2.11"]
]
}}
(cider-required-middleware-version)
If you jack in CIDER ensures that stuff is injected. If you’re starting your project yourself you should ensure that stuff is present in your project. Profiles are just the source of frustration and forgotten deps
ah ok... would it also mean, if you put stuff in the project, it's more portable for others to use?
{:user {:jvm-opts ^:replace ["-Xmx3G"]
:plugins [[lein-pprint "1.2.0"]
[lein-try "0.4.3"]]
:dependencies []}}
(cider-required-middleware-version)
{:user {:jvm-opts ^:replace ["-Xmx3G"]
:plugins [[lein-pprint "1.2.0"]
[lein-try "0.4.3"]]
:dependencies []}}
Can you rename the file so nothing is effectively there and try this whole process again?
Nearly all Leiningen-related problems are caused by random stuff in ~/.lein/profiles.clj
gotcha... renamed it, cider-jack-in produces the same origami/origami error as before.
Can you run “lein repl” from a command line? Let’s remove all (mostly) tooling and see if it starts?
lein repl
If there are a lot of uncached dependencies this might take a while ...
Provided artifact is missing a version: [origami/origami nil]
that just returns the aforementioned error... this time in the terminal
java.lang.IllegalArgumentException: Provided artifact is missing a version: [origami/origami nil]
at cemerick.pomegranate.aether$add_version_from_managed_coord.invokeStatic (aether.clj:654)
cemerick.pomegranate.aether$add_version_from_managed_coord.invoke (aether.clj:646)
cemerick.pomegranate.aether$add_version_from_managed_coords_if_missing.invokeStatic (aether.clj:682)
cemerick.pomegranate.aether$add_version_from_managed_coords_if_missing.invoke (aether.clj:676)
clojure.core$partial$fn__5824.invoke (core.clj:2624)
clojure.core$map$fn__5851.invoke (core.clj:2753)
clojure.lang.LazySeq.sval (LazySeq.java:42)
clojure.lang.LazySeq.seq (LazySeq.java:51)
clojure.lang.ChunkedCons.chunkedNext (ChunkedCons.java:59)
I have a hodge-podge poorly understood repl/nrepl/cider/emacs setup, as a side note (on par with my profiles.clj), fyi.
I once downloaded and attempted to run https://github.com/hellonico/origami which is all I know about origami...
I almost feel like lein is climbing up out of my project directory and trying to install things from other projects.
Just do the command line. Emacs will just invoke commands that we can invoke ourselves but much more difficult to see which directory we are in and the errors
I'm isolating a copy of the project directory elsewhere in my filesystem and will use a fresh terminal instance on it; stand by.
whoa. cp -r'd the project to my desktop, opened a fresh terminal... ran lein repl, and same error! I checked project.clj and no mention of origami in there...
(defproject testproject "0.1.0-SNAPSHOT"
:description "an example"
:min-lein-version "2.0.0"
:plugins [[duct/lein-duct "0.12.1"]
[lein-tools-deps "0.4.5"]]
:lein-tools-deps/config {:config-files [:install :user :project]
:aliases [:backend :dev :test]}
:resource-paths ["resources" "target/resources"]
:middleware [lein-duct.plugin/middleware
lein-tools-deps.plugin/resolve-dependencies-with-deps-edn]
:target-path "target/%s/"
:main ^:skip-aot testproject.todo-example.backend.core
:profiles
{;; generated by duct
:dev [:project/dev :profiles/dev]
:repl {:repl-options {:init-ns user}}
:uberjar {:aot :all}
:profiles/dev {}
:project/dev {:source-paths ["dev/src"]
:resource-paths ["dev/resources" "target/dev/resources"]
:target-path "target/dev/"
:dependencies [[integrant/repl "0.3.1"]
[eftest "0.5.4"]
[kerodon "0.9.0"]
[com.gfredericks/test.chuck "0.2.7"]
[reifyhealth/specmonstah "2.0.0"]
[test2junit "1.4.2"]]
:plugins [[test2junit "1.4.2"]]
:test2junit-output-dir ".out/test-results"}
:local-staging {:target-path "target/local-staging/"
:resource-paths ["dev/resources" "frontend-target/local-staging"]}
:staging {:target-path "target/staging/"
:resource-paths ["dev/resources" "frontend-target/staging"]
:lein-tools-deps/config {:aliases ^:replace [:backend]}}
:prod {:target-path "target/prod/"
:resource-paths ["frontend-target/prod"]
:lein-tools-deps/config {:aliases ^:replace [:backend]}}
:test {:resource-paths ["dev/resources" "frontend-target/test"]
:lein-tools-deps/config {:aliases [:test]}}})
~
I'm going to generate a new project with a lein template and see if this happens in it.
ok, renamed .m2 and ran lein repl in the root of the problem project and I see every single dependency ever there downloading.
I removed .m2 and ran lein repl from my newly generated lein template app, and it only installed the .m2 deps for that project... so there's something up with my project.clj above... or something it invokes.
At a guess: one of the dep's deps is screwy. You might be able to define origami at a top level instead to overwrite it
found the source of the problem:
[lein-tools-deps "0.4.5"]
and
lein-tools-deps.plugin/resolve-dependencies-with-deps-edn
In Microsoft land, I can use SignalR to send data from back end to front end to save polling, is their an equivalent library that does this for Clojure?
Eventually, I want to have a front-end that will update when the back-end sends a message, where the back-end is pulling messages of a rabbitmq queue
I'm more asking: are you wanting to implement the updates yourself, or are you wanting a full framework that does the synchronisation for you?
If you want a simple thing where you write the notifications yourself, you can make a websocket endpoint. Your frontend connects to that, and reads from that
looks like http-kit can do it https://http-kit.github.io/server.html#websocket I'll look into this.
lein-tools-deps.plugin/resolve-dependencies-with-deps-edn
is pulling in everything I've ever installed in .m2... I have a deps.edn in my project but not anywhere else... am I supposed to have a higher level one?Maybe there's something strange in your deps.edn
file that is causing that?
there is a mention of an 'install level' deps.edn at https://github.com/clojure/contrib-api-doc/blob/master/cli/example-deps.edn
That is only going to have a default Clojure version in it and the "standard" repository definitions.
{:paths ["src"]
:deps {org.clojure/clojure {:mvn/version "1.10.1"}
org.clojure/clojurescript {:mvn/version "1.10.520"}
com.cognitect/transit-cljs {:mvn/version "0.8.243"}
com.taoensso/timbre {:mvn/version "4.10.0"}
integrant {:mvn/version "0.8.0-alpha2"}
funcool/bide {:mvn/version "1.6.0"}
medley {:mvn/version "1.3.0"}
metosin/reitit-spec {:mvn/version "0.3.7"}}
:aliases
{:dev {:extra-deps {cider/cider-nrepl {:mvn/version "0.21.0"}
refactor-nrepl {:mvn/version "2.4.0"}}}
:test {:extra-deps {com.gfredericks/test.chuck {:mvn/version "0.2.7"}
eftest {:mvn/version "0.5.4"}
kerodon {:mvn/version "0.9.0"}
reifyhealth/specmonstah {:mvn/version "2.0.0"}
test2junit {:mvn/version "1.4.2"}}}
:backend {:extra-deps {bk/ring-gzip {:mvn/version "0.3.0"}
com.datomic/datomic-free {:mvn/version "0.9.5697" :exclusions [com.google.guava/guava]}
duct/core {:mvn/version "0.7.0"}
duct/module.logging {:mvn/version "0.4.0"}
duct/module.web {:mvn/version "0.7.0"}
liberator {:mvn/version "0.15.3"}
environ {:mvn/version "1.1.0"}
org.yaml/snakeyaml {:mvn/version "1.23"}
org.flatland/ordered {:mvn/version "1.5.7"}
ring {:mvn/version "1.7.1"
:exclusions [org.clojure/tools.namespace]}}}
:cljs {:extra-deps {re-frame {:mvn/version "0.10.6"}
reagent {:mvn/version "0.9.0-rc3"}
thheller/shadow-cljs {:mvn/version "2.8.60"}}}
:cljs-dev {:extra-deps {binaryage/devtools {:mvn/version "0.9.4"}
day8.re-frame/re-frame-10x {:mvn/version "0.4.5"}}}
:cljs-local {}}}
My experience is that trying to blend lein
(or boot
) with deps.edn
is an exercise in frustration. Either stick to lein
and project.clj
or switch completely to the Clojure CLI and deps.edn
I wrote boot-tools-deps
to attempt that and it never worked properly beyond the very simplest deps.edn
files so I archived it. I don't know how well lein-tools-deps
works but I really wouldn't recommend attempting this sort of thing...
(`lein` already does enough "magic" on its own, without trying to override how it resolves dependencies using a library with different algorithm for resolving conflicts)
gotcha... this is an existing project I'm exploring... so I'll have to possibly just pull it all into project.clj.
That means you're running code like (assoc [] :my-key "hi")
where assoc only works on vectors if key is a number referring to its index like (assoc [1 2 3] 1 :x) ; => [1 :x 3]
it's giving an error for this code, where I'm deep merging two maps. It has worked so far for merging maps, but not for the latest pair of maps that I'm inputting as parameters:
(defn deep-merge
"Recursively merges maps."
[& maps]
(prn "" (count maps))
(prn "maps in deep merge are " maps)
(letfn [(m [& xs]
(if (some #(and (map? %) (not (record? %))) xs)
(apply merge-with m xs)
(last xs)))]
(reduce m maps)))
(merge-with into {:foo 6} {:foo 4 })
Error: 4 is not ISeqable
at Object.cljs$core$seq [as seq] ()
at Function.eval [as cljs$core$IFn$_invoke$arity$3] ()
at Function.eval [as cljs$core$IFn$_invoke$arity$3] ()
at Function.eval [as cljs$core$IFn$_invoke$arity$2] ()
at eval ()
at merge_entry ()
at eval ()
at Function.eval [as cljs$core$IFn$_invoke$arity$3] ()
at Object.eval [as cljs$core$IReduce$_reduce$arity$3] ()
at Function.eval [as cljs$core$IFn$_invoke$arity$3] ()
so what's happening is that with deep-merge it's recursing down these maps, but also down the vectors, and that's what's causing the error, correct?
I'm cleaning up a version of the function I've been using. Instead of map or vector I've been using (coll?) and when it's a coll I use into since it works for appending to whichever source collection type.
okay I mis-diagnosed the issue earlier:
=> (deep-merge {:foo [4 5 6]} {:foo [7 8 9]})
"" 2
"maps in deep merge are " ({:foo [4 5 6]} {:foo [7 8 9]})
{:foo [7 8 9]}
where
(defn deep-merge
"Recursively merges maps."
[& maps]
(prn "" (count maps))
(prn "maps in deep merge are " maps)
(letfn [(m [& xs]
(if (some #(and (map? %) (not (record? %))) xs)
(apply merge-with m xs)
(last xs)))]
(reduce m maps)))
Might take some modification to fine-tune
(ns app.merge-deep)
(declare smarter-into)
(defn merge-deep
[& maps]
(->> maps
(reduce #(merge-with smarter-into %1 %2))))
(defn smarter-into
[prev next]
(try
(cond
(and (sequential? prev)
(sequential? next)) (into prev next)
(and (coll? prev)
(coll? next)) (merge-with smarter-into prev next)
:else next)
(catch Exception e
(println "Could not merge values" {:prev prev
:next next})
next)))
(comment
(merge-deep {:a {:b {:c [1]}}}
{:a {:b {:c [2]}}}))
;; => {:a {:b {:c [1 2]}}}
copied from somewhere on GitHub:
(defn deep-merge [& maps]
(apply merge-with (fn [& args]
(if (every? map? args)
(apply deep-merge args)
(last args)))
maps))
Depends what you want it to do when vectors\lists are encountered. This version will use the right most val mine concacts the vectors\lists but if that's all you need it makes sense.
The try and catch in mine is not necessary either, I just put that in to help debug any specific values it can't merge and if it does fail, it just takes the right-most value to make it a little safer.
I just followed the 'Installation" section of https://shadow-cljs.github.io/docs/UsersGuide.html#_installation and there are a few things I don't understand...
1. Why does that guide mention needing Node.JS and NPM? Someone in the chat here mentioned Node.JS should come with NPM so after I installed Node.JS I checked (command prompt, 'npm, got a response).
Yes, node comes with npm but there are ways to install it that may not include both packages. npm is required to download the shadow-cljs package and install it into the local directory node.js is the runtime to execute it
I have a feeling that in the early days of node, installing it did not install npm at that time?