Fork me on GitHub
Alexandre lopes godoy00:08:16

is Clojure good for UI? I want to create a small program for my company. Would be simple website or desktop app. Flutter seems the most practical option, but maybe not the one I would enjoy the most.

Drew Verlee00:08:14

Sure, your building on the Js and java platforms, so all of that is fair game.


(really psyched about clojuredart for that)


There's Selmer if you just need some basic html/forms served up quick


Does your app need anything complicated?

Alexandre lopes godoy01:08:48

no, just a simple app. Where can I find examples of websites created with clojurescript?


also what is your "ideal" deployment target? An exe? A webpage? An exe that connects to a server?

Alexandre lopes godoy01:08:01

no ideal deployment target. Probably a webpage would be easier I guess.


Here is a guide to building a web page with ClojureScript, using CSS and hiccup. I've use this approach for many live websites

🙏 4

i'm still a relatively new beginner but nonetheless astounded at how incredible clojure is. i just wish i had started learning it sooner 😞


Don’t stress yourself! I figured learning never ends anyways, so it is beneficial to embrace that. Some of the coolest people I met always keep an open mind to learn more and refine their views. In regards to Clojure, I dabbled with it a few years ago and learned some of the basics, I think around 2014-ish or a bit later. But since about one year on a bit of a binge-learning track and it’s great! You don’t have to know it all before Clojure becomes practically useful either. For me it is already paying off. Primarily though having a REPL open at all times. When I’m on a new project that requires to incorporate some web API I don’t know yet, I use a Clojure REPL to play with it (instead of just using curl or something like that). And I have babashka scripts to automate mundane things such as collecting reports and so on. I also read of a sysadmin that isn’t necessarily a programmer but uses the Clojure REPL to debug/audit production apps that run on the JVM.


ive also been using the repl / babashka to test against APIs. its really awesome for that

🎉 9

Hi, I'm browsing a lot of clj/cljs code on github lately, why so many functions in deftype starts with - ?


Functions in a deftype are most likely functions from a protocol (check (doc defprotocol)). It is a common convention to have a "regular" function in front of a protocol function, often with the same name except the protocol function will have a dash at the beginning.


(the implication being that the protocol function would be private/"protected"/read the docs)

Alex Miller (Clojure team)13:08:06

we treat using a wrapper function around a protocol as a best practice in the clojure team

Alex Miller (Clojure team)13:08:43

it is extremely useful as a place to put special logic in advance of the protocol call, add specs, etc


ok, got it thanks


The other option is putting a * at the end of the protocol name and/or the end of the function names


i've seen and done both


Also, really like this library. I think its a good example of something being just "done"


and when i want to use swing, it is the thing


hey folks, is there a channel here on slack where people can post their projects for inclined clojurists to give feedback?

Darin Douglass14:08:27

#code-reviews would likely be a good place to start


Thanks! Exactly what I was looking for 👌:skin-tone-4:


hi all - quick question. Assuming I have a function called get-promos which returns a map {:promos [] :count 0} ; when using this get-promos function elsewhere, how can I de-structure the response? I was thinking it would be like this:

