Fork me on GitHub

I have some weird shenanigans going on. I have a log message that indicates an error:

:dal.secretsmanager/token "51680555-f0c4-43ef-a5db-c5c75e7e5cdf",
:clj.core/step "createSecret"}

Assert failed: (s/valid? :dal.secretsmanager/secret-id secret-id): java.lang.AssertionError
java.lang.AssertionError: Assert failed: (s/valid? :dal.secretsmanager/secret-id secret-id)
at dal.secretsmanager$read_secret_metadata.invokeStatic(secretsmanager.clj:43)
at dal.secretsmanager$read_secret_metadata.invoke(secretsmanager.clj:43)
at clj.core$secret_already_created_QMARK_.invokeStatic(core.clj:33)
at clj.core$secret_already_created_QMARK_.invoke(core.clj:30)
at clj.core$route_event.invokeStatic(core.clj:86)
at clj.core$route_event.invoke(core.clj:79)
at clj.core$_handleRequest.invokeStatic(core.clj:110)
at clj.core$_handleRequest.invoke(core.clj:104)
at clj.core.handleRequest(Unknown Source)
however, I take that same input and call it in my repl and no error:
(let [{::secretsmanager/keys [secret-id token]} event
      {:keys [step]} event]
  (do (pprint event))
  (secret-already-created? secret-id token)) ; =>

 :dal.secretsmanager/token "51680555-f0c4-43ef-a5db-c5c75e7e5cdf",
 :clj.core/step "createSecret"}



why would that map be valid in the repl and not in the environment where it runs?


Do you perhaps have assertions disabled in your REPL somehow?


no, but I did just put a pprint in and I see that somehow the first param being passed to secret-alreadycreated? is nil


I'm not sure how it's becoming nil yet


