I think I found the answer https://gist.github.com/swannodette/4fc9ccc13f62c66456daf19c47692799:
Simply add a new compiler option :infer-externs true to your compiler config. Now when you build your project you will get a new file in your :output-dir named inferred_externs.js. When you do an advanced build, this externs file will be used.
So, your inferred_externs
should be in the :output-dir
of your advanced build. Therefore, you might need to check it in to source controlIs the only reason to using (testing...)
in clojure.test for self-documentation? Any reason to use them over just splitting tests into individual (deftest..)
blocks?
you can define deftest
scoped let
blocks, which can be very useful. which is to say the relation between them is block contextual.
tests are still just functions and you can compose them as such π
Hm, I'm not sure I know what you mean. Sure I could do:
(deftest my-test
(let [some-var ...]))
but I could do that same thing with testing
:
(testing "something something"
(let [some var ...]))
I guess I'm asking, what's the point of the testing
macro at all when there is deftest
?https://clojuredocs.org/clojure.test/testing is what I'm referring to, just to make sure we're on the same page π
(t/deftest foo (t/testing "this could describe what you want" (t/is (= 1 2))))
(foo)
FAIL in (foo) (form-init14706425140162863748.clj:16)
this could describe what you want
expected: 1
actual: 2
diff: - 1
+ 2
it can add context and descriptions in error messages, in addition to serving as documentation in the test definitionsI find testing
very useful when I have a deftest
for a function and want to logically group assertions based on what scenarios they are checking.
See, for example, this test for next.jdbc
's get-connection
protocol implemented on various data types https://github.com/seancorfield/next-jdbc/blob/develop/test/next/jdbc/connection_test.clj#L88
^ @mail985 is that a useful example?
how to possible export the full clojurescript project into a single *.js file? (I saw somewhere on github.. but I donβt know where.. could you help me?)
What tool are you using to build your cljs?
When you build the js bundle for your prod env all the cljs goes into a js file
hi, I have a checkbox in a form and I was wondering whether there was a nicer syntax for the submit action here, please:
[:input {:type :checkbox
:checked checked
:onchange "this.form.submit()"}]
If you have a button you donβt need to use this.form.submit
fn
@baptiste-from-paris thank you. I had a button before. But this is a checklist, so I need a checkbox π
if you have a button you donβt need any js
, just put a required
attribute on the checkbox and the user has to choose at least one checkbox
@baptiste-from-paris I need to send a post request to the backend every time the user changes the state of the checkbox. itβs a todo list. I am actually not submitting a whole form. itβs a βformβ that includes just two elements: one input type=hidden + the checkbox (previously a button type=submit).
I mean replacing "this.form.submit()"
with just :submit
or something like that�
Check out shadow-cljs. There is a #shadow-cljs channel here too
Hi quick question, can I reference a function in another package without requiring it? Basically I just want to hold references to functions, but would love to avoid requiring it, I can reference using full package.
Depending on your use-case, you might just use quoted vars (something like #'reagent.core/ratom
) and then just make sure that the symbol resolves properly before using it
@roguas why do you want to avoid requiring it, though?
hi! When do you use maps and when do you use records?
trying to refactor some code that was dynmically loading symbols, so its a step in direction towards require
I think records are mostly handy when it comes to protocols. So that you can have a generic way of processing different types of records.
Accessing fields in records is faster, too, so they are useful when performance is critical
@roguas @mitchell_clojure ok thanks! Do you also use it to increase readability of the code? As it adds a bit more structure than maps. Or do you think maps with spec provides the same clarity?
I think the general approach is to just use maps with spec. The idea behind this is that the shape of your map is "self-documenting" in a sense. For example {:name "Mitch" :employee-number "1020.12"}
is descriptive enough, without going through all of the OOP ceremony of creating decorators (when we want to accrue data) or interfaces (when we only want to act on a subset of the keys).
Ok. Great. Then I think we all have the same understanding. Protocols for polymorphism on type, plain maps for data and maps with spec for expressing composability and other rules when needed.
I'd like to make a function that increases each element of a vector by its position in the vector, with position starting at 1. For instance [0 1 2] becomes [1 3 5], or [3 4 5] becomes [4 6 8]. Here's my current attempt:
(map + [3 4 5] (range 1 (inc (count a))))
I was wondering if there's a more idiomatic way of doing this? Thanks!
(map-indexed #(+ (inc %1) %2) [3 4 5])
Thanks @delaguardo! I didn't know about map-indexed. Why do we need a second argument %2
and where does its values come from?
map-indexed expect first argument to be a function of two arguments where first β position of element in collection, second β element
Ah! I understand now! Thanks again!
in anonymous function written via #(
dispatch macro you can refer to first argument as %
or %1
, second β %2
etc.
there is also %&
to make a function of variable amount of arguments
I didn't know about %&! That'll be very helpful!
I have two local clojure projects A and B (using lein). What is the best way to call functions in B from A?
(map-indexed (partial + 1) [3 4 5])
π
Thanks! Appreciate your feedback! π
^ even better) cool)
Woah!
The best way depends on your goals and desires. One way is to run the command lein install
in the root directory of project B, which if successful will create a JAR file for selected files of project B and write it into your $HOME/.m2 directory. Then add that artifact as a dependency in project A's project.clj file, and then require project B's namespace(s) containing the functions you want to call into project A's code.
If you later change code in project B, that will have no effect on the contents of that JAR file, unless you do lein install
again to create another JAR file.
What is happening there with partial? I see that it takes a function +
and a variable amount of args.
If you want to you "live" changes in B, in A, what I've done before is add B as a dep of A, and then (from A's root):
mkdir checkouts
ln -s /path/to/B checkouts/
it creates a function that calls +
with args 1
and any other args provided to it
let me give you a fishing rod ) https://clojuredocs.org/clojure.core/partial
What are the args in this case? first arg is 1, second arg is index position? , third arg is [3 4 5]?
third is an element from that position
the 3rd arg is the value at that position, yes
oh! I have it backwards! Second arg is [3, 4, 5], and third arg is value at that position?
no
see the map-indexed
docs perhaps?
ok, thanks @jason358, I'll read it again!
my example can be rewritten as follows:
user=> (def f (partial + 1))
#'user/f
user=> (map-indexed f [3 4 5])
(4 6 8)
user=>
so, (partial + 1)
returns a function, map-indexed
then calls that function for each vector element
Ahh! I see now, that's why @delaguardo said "third is an element from that position"
Thank you both so much! π I learned a lot just now
π»
clojure tools deps lets you use local paths in your dependency definitions https://clojure.org/guides/deps_and_cli#_using_local_libraries
so you can reference other local projects via their path in your filesystem
this is awesome - good stuff and great community
does a struct-map
have an ordering?
Hey all, I'm trying to get the local timezone on my server. I'm running centos in docker and when i run date from bash i get Wed Sep 16 10:41:44 MDT 2020 but when I try to get my timezone in the repl it looks like this.
(ZoneId/systemDefault)
=> #object[java.time.ZoneRegion 0x45024d57 "UTC"]
I'm not sure how to narrow down what the cause might be. eg docker, repl, java, centos, clojure
definitely not clojure
but if I may make a suggestion, go in the other direction, get everything on your server in utc
that function will do this https://docs.oracle.com/en/java/javase/13/docs/api/java.base/java/util/TimeZone.html#getDefault()
> Gets the default TimeZone of the Java virtual machine. If the cached default TimeZone is available, its clone is returned. Otherwise, the method takes the following steps to determine the default time zone.
Use the user.timezone property value as the default time zone ID if it's available.
Detect the platform time zone ID. The source of the platform time zone and ID mapping may vary with implementation.
Use GMT as the last resort if the given or detected time zone ID is unknown.
(System/getProperty "user.timezone")
-> "UTC" for me
very likely docker
okay, thanks guys. @dpsutton mine also returns "UTC" so I think that gives me somewhere to start looking. Thanks!
https://serverfault.com/questions/683605/docker-container-time-timezone-will-not-reflect-changes
definitely docker
yeah. i'm confused. my system timezone is definitely not UTC but running a repl locally is giving me utc
but consider running in utc, it is good and common practice
are you on a mac?
no, i'm on windows
interesting, but running just bare clj
i get America/Chicago. yes on a mac
i apologize. i ran that in a project's repl that explicitly sets {:jvm-opts ["-Duser.timezone=UTC"]}
. otherwise it is picking it up correctly
http://yellerapp.com/posts/2015-01-12-the-worst-server-setup-you-can-make.html
haha maybe that's what i'm doing
yeah, that's it LOL
thanks!
but as @hiredman mentioned, that's probably actually a good thing
is there another way to get the system's timezone? I need to do reporting and it makes more sense for the end user if it show's the servers timezone
I usually operate in UTC and that's fine but in this instance I need the systems timezone
(Timezone/getDefault)
its common for the server to do everything in UTC and let the client format those times into local timezone
How do i initialize a sequence by another sequence. So kinda like seq1 = seq2
this normally isn't necessary. can you write in pseudocode what you are trying to do?
and the reason this isn't usually necessary is because the sequence you are using is probably immutable.
So what im trying to do is remove "not" in an element, So the user has to enter '(not (not x)) for example, and my function needs to remove both of the "not". So I want it to remove the first not first so then it will be 'not 1', then it will remove the last not in that element, but i have to update my expr after removing the first "not"
(defn remoove-nots
[expr]
(loop [x 1]
(when (>= x 0)
(if (= fourth-test (first expr))
(expr (nth expr 1)) ;;HERE i want to update expr
)
(recur (- x 1))
)
)
)
can't quite follow what's going on here but just use expr
wherever you want. you haven't changed it.
I want to chagne it tho
you want to change it twice then? sounds like you want to change the result of your change?
So instead of holding '(not(not x)), i want it to hold '(not x) after goinmg through once
yeah i wanna change it twice
oh, you probably want to add that to your loop and recur. (loop [e expr x 1] ... (recur (rest e) (inc x)))
something like that
what does (rest e) do?
@ntrut Returns the rest of the sequence that is in e
. I think in your case you want (second e)
instead to turn (not (not x))
into just (not x)
?
Yeah sorry. That was just an example function that returns a βmodifiedβ version of expr (I called it e because shadowing can get confusing)
Yeah i want to turn (not(not x) into (not x)
but i cant figure out how to update expr in my case
clojure data structures are immutable
you don't make changes to data
you return new instances of transformed data
aaaa i see
I recommend you maybe read a few introductory articles/guides on clojure, it's probably a much different paradigm than what you're used to and it will be really hard to hack your way through it in the dark
So i need to create a seperate function that returns a new instance of my transformed data and have that loop twice
I have read a few things but its different once i gotta start coding projects haha
If you are looking for a kind of map with ordering guarantees on the key/value pairs, there are several linked from the Clojure cheatsheet in the "Maps" section: https://clojure.org/api/cheatsheet
I do not know whether a struct-map
has any ordering guarantees.
I don't know if struct-map
's are considered deprecated, but typically record
or plain maps are much more commonly used.
thanks for the insights
invoking sorted?
suggests that it doesnβt
sorted?
might only return true for a few sorted collection types built into Clojure. Third party ones, which several of the ones linked from the Cheatsheet are, I have no idea what they return when passed to sorted?
@andy.fingerhut @clojurians-slack100 @marshall thank you very much. I will check out these variants. :)
I wonder if you memoize a function foo of 3 arguments, and then use it in a map expression, mapping (partial foo first-fixed-arg initial-but-changing-second-arg)
onto a collection, will your desire for memoization survive the use of partial
?
It seems like it should to me. If foo
is memoized, (partial foo ...)
is creating another function that calls foo
, which is still memoized.
by which I mean, if foo
is memoized, it should not become unmemoized by having other functions call it, and (partial foo ...)
is just another function that calls foo
. (partial foo ...)
does not cause any changes in foo
's behavior.
In a small test scenario, it should be straightforward to verify this by having foo
do println
or some other kind of debug output, to see when it is being called versus not.
@fappy in case it's not clear: partial
doesn't immediately call foo, so nothing is immediately memoized. Only when the function returned by partial
is called, only then foo is called (and that call is memoized)