(let [{promos :promos promo-count :count} (get-promos)]
but that doesn’t seem to be working. What am I doing wrong here?


works for me, what are you seeing?


I’m getting nil back for both


are you evaluating them inside the let block?


but if I print within the get-promos function then I get the correct value


build=> (let [{promos :promos promo-count :count} {:promos [:promo1 :promo2] :count 2}]
  {:promos-i-saw promos :count-i-saw promo-count})
{:promos-i-saw [:promo1 :promo2], :count-i-saw 2}
yeah works for me


they’ll only exist inside context of that let.


let me have a look again - maybe the issue is elsewhere :thinking_face:


hey, how do I get ARGV in Clojure? I've been trying everything I found (`& args`, *command-line-args*, even a library) and I still can't pass an uneven number of parameters. is the issue how I run my program? I run it like clj -X myapp/-main foo


user=> (apply (fn [& args] args) [1 2 3])
(1 2 3)


yes -X expects an even number of arguments because it builds a map out of them (so keys and values) and passes them to the function


you can use -M to get the more traditional -main style

David Caudill18:08:24

so...hi I am new here

👋 4
David Caudill18:08:28

and I have many questions

David Caudill18:08:56

I have Clojure for the Brave and True

David Caudill18:08:34

but it looks like i need "a viable workflow for developing clojure on windows"...anybody got any tips for what I can do to quickly get all the "setup hell" out of my life?

David Caudill18:08:48

or even just tell me what a viable workflow COULD be on Windows so i don't run around trying dead tools/plugins from old tutorials?


@davidkcaudill Since you're using the Brave book, installing Leiningen on cmd/powershell is going to be your easiest solution.

David Caudill18:08:29

ok i have that much


The newer, simpler Clojure CLI does have a Powershell installer but I think, on Windows, it's easier just to use WSL2 (and Ubuntu) as your shell and use the Linux installer. If you want advice on using the new CLI stuff with Powershell, the #clj-on-windows channel is where the maintainers and users hang out.

David Caudill18:08:51

ok so is the expected dev workflow all CLI? emacs?


(I split my time between macOS and Windows and use WSL2/Ubuntu -- and the brew package manager on both; on an earlier Windows laptop, I used Scoop for package management and use the new Clojure CLI that way; much depends on your comfort with the CLI, esp. the Linux CLI).


Clojure tools and libraries generally expect you to run things at the CLI, yes, although you can avoid that to some degree with some editors that let you ignore the CLI.

David Caudill18:08:00

i do not know emacs...i can use vim but i cannot imagine using a CLI for dev after a decade of IDEs


You definitely want an editor with a good Clojure integration. I use VS Code on macOS and Windows. It has a great "getting started" experience but also serves advanced developers. Cursive is also a good experience if you are used to IDEs like IntelliJ.


IntelliJ/Cursive is about half of the marketshare according to developer surveys. It is quite capable, actively maintained, and certainly not a "dead end"

👍 2
David Caudill18:08:07

So i have Cursive set up...I think? but i am encountering what I think is a bug

David Caudill18:08:45

it's eating my keypresses of ) which is maddening.


it's likely not a bug, just structural editing. I haven't typed ) in a very long time


“structural editing”


you are using parinfer/paredit

David Caudill18:08:01

wow and i didn't even know what it was


it’s different and you’ll need to adapt a bit, but more powerful

David Caudill18:08:32

ok but not letting me end my hello world function is...not that helpful right now

David Caudill18:08:10

i've not been this confused by a computer since i was a child

David Caudill18:08:15

and i'm enjoying it

😆 4

If you need it there's a #cursive channel here as well.

David Caudill18:08:55

i was really hoping cursive would just let me run a .clj file and debug it

David Caudill18:08:23

i didn't know that 20min later i was going to be looking up barf


I think for a beginner you’ll be happy with about 2-4 “moves”


In general, Clojure tooling assumes a "project" so just editing and running code on its own isn't "usual". What languages/tooling have you used prior to Clojure @davidkcaudill?

David Caudill18:08:43

I'd say primary fluency is Python


OK, so Python isn't project-based. A lot of languages are, so in Clojure you're nearly always going to have a project.clj file (for Leiningen) and a src folder with your source code in (or deps.edn for the Clojure CLI stuff but, again, with a src folder).

David Caudill19:08:11

ok is there a name for this standard in clojure?


Not sure what you mean? Those are the filenames used by those two tools to describe the project, in particular the dependencies (other libraries) that the project uses.

David Caudill19:08:39

i guess what i'm asking for is a name for that project convention

David Caudill19:08:00

something i could google and figure out a little more, later on


It's sort of inherited from Java and a number of other languages that have project-based structures by default. If you run lein new app myapp it will create a minimal project (in the myapp folder) with project.clj, src, test, and several other files that you typically find in a Clojure project.