(let [{:secretsmananger/keys [secret-id token]} event
            {::keys [step]} event]
is there some way that this mapping is wrong and resulting in a nil?


for context, an event is generated by this:

(defn- marshal-event [event]
  (let [{id :secret-id
         token :client-request-token
         step :step} event]
    {::secretsmanager/secret-id id
     ::secretsmanager/token token
     ::step step}))


I think I found it: s|:secretsmananger/keys |::secretsmanager/keys|


Hey folks, can you explain difference between what agent, atom, ref is and an example of use case?


yeah, but I’m still confused 😞


There are kind of two ways to talk about agents, one is by comparing them to clojures other reference types, the other is by comparing and contrasting them with actors, which you may be familiar with from other languages


The reference type stuff is really good because you get in to how clojure models identity, and there is a great rich talk about it, and the agent stuff is just kind of an addendum to that (which is fine because agents aren't really used much anyway)


An agent is a reference type, sort of like a pointer. You can deref it to get it's value, and it's value can change. Clojure has a number of reference types that have different rules that govern how their values change over time


Agents are asynchronously (changes are queued up and happen later) and atomically (one change at a time is executed, and only complete changes are visible) updated


If you want to transfer money from one account to another without it getting lost or double-counted temporarily, you either need (a) to put the state of each account into its own ref, and use a ref transaction to do the money transfer, or (b) put the state of both accounts (and perhaps many more) into one place, like an atom or agent, and update the information about both accounts in the same update operation.


That maybe helps illustrate the difference between the ability of refs to perform coordinated updates across more than one ref, whereas that is not possible across multiple agent or atom instances.


In Clojure, what's the right word for what I used to all "objects" in Java? Like, think of collections of homogeneous, composite values. "Customers" "Books" "Movie listings" ---- things like this. What do we call these?


Composite values in Clojure are hash maps. We have collections of those.


@chepprey There is only "data" in Clojure really.


Perhaps the closest thing to a "common name" is ...


maybe a "record" is somewhat like a (immutable) java object. (defrecord ...)


I just use hashmaps. But records are there I think for speed.


I'm just using hashmaps too, I'm not doing anything idunno substantial, not yet. Just a tinkering noob with a pet project. I wanted to ask a completely different question, and then worried that I didn't have the right word to use for what I keep thinking of as "object".


Prefer hash maps to records.


Let me ask the question, with bad terminology, then maybe you can see what I mean...


So I got this vector of objects. Each object has a timestamp. I want to transform this vector into some other datastructure such that I can group the objects up by calendar date.


A vector of hash maps?


fwiw the point of transforming the data in the vector is to create hiccup for rendering html representation of this data.


The raw data is indeed a vector of hashmaps


Then just call them maps or hash maps.


Id phrase it "I have a vector of hashmaps. Each hashmap has a key :timestamp with a timestamp as a value"


"So I got this vector of maps. Each map has a timestamp. I want to transform this vector into some other datastructure such that I can group the maps up by calendar date." 🙂


just like that huh? ok. 😄


and you want group-by 🙂


[[ races to clojuredocs tab, ctrl-s... ]]


pass in a function that takes one of these hashmaps, and returns a key to group under. You would make your own little func that returns some value representation of your 'interval'


omg group-by that's cheating


You can re-implement group-by yourself if it helps you feel less like cheating 🙂 Or, just move on to the next part of the task you started with, smoothly and efficiently.


well it'd be a good thing for me to at least peruse the sourcecode to see if I had a chance at hacking it out myself


When first reading its source, you may want to ignore the call to persistent!, replace (transient {}) with {}, and replace assoc! with assoc. If you understand it with those changes, then go back to the original, which has those things in there for lower CPU time cost for calculating the result.


you could think about it as a reduce over that vector. You have a whole bunch of things to go in (the collection of items), and one composite 'thing' to come out (the hashmap representing the final grouping). Good indicator it could be done with reduce. There will be multiple ways to do it of course...


I swear sometimes i think i need some kind of medication to help me with suffering "the shakes" when I can't just solve every problem with building mutating for-loops


It is a mental shift, to be sure, that even experienced Clojure developers experience sometimes, especially if they switch between programming languages often enough.


Interesting. Ya, I've been studying reduce, reduce-kv lately, seemed like these were in the neighborhood of what i needed


... but didn't quite fit. Then I figured I'd go recursive, loop-recur... while having a guilty feeling like "if you're using loop-recur you can probably find a more functional way to do it"


theres nothing wrong with using loop recur. I used it a lot when beginning. And having a really firm grounding in loop/recur really helps you long term.


Hmm, you need to be careful: Clojure's loop/`recur` is not like loops in most languages. I'd advise beginners to try to avoid it as much as possible. There's nearly always a better option.


I found not only that loop/recur really helped me bridge early on, I found it greatly improved my loopy code in other languages


my project impacts nobody but me so, bull-in-china-shop approach is low risk 😉 I'm a Clojure beginner but I've been slinging corporate Java for 24 years. So i dunno where i fall on the overall beginner spectrum. I think i get the uniqueness of loop recur tho (the fallback approach when you don't have TCO in the jvm)


i still use loop/recur all the time inside core.async in cljs. making web games.


@chepprey Your biggest adjustment is going to be that you have no assignment statement (and our "objects" are all immutable) 🙂


I started with clj. Came from long time python. then cljs came later


but I have friends who started with cljs went the other way


whatever your path is...


I started doing Java back in '97 I think (after doing C++ for years before that), so I sympathize with where you're coming from @chepprey


oh i ❤️ immutability. I'm a total fanboy of the RichH church of language opinion

rich 4

been watching the talks since clojure first came out. I created the 4clojure google group many years ago 😎 but it's only been the last couple months that I actually finally knuckled down and REALLY made something with it


@deleted-user I think look for a tutorial or guide that sets you up with figwheel


lein new figwheel myproj is a good way to start. cause its quite simple template


just client side


with all your hotloading goodness setup


there you can play with just cljs, without having to think about server side, clj, nrepl etc


(or take a look at shadow-cljs which is getting a lot of praise too -- Eric Normand wrote glowingly about it in his latest newsletter)


that one is also purely client-side


then when you are ready add in the server side. and then when you are ready for alien spaceship features, start writing cljc


which is truly a transformative experience


I last did cljs back in 2014/2015 when tooling was very primitive. I plan to set most of this weekend aside to revisit cljs 🙂


transformative - but only produces a new altered copy of you, leaving the original you unchanged.


figwheel is amazing.


cljc made me realise that its so much more than just "the same language on server and client"


so much more that using something like js


because you can intersperse in the same file, client, server, and both


question - i started w/ my server side first, using emacs/cider... I got used to editing code and eval'ing individual eh functions (forms?) c-x c-e...


so for instance, my latest project is a multiplayer online game. And I wan write 'workflows' in cljc, that start with the initial client code, then the server function to handle that network message, which then sends back to the client (the receiving client func comes next)


and the file reads top to bottom of the complete network protocol


but when i went to the cljs / shadow-cljs tutorial project, that became such that saving the file is what re-evaled everything in the file


yeah I use cider. and fighweel hotloading together.


i wondered if that is specific to shadow-cljs, maybe figwheel works more fine-grained? I've also read you CAN use figwheel and shadow together, although I don't understand what that would really mean.


does shadow use figwheel?


I'm used to just eval'ing code from my editor directly into a running image -- I don't like save/watch/reload workflows so I hope I won't have to do that with cljs!


@crispin that sounds awesome. In my environment there is no figwheel. But it's a good question, what would it bring to the table w/ shadow-cljs, i'm not really sure


figwheel brings up compile errors on your DOM


hihglights the code


(I thought it was either/or? You use figwheel or you use shadow-cljs?)


you can click on it and it drops your editor to that line


its mostly the hotloading functionality


so save file, code is compiled, passed over websocket, inserted into js runtime


@seancorfield 🤷 perhaps that's true. Maybe I can google around and find what I was reading that suggested both could work together...


huh yeah. shadow looks like figwheel.


filling the same spot I think. Use whichever you prefer


Scroll down to Yogthos' comment


but shadow should also work with cider repls


yeah. so its another hotloader. fighweel works with browser and node. and so does shadow.


OK so I just tried in my Emacs/cider, I have a shadow-cljs REPL, in my source file (not directly the repl) I just did a (def n 3) c-x c-e and it eval'd. Type "n" in the repl and I got 3.


I don't use node. I just use JVM server side.


I'm not sure why I thought I had to save the file. Anyhoo - eval'ing forms seems to work as expected.


yeah. and c-c k for full namespace re-eval (without save)


so in the file you have a namespace, say (ns foo.core ...)


and in that file, in that namespace you eval (c-x c-e) a definition like (def n 3)


(this is ALL cljs files)


no go over to the console on the browser window and type




you can see its there in the pages js context under its namespace


(in advanced compilation these names get minimised, but you can see how it does it)


so figwheel/shadow can be hotloading you files when saved into the browser context


and you can be linked and evaling inside cider aswell


you should also get println logging into you emacs repls


add the chrome clojure dev tools, and you can open and examine clojure datastructures inside the console in the browser


so if you did (js/console.log "my thing:" my-thing) or (println ...)


that would log out to the browser console


with little colapsey arrows


yes, i've had that going already (logging)


that you can open up and examine as clojure data


I don't know any other stack like this. It's heaven.


actually have a TODO to check out tap> for logging


dunno if it's in cljs yet tho (my todo was for clj)


when you get server and client together, cider routes automatically!


so you have two emacs repls, one server clj, one client cljs


and if you c-x c-e in a clj file, it routes it to the server repl


and if you are in cljs, routes it to client repl


and in cljc to both


I also use c-x c-e in cljs namespaces to examine and debug


man i wish we could use this stuff @ my day job.


so if there is, say, (defonce state (r/atom {}))


after that I put #_ @state


that is. ignore the next form (so it sompiles without it), and then deref state


you can put your cursor after the @state, go 'eval' in cider, and it will pretty print out whats in the state atom on the client


awesome for debugging


build little snippets in cljs and eval them to examine state deeply


like 5 years ago i was trying like hell to get other devs interested in clj.... we make full-stack stuff. Having the same language on client & server is SO useful it's why we actually use GWT a lot, even still now. ..... but, tragically in 2014 our wee company got bought by supermassive black hole borg company, and i suddenly became a very small fish in a huge pond, and changing away from Java & JS is not an option. 😢


yeah, I hear you. Not everyone is ready to walk the path. :man_in_lotus_position:


tap> is in latest CLJS

👍 4

hi all, I am working behind proxy and cannot connect to maven central directly. In case of lein, I am using :mirrors to specify artifactory URL. I want to try clj tools now. How to specify artifactory url in deps.edn?


:mvn/repos at the top level


what's your favorite way to namespace your projects? I tend to have core for orchestration actions (bringing it all together), I tend to have util for pure functions and dal/`data_access` for functions with side effects


I try to avoid core as much as possible -- that's really just a weird artifact of Leiningen's default from long ago.

😮 4

util is also something else I try to avoid (that said, I think we have one at work).

😮 4

😆 now that I guess I'm doing everything not to do, what do you like to do instead?


It's hard to generalize. At work, when we started, we used worldsingles as a prefix for most namespaces and kept them broader and somewhat generic. So we had worldsingles.user,, worldsingles.reporting etc.


We've since adopted ws as a prefix and gone to more deeply nested naming.


Simple examples:,, (that's another search engine).


oic ... so you don't group things by queries vs commands or pure vs side-effects?

seancorfield05:06:35, ws.messaging.logging


It generally makes more sense to organize to match the domain, in my opinion. Trying to split code based on its implementation is rather artificial.


That said, as shown above, we do have some namespaces that are all about side effects 🙂

👍 4

cool, thanks for the tips


Some things to consider: it's common practice, when you require/`as` to use the last segment of the namespace as the alias -- so you don't want to reuse that last segment too often or you won't be able to require in those namespaces without inventing new aliases.


Also, many editors only show the filename on the tab, not the path, so you don't want lots of some/thing/core.clj files 🙂


What’s the difference between concat and lazy-cat?


looks like lazy-cat is concat but is lazy in its consumption of input sequences. That is the body of one of the input sequences will only be invoked when the element is pulled from the outer lazy sequence


I've never used lazy-cat, but it is literally a macro that wraps its args in lazy-seq and passes those to concat.


but concat also returns a lazy-seq


so (lazy-cat xs ys) === (concat (lazy-seq xs) (lazy-seq ys)) === (lazy-seq (some-real-concat-func (lazy-seq xs) (lazy-seq ys)))


So I still don’t see the difference.


they both return a lazy-seq


so if I go (concat a b c d e f g h i j k l m) a...m are all evaluated. and the value is passed into concat... which returns a lazy-seq


if I go (lazy-cat a b c d e f g ...) non of them are evaluated... until they are needed... by consuming elements of the return value from lazy-cat


I think I got the idea. So it’s function vs macro, and the difference is not the return value or the goal, but whether the args are evaled when invoking. Thanks!


imagine if those body args, a to m, were something very concrete. Like a loop/recur that returns a collection


in the concat, they'll all run first, and then pass their collections to concat


in lazy-cat they will evaluate, and cache, their values as needed


I guess its tricky to see because if you pass lazy-seqs themselves into concat, it would behave just the same

jason poage07:06:13

How do I import compiled cljs files into my react project? i created an example of what im trying to do here


@jason821 there are many ways. are we doing development or release builds? Are you preserving namespaces or minifying/munging them? Are you integrating with existing javascript react code?


if you turn advanced compilation off on your production build: set :optimizations :simple here:


then you can build, with lein cljsbuild once min a js artifact that will be written here:


do that, then open the js file in an editor and have a look

jason poage07:06:28

i have a react project that i want to finish writing in clojurescript and eventually rewrite the javascript parts

jason poage07:06:02

im not sure how to answer those questions, i guess i dont have any release builds and its still in the development stage. its not fully functional quite yet


Are there any good tutorial on how to get started with Clojure using Maven? I am in the java enterprise.


@jason821 there are many ways to do it but your big problem will be conflicting versions of react. Your cljs dependency (reagent/om/rum) will bring its own react dep, and your js will bring their own. There are different ways to resolve the conflict. My advice, seeing as you are still in dev, and you intend to rewrite the whole thing anyway, is to start with fresh cljs toolchain using whatever library you choose, and then drop in the old js react components as js source code feeding into the compiler, to build a single optimized .js output artifact at release.


you can feed the old js in as inputs to the compiler, or you could keep them seperate and import the scripts into the browser. I would want to try to get it feeding in pre compiler so it passes through the google closure compiler optimizer with the cljs compiled source.


you can mount js react components pretty easily in reagent/om/etc

jason poage07:06:07

It’s so close to done that most, if not all, of the react components are already written. i can read, write and display the data as expected, but i havent implemented the delete and put operations yet. other things like cookies, authentication and sessions i havent even started with.

jason poage07:06:26

i can console.log the value of my clojure function from react now that i did what you suggusted, but now i get “failed to compile” from react

jason poage07:06:49

with lots of “Expected an assignment or function call and instead saw an expression” errors


where do you get "failed to compile"?

jason poage07:06:35

instead if displaying content, it displays


the artifact produced by cljsbuild should not be fed into another compiler...

jason poage07:06:58

“failed to compile” along with two thousand lines “Expected an assignment or function call and instead saw an expression” and at the very end “Java is not defined”


is thats what happening?


going into some node thing?


you want to bring that cljs .js artifact in at page root

jason poage07:06:44

so the only way to do it is to feed js into a cljs compiler?


with a script tag

jason poage07:06:38

how do i call clojure from javascript then? do i need to import anything?


after that is loaded, you will have the namespaces in the js window namespace

jason poage07:06:21

will i be able to access it within react?


so myproj.core namespace function my-func


is at js: myproj.core.my_func

jason poage08:06:15

so i dont need to import it into react, i just need to call the namespace?


just be aware, when you switch on advanced compilation this is no longer true


but one thing at a time


(in advanced, myproj.core.my_func may be Cx.Od.f4 one compile and the next. You have to declare 'exports' to preserve the clean namespace interface of select functions)


you will want to also probably :exclude the inbuilt react from your cljs deps if you have them


so if you add a dep to your cljs project of reagent, that will bring its own react, and that react will be bundled and minified into that js. So you need to :exclude it

jason poage08:06:25

i probably wont be using react with cljs conisedering most of the react stuff is done, so dependency shouldnt be an issue


ok cool. then theres no problem

jason poage08:06:18

so i include the compiled js file in the index.html in a script tag in the head section?


you can coral the data in and out of js with clj->js or the reader macro #js


after that script is loaded, check the namespace is there in your console


and you can call it

jason poage08:06:16

ok so i did that. now how would i reference from within the js project.core.hello_world()?

jason poage08:06:37

because i tried it just like that, and it says project not defined

jason poage08:06:18

or well in my case, the project name is “hello_world” and the function is hello_world.core.hello_world


do you have the hello_world in the console at all


like go in and type hello_wo... see if it completes


open the compiled js artifact


search for hello_world=... is it in there?

jason poage08:06:18

the output from the function shows up in the developer console, but somehow it still says hello_world is not defined. im not sure how it thinks its not defined but can still access its value

jason poage08:06:38



so you go to console


type hello_world and hit enter. what does it say?

jason poage08:06:36

it gives me the object from the hello_world namespace

jason poage08:06:11

and says the function is located on line 2122

jason poage08:06:18

is somehow the react script is getting rendered before the clojure script?

jason poage08:06:12

i tried moving it to the top of the document but still nothing. the error in the console shows up after the output of console.log also


can you delay the mount of the root react component in the js until the namespace is loaded and defined?

jason poage08:06:11

with set timeout?


or allow it to be null, and repaint it later when its not?

jason poage08:06:30

yeah ill give that a shot


its not ideal


but it can get you started


the other thing to check is any async/defer props on script tags in your html. both the cljs build and the javascript

jason poage08:06:56

it seems that for every file that uses that name space i would have to make that check, because it imports and checks if its defined before the scripts are ever even executed


Im starting to get outside my paygrade, because I do it reverse. Import the js into a cljs project and bundle as a single artifact.

jason poage08:06:46

lol i cant believe how difficult this is


Im not sure how you are calling the cljs. cant you just go hello_world.core.hello_world() in the code?


the browser is well complicated


you've only scratched the surface

jason poage08:06:30

yes, thats whats happening. it both knows the value and thinks its undefined


it could be your js compiler?


not sure of your js toolchain

jason poage08:06:13

im using the react scripts


no sure of any js toolchain cause I don't use them

jason poage08:06:21

the only option i can think of is have a file that does a check on the name space then exports the namespace. ill give that ashot

jason poage08:06:42

then ill just have to import that file if i want to use the namespace


so are you going foo = require('....')? with the cljs namespace?


try not doing that. Just use the namepace

jason poage08:06:14

how do i create an async function that returns a value after a timeout?

jason poage08:06:07

oh yeah you dont do javascript lol


i get the feeling your js react side is trying to be 'clever'


and thats printing the undefined?


why not just try a timeout


setTimeout(1000,function(){/mount react root/});

jason poage08:06:40

it loads the files, does error checking. then executes the scripts. at least thats how its acting. but its not quite exactly like that though because console.log gets executed just fine. it doesnt make sense

jason poage08:06:30

so im working a file that will return the namespace once its been loaded. hopefully that does the trick


also instead of :simple try :whitespace under :optimization just.. in... case...


might be the simple optimisations stuffing with the interop?

jason poage08:06:34

my idea for it to timeout first doest work and i know why now. it has nothing to do with the order things are loaded or executed. the timeout doesnt work, because “typeof hello_world” returns “object” but then later react says is undefined because its not actually defined within react.

jason poage08:06:01

im going to give :whitespace a shot


and the cljs js compiled artifact be the first script tag


i thought script tags were blocking...

jason poage08:06:16

im thinking its not the script tags and its the compiler.


js ocmpiler, or cljs compiler?


are there options to make is less strict. So you can use an expression that it just accepts, and doesn't try to source and examine at compilation?

jason poage08:06:59

like its ignoring the script tag, but the browser regonizes it so it the browser reads the value from the cljs but the react part of it doest recognize it in its own script so it thinks its not defined

jason poage08:06:16

im not sure but probably


yeah and thats at js compile time?


that it doesnt recognise


thinks its undefined?

jason poage08:06:57

it doest give me the error in the terminal


Im not familiar with how the nodejs react tooling works


so if you create a function in js side, that calls the function in cljs


so in js, function test_call() { return hello_world.core.hello_world(); };


and then load the page up with both scripts loaded


and then, in the console, go test_call()


does hello_world run?


(i want to see if the js compiler preserves the call inside the function)

jason poage08:06:00

the test_call() is undefined


there is no test_call?


or it returns undefined?

jason poage08:06:42

uncaught reference error


the js compiler at least needs to output the code, or an error. check the settings of the js compiler

jason poage08:06:39

the window variable doesnt return any of the functions in my react app, at least not on the top level. its probably nested somewhere

jason poage09:06:30

so i got it working

jason poage09:06:11

you have to reference it from the window object, which i think you said something about that earlier. so window.hello_world.core.myFunc() works just fine

jason poage09:06:32

I can’t believe how many hours I spent on this.

jason poage09:06:18

thanks for all your help, i really wouldnt have been able to figure this out without you!


glad I can help


you wanna try advanced compilation now?

jason poage09:06:34

yeah i already did.


and you added the :export metadata?

jason poage09:06:49

lol it was the last thing i tried before i actually tried the thing that works

jason poage09:06:01

what does that do?


ill get a link

jason poage09:06:46

this is going to be so awesome. i can finally start writing clojurescript =D


you add :export key metadat to the function (defn ^:export my-func [] ...)

jason poage09:06:33

oh yeah i’ve done that


and that func wont be munged by the advanced compile


it should be exposed for calling from the other js artifact


those docs will go into more details now you've got it working

jason poage09:06:28

now i just have to figure out how to call javascript from clojure (not clojurescript), and i’ll be all set


you use the js namespace

jason poage09:06:48

is migrating from clojurscript to clojure pretty easy?


(js/my_js_func ...)

jason poage09:06:38

because after i rewrite my backend in clojurescript, i would want to just go to clojure. i would only write it in clojurescript if it would make it easier to make the migration from javascript

jason poage09:06:00

so you can call javascript and java from clojure?


its different. cljs is not js. and something like figwheel + reagent is a lot more than react.


the datastructures are obviously completely different


you will have seams... edges... where data needs to be coralled and reformatted form the js world to the cljs world


and visa versa


going all in on cljs that is not the case

jason poage09:06:55

i can just format to json though, or is there a better way?


you will have to


depends what your doing and talking to


I use transit + msgpack between client and server


just saying that theres cljs<->js interop... and then theres it just written in cljs. With atoms and reactive hotloading state preserving joy. And bolt devcards on...


java and clojure have full interop aswell yes

jason poage09:06:55

but not clojure and javascript?


cljs and javascript do


so you can interop between C# and

jason poage09:06:41

so if i migrate 100% to cljs on the backend, how would i switch over to clj? how much different is clojure from clojurescript?


i use clojure on backend


but you could also use cljs on node if you want cljs on both ends

jason poage09:06:16

thats the end goal, but right now i have javasript on the backend

jason poage09:06:24

so im not sure if i should go from javascript to clojurescript to clojure, or if i should just go straight from javascript to clojure.


clj on jvm is very powerful. lots of great libraries and ecosystem. multithreaded joy. has more advanced construct of time primatives if they are needed (cljs only has atoms. clj has refs and agents).


but your server is already written in javascript


also, how well do you know node. If you are a node gun... maybe you want to leverage that knowledge

jason poage09:06:26

would it make more sense though to migrate to clojurescript first though, or would it make more sense to just migrate to clojure? the backend is more flexible, because i can have two servers talk to each other, i could hypothetically have my backend server written in several unrelated languages

jason poage09:06:12

or i could have the front end talk to the server it needs for the particular data it wants


maybe you dont need to rewrite the backend at all?

jason poage09:06:14

well if clojure can offer me more because it runs on the jvm, why not?


IMHO it offers you much more


also, it tends to be the setup most people use. So the path is more well trodden. Less weird issues. Better integration


I start my projects with the luminus template when doing client and server.


it might be a good little walkthrough to go through, so you can see the client and server set up togather and how it works.

Crispin09:06:35 there are other options, too. But this works for me.

jason poage09:06:08

that just basically gives you a bunch of tedious monotonous code so that you dont have to write it yourself or something? lol im not familar with using templates, i usually just write everything from scratch haah


yeah its just all that really tedious stuff set up for you

jason poage09:06:34

will it help me with a project that i’ve already started?


not so much. And impossible to 'update' later. Like as the luminus template improves, you don't get it in your old projects.


you can port the stuff over if you want. There are other projects. and even frameworks now. I haven't really used them.

jason poage09:06:20

so its almost better to just not even use a template then you dont have to worry about upgrading lol

jason poage09:06:12

is luminous comparable to rails? i’ve only experimented with rails, i started building a web site and halfway through i decided it was too complicated and dumbed down for me lol i plan on revisiting it sometime but for what im doing now, clojure makes more sense


not really. rails is more a framework. luminus is just a templated project with a bunch of other libraries included

jason poage09:06:23

so that you dont have to go out looking for those libraries?


there are clojure web frameworks, comparable to rails. like arachne or Om next? I'm not across them, but I know they exist.

jason poage09:06:37

true. it seems so far that if i only learned luminous, i wouldnt really need to learn anything else to do a majority of web development then


its a good starting point. But if im doing client only code (like a gamejam webgame) I use the figwheel template.

jason poage09:06:30

well this is confusing lol so many options


I would keep it simple


you only just got cljs code working


just stick to that


forget about server side for now


spend 6 months learning cljs and just using that cljs where you have it now

jason poage10:06:05

well i already have a server side app, but its seperate from the project im already working on


one thing about clojure that I didnt realise when I started is it is both very broad and very deep as a language

jason poage10:06:12

i created a simple server side clojure app that does several types of calculations and accepts a json object as input to generate a bunch of values based on the input. but then i have my js backend which is for the project im working on


like you can go down down down into one little thing, and its deep. like a full logic programming engine in core.logic


but you dont ever need to learn any of that


and its also broad


its running as js in your browser, and on node, and react-native on mobile, and on the JVM, and people are making .net apps with it....

jason poage10:06:53

you’re talking about core.logic doing all those things?


so just find where it helps you out, and use it there first. You don't need to chase all the butterflys at once. The mountain will wait for you.


no. core.logic is logic programming engine that comes associated with clojure. So think the language prolog


its like a lispy-prolog, embedded in clojure


theres deep holes everywhere you can go down

jason poage10:06:36

just focus on what i need at the time though im guessing is the thing to do


just start somewhere and use ti


and be patient

jason poage10:06:35

each of it is just someone else’s idea of the implementation


Hey all, pretty beginner question. I'm working on building an API using Ring and Compojure but I've been out of the Clojure world for about 2 years now and I'm hitting some weird behavior I haven't seen in a while. The code is really simple right now,

(defn- hook-handler
  "Handler for processing GitHub webooks."
    (response (:body req)) 

(defroutes app-routes
  (GET "/" [] (response "Success!"))
  (POST "/hook" request hook-handler) 
  (route/not-found "Not Found"))

(def app
  (-> app-routes
      (wrap-defaults api-defaults) ;; Ring middleware
      (wrap-json-response)))  ;; Ring middleware
But when I navigate to to just look at the response for a GET to /, I get a pop-up asking to download a file of type application/octet-stream. I've attached a screenshot if it helps. Any idea what's going on here?


try (ring.util.http-response/ok "Success!")


I still get that popup using ok. I did get it to work by using the ring.util.content-type function and casting it to text/html and application/json so I'm going to roll with that


debug the response map, see if the Content-Type header gets set correctly


I am using a validator package and it produces results like this-> {:email ("E-mail"), :pass ("Şifre")} how can I remove paranthesis is there a method to apply a function to all map values. (Expected result: {:email "E-mail", :pass "Şifre"})


yes but not in core,, (into {} (map (fn [[k v]] [k (first v)]) my-map)) would work too

Markus Åkerlund Larsson12:06:35

How do I get a working Clojurescript repl in Cursive? I've started one using the functions in figwheel-sidecar.repl-api, but after I do, I can't load and cljs namespace that depends on other of my namespaces, ordinary clojure namespaces fail if they have :gen-class, and can't find any libraries


thank you very much

Markus Åkerlund Larsson13:06:18

@manutter51 that seems to still have the same issues when loading clojure namespaces, and it would be nice to have to option to use nREPL


That’s odd, it’s working fine for me, although without the nREPL of course. Maybe you have a version conflict somewhere? There’s also File -> Invalidate Caches / Restart… Sometimes that clears out weird glitches.


Guys, what is the convention for placing tests? Do you have them 1) in the same file as src 2) in the separate file next to source 3) in dedicated <project>/test/ 4) else ?



☝️ 4

usually the test namespace is if the namespace being tested is


but this is a less strong convention than where the files go $PROJECT/test


Is there a way of running the tests in live REPL when they are placed in the default $PROJECT/test ? Aah, nevermind, got it, you just load the -test namespace to REPL as well 🙂


there are a few helpers in clojure.test, too @kyselyradek


Yeah, I’m looking at them now. Thank you 🙂


I think I got the idea. So it’s function vs macro, and the difference is not the return value or the goal, but whether the args are evaled when invoking. Thanks!


I'm living the Running with Scissors life but, I'm not doing a very good job of converting repl experiments into tests. Has anyone got a workflow they're happy with?

✂️ 8

@mathpunk Are you putting the "repl experiments" inside (comment ,,,) forms in your source files?


(that's what I do, so at least the experiments persist, even if they don't get into actual tests)


in my main project directory I've got a siderail/user.clj file


it's full of do statements


so that I can be sure to require and define exactly what I need


and then, Past Me, a doofus, extracts the useful functions to namespaces and leaves the do blocks in that user file


so I have documented how I used it, but, it is not what I would consider 'test coverage'


Are there any gotchas with rebinding the to the same name inside a let ?


(let [a 1 a (+ a 2)] a)


the second binding simply hides the first

👍 4

yep, that's my objective, was wondering if it was considered bad practice


it's good as long as it makes things clear - also that translates directly to (as-> 1 a (+ a 2)) (more useful when you have a longer series of bindings)


user=> (macroexpand '(as-> 1 a (+ a 2)))
(let* [a 1] (+ a 2))


maybe a more helpful example

user=> (macroexpand '(as-> 1 a (+ a 2) (* a a) (dec a)))
(let* [a 1 a (+ a 2) a (* a a)] (dec a))


got it, exactly what I need, had four rebindings


@lockdown- also like all the arrow macros, it's set up perfectly to be used inside ->


besides -> ->> does all include stuff like cond-> , some-> etc ? (haven't study those, just grepping through the api)


right, they all take an initial value as a first arg


which means that if you start with ->, you can do every nesting alternation of them you might need


re: that edit, of course -> turns nesting into sequencing :D


knowing some scheme, was accustomed to nesting 😉


as-> is really neat


it's useful for algorithms that work in terms of successive updates to a single target value


yep, very useful, clojure has all this neat macros to improve lisp readability


clojure-mode is indenting incorrectly because of calling as-> without the first arg (since is inside a ->)


oh yeah, that's a definite gotcha