This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2019-06-19
Channels
- # announcements (2)
- # beginners (448)
- # calva (10)
- # cider (27)
- # clojure (121)
- # clojure-argentina (2)
- # clojure-brasil (6)
- # clojure-chicago (1)
- # clojure-colombia (9)
- # clojure-ecuador (1)
- # clojure-europe (1)
- # clojure-italy (14)
- # clojure-mexico (1)
- # clojure-nl (19)
- # clojure-spec (11)
- # clojure-uk (160)
- # clojurescript (25)
- # core-async (7)
- # cursive (8)
- # data-science (1)
- # datascript (1)
- # datomic (4)
- # devops (2)
- # graalvm (3)
- # hoplon (1)
- # immutant (1)
- # jackdaw (32)
- # jobs (2)
- # joker (2)
- # keechma (9)
- # leiningen (26)
- # luminus (13)
- # off-topic (2)
- # overtone (2)
- # quil (5)
- # reagent (38)
- # reitit (13)
- # shadow-cljs (16)
- # spacemacs (2)
- # tools-deps (4)
- # xtdb (12)
I have some weird shenanigans going on. I have a log message that indicates an error:
{:dal.secretsmanager/secret-id
"dev/kashoo_bearer_token",
: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/secret-id
"dev/kashoo_bearer_token",
:dal.secretsmanager/token "51680555-f0c4-43ef-a5db-c5c75e7e5cdf",
:clj.core/step "createSecret"}
true
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?
Have you seen https://clojure.org/reference/agents ?
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 ref
s 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 https://clojure.org/guides/spec#_entity_maps ...
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.
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." 🙂
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'
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)
@chepprey Your biggest adjustment is going to be that you have no assignment statement (and our "objects" are all immutable) 🙂
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
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
@deleted-user I had a good experience with this one: https://github.com/jacekschae/learn-reagent-course-files
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)
then when you are ready add in the server side. and then when you are ready for alien spaceship features, start writing cljc
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.
cljc made me realise that its so much more than just "the same language on server and client"
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)
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
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.
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
(I thought it was either/or? You use figwheel or you use shadow-cljs?)
@seancorfield 🤷 perhaps that's true. Maybe I can google around and find what I was reading that suggested both could work together...
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'm not sure why I thought I had to save the file. Anyhoo - eval'ing forms seems to work as expected.
add the chrome clojure dev tools, and you can open and examine clojure datastructures inside the console in the browser
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
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. 😢
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.
util
is also something else I try to avoid (that said, I think we have one at work).
😆 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.search
, worldsingles.reporting
etc.
We've since adopted ws
as a prefix and gone to more deeply nested naming.
Simple examples: ws.search.common
, ws.search.elastic
, ws.search.discovery
(that's another search engine).
oic ... so you don't group things by queries vs commands or pure vs side-effects?
ws.messaging.io.mysql
, ws.messaging.logging
@johnjelinek It Depends.
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 🙂
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 🙂
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.
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 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
I guess its tricky to see because if you pass lazy-seqs themselves into concat, it would behave just the same
How do I import compiled cljs files into my react project? i created an example of what im trying to do here https://github.com/jpoage1/cljs-testing/tree/master/src
@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: https://github.com/jpoage1/cljs-testing/blob/master/project.clj#L47
then you can build, with lein cljsbuild once min
a js artifact that will be written here: https://github.com/jpoage1/cljs-testing/blob/master/project.clj#L45
i have a react project that i want to finish writing in clojurescript and eventually rewrite the javascript parts
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.
@jarvinenemil have you seen Stu's simple Maven example to call Clojure from Java? https://github.com/stuarthalloway/clojure-from-java
@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.
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.
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
with lots of “Expected an assignment or function call and instead saw an expression” errors
instead if displaying content, it displays
“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”
so the only way to do it is to feed js into a cljs compiler?
how do i call clojure from javascript then? do i need to import anything?
will i be able to access it within react?
so i dont need to import it into react, i just need to call the namespace?
(in advanced, myproj.core.my_func may be Cx.Od.f4 one compile and http://qG.ar.bb 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
i probably wont be using react with cljs conisedering most of the react stuff is done, so dependency shouldnt be an issue
so i include the compiled js file in the index.html in a script tag in the head section?
ok so i did that. now how would i reference from within the js project.core.hello_world()?
because i tried it just like that, and it says project not defined
or well in my case, the project name is “hello_world” and the function is hello_world.core.hello_world
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
console.log(hello_world.core.HelloWorld())
it gives me the object from the hello_world namespace
and says the function is located on line 2122
is somehow the react script is getting rendered before the clojure script?
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?
with set timeout?
yeah ill give that a shot
the other thing to check is any async/defer props on script tags in your html. both the cljs build and the javascript
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.
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?
yes, thats whats happening. it both knows the value and thinks its undefined
im using the react scripts
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
then ill just have to import that file if i want to use the namespace
how do i create an async function that returns a value after a timeout?
oh yeah you dont do javascript lol
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
so im working a file that will return the namespace once its been loaded. hopefully that does the trick
levels are explained here: https://developers.google.com/closure/compiler/docs/compilation_levels
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.
im going to give :whitespace a shot
im thinking its not the script tags and its the compiler.
nodejs
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?
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
im not sure but probably
it doest give me the error in the terminal
the test_call() is undefined
undefined
uncaught reference error
the js compiler at least needs to output the code, or an error. check the settings of the js compiler
the window variable doesnt return any of the functions in my react app, at least not on the top level. its probably nested somewhere
so i got it working
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
I can’t believe how many hours I spent on this.
thanks for all your help, i really wouldnt have been able to figure this out without you!
yeah i already did.
lol it was the last thing i tried before i actually tried the thing that works
what does that do?
this is going to be so awesome. i can finally start writing clojurescript =D
thanks!
oh yeah i’ve done that
now i just have to figure out how to call javascript from clojure (not clojurescript), and i’ll be all set
is migrating from clojurscript to clojure pretty easy?
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
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.
you will have seams... edges... where data needs to be coralled and reformatted form the js world to the cljs world
i can just format to json though, or is there a better way?
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...
but not clojure and javascript?
http://clojure.net and .net do
so you can interop between C# and http://clojure.net
so if i migrate 100% to cljs on the backend, how would i switch over to clj? how much different is clojure from clojurescript?
thats the end goal, but right now i have javasript on the backend
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).
also, how well do you know node. If you are a node gun... maybe you want to leverage that knowledge
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
or i could have the front end talk to the server it needs for the particular data it wants
well if clojure can offer me more because it runs on the jvm, why not?
also, it tends to be the setup most people use. So the path is more well trodden. Less weird issues. Better integration
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.
http://www.luminusweb.net/ there are other options, too. But this works for me.
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
haha*
sweet
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.
so its almost better to just not even use a template then you dont have to worry about upgrading lol
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
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.
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.
well this is confusing lol so many options
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
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
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....
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
just focus on what i need at the time though im guessing is the thing to do
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."
[req]
(content-type
(response (:body req))
"application/json"))
(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?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
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, https://github.com/weavejester/medley/blob/master/src/medley/core.cljc#L91, (into {} (map (fn [[k v]] [k (first v)]) my-map))
would work too
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
@c09mld have you seen this? https://github.com/bhauman/lein-figwheel/wiki/Running-figwheel-in-a-Cursive-Clojure-REPL
@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.
@jarvinenemil have you seen Stu's simple Maven example to call Clojure from Java? https://github.com/stuarthalloway/clojure-from-java
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 ?
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
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?
@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)
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'
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))
@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
it's useful for algorithms that work in terms of successive updates to a single target value
clojure-mode is indenting incorrectly because of calling as->
without the first arg (since is inside a ->
)
oh yeah, that's a definite gotcha