(a lot of Java projects use Maven as their build tool and that has a slightly different convention in that source goes in src/main and tests go in src/test but otherwise the structure overall is similar with Maven's pom.xml at the top, describing the dependencies etc)

David Caudill19:08:32

thanks! and yeah i thought i recognized some java conventions here


You'll be exposed to quite a few Java-isms as you learn Clojure since it is a hosted language -- expecting to run on the JVM (or, for ClojureScript, expecting to run on a JS engine in a browser or Node.js on the server). Dependencies, packaging of libraries, stacktraces -- those will all expose the underlying platform.


braveclojure starts with a leiningen setup

David Caudill19:08:59

it's very mac-focused as a book though

David Caudill19:08:21

i am just hoping to get up to a place where i can put code on the screen and modify/run the code


Clojure tools and docs generally assume macOS/Linux. Windows is not as popular for Clojurians (which is why Windows tooling lags behind a lot in some areas).

David Caudill19:08:33

yeah it won't be my daily driver, i expect to use MacOS at work


Just for context and Q15 in the full results shows the O/S breakdown:

MacOS                52.71%  1,305
Linux-based          37.04%    917
Windows with WSL      4.97%    123
Windows without WSL   4.77%    118

David Caudill19:08:11

hm this seems like it's not a great use of my time and I should just wait to start my job next week :thinking_face:

David Caudill19:08:01

the docs for everything are missing Windows sections, missing changes in windows, etc. For instance: Cursive's docs on how to turn off structural editing, haha


For Cursive, the menus and options should all be the same between Windows, macOS, and Linux but the key bindings will all be different I suspect.


> Structural editing comes enabled for Clojure code by default. If you don't like it, you can turn it off at Settings→Editor→General→Smart Keys→Use structural editing. nothing os specific in that

David Caudill19:08:52

nope there's not

David Caudill19:08:59

except that's not where it is at all


note that the pages for cursive have a toggle for which flavor of os to show so make sure it is on win/linux

👀 2
David Caudill19:08:41

omg that's a lifesaver thank you

David Caudill19:08:50

but yeah those settings have all been moved

David Caudill19:08:03

nested one layer deeper and renamed

David Caudill19:08:21

and it's felt like every single step of this process has been that way!


yeah. same in osx. i think intellij moved things in general

David Caudill19:08:10

that's pretty typical

David Caudill19:08:24

and NORMALLY nbd! but when you barely have a clue what's happening, ugh


if you keep a list of these things, i bet the author of Cursive, Colin, would love these things that beginners run into

David Caudill19:08:36

that's a great idea!


he's very responsive. and i believe cursive is one of the few paid developer tools

David Caudill19:08:49

ahhh turning off this super strict editor is SO MUCH BETTER right now

David Caudill19:08:03

i'll turn it on when i don't need to learn the syntax


you'll be back 🙂

😄 2

Once you get used to it, the (strict) structural editing will save you a lot of pain with mismatched parentheses -- and you'll come to love being able to manipulate "forms" instead of just characters/text. But it does take some getting used to.


You'll also find, again once you get used to it, that have a live REPL running all the time, where you develop by evaluating code into each with just a keystroke as you are developing, will make you super-productive -- and you'll wonder why you could never do that with other languages. REPL-Driven Development is the "superpower" of Clojure.

❤️ 5
Panagiotis Mamatsis20:08:54

Good evening everyone. I have a question regarding Emacs. Why so many Clojurians are using it? I am currently using VS code but in most of the videos I see the presenters are using the REPL or Emacs editor!


Why is Emacs usesd so much? Emacs always provided excellent support for Clojure and a great many other languages. There still remains the most diverse set of add-ons (packages) than any other editor. It's also free. Emacs is highly customisable, so the experience can be tailored exactly to an individual need. If your looking for easy of use, then Spacemacs is arguably the simplest way to use Emacs with its consistent mnemonic menu system. There are many other community configurations for Emacs. There is a wide range of editors that support Clojure and REPL driven development


For a while I was obsessed by learning niche / new languages, and the pattern I discovered was that emacs had the magic sauce so you could get the most editor integration for a new language with the least effort required from the people inventing the language.


I no longer use emacs (for reasons that aren't relevant to this discussion) but it's pretty hard to avoid running into, especially in the open source world


Emacs is nice…

Johannes Neugschwentner Johannes20:08:29

hi guys 🙂 We're doing a project involving clojure fullstack with re-agent/re-frame on the frontend ... I am to set up a convention for how to create our components and we wanted to stick to them being form2-components with typically

[props & children]

Johannes Neugschwentner Johannes20:08:29

now when I use nesting of component I iterate the children in the last/base component and hand them react :key props/ids ... but the browser is uttering missing :key warnings anyway ...


can you post a snippet of your code? it will much easier to help that way

Panagiotis Mamatsis20:08:38

Thank you so much for your explanation! I will give Emacs a try!

Panagiotis Mamatsis20:08:09

Actually I am using VS code daily and in between I am squeezing my Clojure education!!!


@pmamatsis jokes aside emacs is nice but the people that use it have been invested in it for a long time. We write our own functions and shortcuts, tools etc. if you’re new then absolutely give calva a try. I live in emacs even when not coding so I simply have no reason to leave

👍 2

Why is Emacs usesd so much? Emacs always provided excellent support for Clojure and a great many other languages. There still remains the most diverse set of add-ons (packages) than any other editor. It's also free. Emacs is highly customisable, so the experience can be tailored exactly to an individual need. If your looking for easy of use, then Spacemacs is arguably the simplest way to use Emacs with its consistent mnemonic menu system. There are many other community configurations for Emacs. There is a wide range of editors that support Clojure and REPL driven development


I'm trying to write some integration tests for the first time but I'm getting inconsistent results between test runs and I can't figure out why at all. Here is my test file:

(ns sheluchin.prj.query-test
  (:require [clojure.test :as t]
            [crux.api :as crux]
            [fulcro-spec.core :refer [specification  ;; a wrapper for deftest
            [sheluchin.server.db.queries :as q]

(def crux-node nil)

(defn with-crux [f]
  (with-redefs [crux-node (crux/start-node {})]

(defn with-note-list [f]
  (let [note-list {:note-list/id :singleton}]
    (q/new-note-list! crux-node note-list)
    (q/delete-note-list! crux-node note-list)))

(t/use-fixtures :each with-crux

(t/deftest fixture-test
  (t/testing "Do fixtures work?"
    (t/is (= #{[:singleton]} (q/get-note-lists crux-node)))
    (t/is (= [:crux.tx/tx-id :crux.tx/tx-time]
             (keys (q/new-note-list! crux-node {:note-list/id :test-note-list}))))
    (t/is (= #{[:singleton] [:test-note-list]} (q/get-note-lists crux-node)))))
Sometimes it totally passes and other times I get inconsistent failures. My understanding is that use-fixtures with :each should wrap the whole deftest, and those records I'm creating should always be available. I have no idea why the results are inconsistent between runs.


does the code under test use threads? with-redefs has concurrency bugs


My own code does not, but I'm using Crux there and I don't know whether it's threaded under the hood, if that matters..


it's not a likely cause of the error, but I don't see anything else suspicious here. are you sure about the order of use-fixtures args? if it works like comp that order is backward and the docstring doesn't specify


@alex.sheluchin it's terrible that one needs to dive so deep, but yeah the order is like comp, the ones at the end are in the inside (called first)


had to go into the defmulti definition of :each for use-fixtures, and from there find usages of ::each-fixtures, which leads to join-fixtures which finally leads to the function compose-fixtures which does the work


Let me try with with-crux last in the fixtures list.


maybe the real lesson here is that for fixtures like yours where the correctness of one relies on the ordering in relation to others, they shouldn't be added as separate fixtures


since nothing in the docs make a promise about that order of application


But I'll need the Crux DB support for many different tests. I thought making it its own fixture would keep things DRY.


but as written you also need to copy/paste the function into every namespace that uses it


Yes, I was planning on making a fixtures namespace and putting it there.


OK - that's your call - I think there's more chance for things going wrong when you implicitly rely on fixture ordering than if you combine two functions yourself to make the ordering explicit


you can still separate the function - it just doesn't have to be a fixture


Something doesn't seem right. When I put with-crux last in the fixtures list, the remaining code doesn't have access to crux-node at all.


OK - there's a decent chance I misread that code above then


Slight tangent.. is the Mount library commonly used in cases like this?


the way it would work with mount / integrant / system etc. would be that the crux db would be passed into a component for it to use, and it would be similarly be passed in when testing


which is slightly awkward with clojure.test since clojure.test expects dynamic vars for providing data, but it's not too hard to wire up


it doesn't really change what these tests would look like


they would impose an order on the setup / teardown, so the misunderstanding I just had would be less likely to be a problem


lol I'm almost totally positive the misunderstanding here is mine, I just don't know what I don't know.


with-redefs replaces your crux-db var (stashing the old value) then runs your code then resets it to the previous value


if this happens in two threads at once you can lose the original value entirely but that's not really a problem here


if it's not a question of your fixture ordering (which it looks like you just ruled out) it has to be an issue with code outside this test ns


Indeed. I'm gonna take a walk and get back to this with some fresh perspective, hopefully 🙂 Thanks for the advice!