The Clojure code itself will be the same regardless of if using Leiningen or Clojure CLI tools. The difference is is the details of how you configure Clojure projects and even then there is much cross-over.
Hello, could someone explain to me what happens when I do ...
( #(if string?
(clojure.string/join (reverse %))
(reverse %)) [:foo :bar :foo])
I understand what I want is with do
( #(if string?
(do clojure.string/join (reverse %))
(do reverse %)) [:foo :bar :foo])
But I would like to just understand the how first ends up going to the true
branch to produce ":foo:bar:foo"
basically string?
is a function which is always truthy (which is what your if
is evaluating for. in order to invoke it you need to wrap it in ()
which is why (string? %)
behaves like you’d expect (it returns a true of false depending on whether or not %
is a string)
This is straightforward
((partial reverse) [3 2 1])
But why does this produce the same result?
((partial reverse [3 2 1]))
@michelemendel I believe thatt that includes [3 2 1] into reverse to make a new function. So when you call that function it will always execute reverse [3 2 1] - like a function with zero arguments
in the first case, (partial reverse) produces a new function that literally does the same thing as reverse (since you don't add in anymore arguments
So in the second case, the reverse has already been done when it reaches partial?
yeap the function you effectively produce is kinda like
(fn []
reverse [3 2 1])
Yes, because this actually works
(partial 3) ;=> 3
maybe you want this in the first code
(#(if (string? %)
(clojure.string/join (reverse %))
(reverse %)) [:foo :bar :foo])
Not sure when you would use that but is a similar idea to (partial +) which produces the + function again I guess
as for the first version, everything in clojure is true except nil
or false
what's the part that get evaluated as true
there
(if string?
true false) => true
string?
is considered as true
omg
thanks ><
it's called nil-punning
wait i heard that before but could you summarise what that is exactly ?
like that all values other than nil
and false
are true
?
yes, that's what I understand
so this is a case of nil-punning? - > string?
is considered as `true`
I think this to make it possible to combine it.
But yes thanks 😄
This is where some understanding of category theory is useful.
hmmm, i guess edge cases and combining of higher order functions perhaps 😮
on second thoughts, i'm not sure your case string?
can be considered as nil-punning
`
Yes, so in these cases, it look strange taken at face value
your string?
case just shows the truthiness concept in clojure
okay! let me read up on it
do
here executes the expressions inside one-by-one then returns the result of the last expression.
so, (do clojure.string/join (reverse %))
executes clojure.string/join
then executes and return the value from`(reverse %)`
cans someone remind how to force a lazy sequence to be non-lazy. It is really difficult to debug a (for ...)
loop with too many lazy sequences.
in second case, your ((partial reverse [3 2 1]))
becomes
((fn []
([] (reverse [3 2 1]))
([x] (reverse [3 2 1] x))
([x y] (reverse [3 2 1] x y))
([x y z] (reverse [3 2 1] x y z))
([x y z & args] (apply reverse [3 2 1] x y z args))))
there's 0 arg there so, (reverse [3 2 1) executed
doall
I see. This is from the definition of partial, right?
yes, that's from partial
source code
its not clear from the documentation whether doall
returns the sequence.
Hello, how can i set the value of a static field in an abstract java class? i want to set the api key for Stripe: Stripe.apiKey = "…"
`(set! (. Classname-symbol staticFieldName-symbol) expr)` https://clojure.org/reference/java_interop#_alternative_macro_syntax
Is there an equivalent of Common Lisp maplist
http://www.lispworks.com/documentation/HyperSpec/Body/f_mapc_.htm`mapcon` in clojure? I.e., maping functions which iterate over cons cells rather than the contents of cons cells? this is very useful when you need to compute something based on an element but also based on elements you'll see later. E.g. checking whether a list is in order, or removing successive duplicates, or checking the list of vertices of a polygon to detect right turns vs left turns.
Unfortunately the function only make sense for lists, not for generalized sequences.
The reason I need such a function now is I want to scan a list with a given binary predicate to determine whether any two consecutive elements of the sequence satisfy the predicate. E.g., given (1 2 3 4 16 5 6 7)
find two concecutive elements (a,b)
such that b = a^2
, and if so replace (4 16)
with some new merged value computed by a given function.
thank you, it worked 🙏
you can craft such function youself
(defn foo [f xs]
(let [xs' (partition 2 1 xs)]
(map (fn [pair]
(f pair))
xs')))
there is also a builder for stripe’s request with method setApiKey
might be a little bit more idiomatic solution
yes in lisp it is pretty easy to write such special purpose functions. but in Common Lisp these function are as friendly as mapcar (CL version of map
) which take multiple arity functions such as (map f l1 l2 l3 l4)
which expects f
to be 4-ary simply because i've given 4 arglists. BTW this is a cool feature of clojure which is pretty difficult to do in Scala.
For the case in point, I need to remove duplicate elements from a list. but not all duplicates, just the ones of a special form. I.e., duplicate elements x
such that (f x)
is true for some given f
the second case is I need to replace a succession of (a b)
with either a
or b
or leave it as (a b)
depending on another predicate function. This is part of a symbolic algebraic reduction phase.
in CL I'd use this cons cell iterator, and in each case look at the first and second elements of the list. and emmit (in a mapcat
fashion the elements of the resulting list.
I can understand why these functions might not be in clojure, because they are very list specific, they don't apply to other non-list sequences.
but you're right that in lisp you can very often write the function you need as if it were built into the language.
is thrown
supposed to work screwy like this? The compiler claims thrown?
cannot be used within (not ...)
(deftest t-invalid-type
(testing "for invalid type within rte"
(with-compile-env ()
(is (thrown? Exception (canonicalize-pattern '(not (:or String Number)))) "test 0")
(is (thrown? Exception (canonicalize-pattern '(not (or String Number)
(or Long Number)))) "test 1")
(is (thrown? Exception (canonicalize-pattern '(and (:or String Number)
(:or :sigma)))) "test 2")
(is (thrown? Exception (canonicalize-pattern '(or (:and String Number)))) "test 3")
(is (not (thrown? Exception (canonicalize-pattern '(:or :epsilon (:cat Integer (:* Integer))))))
"test 4")
)))
thrown?
is not a “normal” function
it is a form of assert-expr
https://github.com/clojure/clojure/blob/28efe345d5e995dc152a0286fb0be81443a0d9ac/src/clj/clojure/test.clj#L504-L516
and it is trivial to create custom not-thrown?
extension as a method of assert-expr
(defmethod clojure.test/assert-expr 'not-thrown? [msg form]
;; (is (not-thrown? c expr))
;; Asserts that evaluating expr not throws an exception of class c.
(let [klass (second form)
body (nthnext form 2)]
`(try ~@body
(do-report {:type :pass, :message ~msg,
:expected '~form, :actual nil})
(catch ~klass e#
(do-report {:type :fail, :message ~msg,
:expected '~form, :actual e#})
e#))))
didn’t test it thoughIs there a way to use a simply 2-thread model to evaluate an expression, or call a 0-ary function, and return its return value, however, in a second thread, wait some timeout, and print a message that the expression is taking a long time. I.e., if expr1 takes more than 10 seconds to finish, print a message, and when it finally finishes print a second message indicating the total time.... If the expression finishes before the timeout, then the 2nd thread should print nothing, but should be killed, as I intend to launch 1000s of these in succession.
I'm generating this as randomized input to some functions during testing. occasionally some test take a long long long time. I'd like to recognize this and find the kind of input which causes it to never return. I can't really use a simple timer, because if it never finishes, the simple timer method wont really work.
is that the normal way I'm supposed to test whether a certain condition is not thrown?
I suggested some time ago that clojure test needs an is-not
which is like is
but logically reverses the expectation.
ask around, i’m not claiming this to be “normal” way)
thus. (is-not (thrown? Exception....)
and (is-not (my-own-predicate ...))
It could be that I know enough clojure now to implement is-not
and submit it as a patch.
ask core members about it first. unlikely this patch will be accepted
clojure.test tend to be as small and simple as possible. is-not
looks like syntactic sugar for me
can be implemented outside of framework
(defmacro is-not [form]
`(is (not ~form)))
You’re making this too hard. You don’t need to assert not thrown at all (an uncaught throw will fail the test). Either just invoke, or assert the return.
To remove duplicates by predicate you can write something like:
(defn distinct-by
([f]
(fn [rf]
(let [seen (volatile! #{})]
(fn
([] (rf))
([result] (rf result))
([result input]
(let [k (f input)]
(if (contains? @seen k)
result
(do (vswap! seen conj k)
(rf result input)))))))))
([f coll]
(sequence (distinct-by f) coll)))
(distinct-by #(mod % 3) [1 5 3 4 2 6])
Which is just a modified version of distinct
to map over pairs of the original sequence, perhaps a transducer will lend itself well
(transduce
(comp
(partition-all 2)
(map select-a-or-b))
conj
[]
xs)
The CL implementation is very tied to the cons cell abstraction, but Clojure is more generic sequence oriented and has a very large collection of sequence manipulation functions which compose well
(deref (future (expr ,,,)) timout-ms timeout-val)
For example,
(deref (future (Thread/sleep 1000) (println 'finished)) 100 :timouet)
will return after 100 ms and print finished after 1000 msI believe if you have an uncaught exception the test flow will stop.
right?
Yes
If you don’t want that, break it into a separate deftest
there seems to be a piece missing from the testing flow. an is-not test or a not-thrown predicate. yes its not the end of the world if the testing flow fails, just not very elegant.
hmm. not sure how to make this do what I need. I don't want anything printed if it took less than the threshold to run. Maybe I'm thinking about it wrong. But if I tried to do it, I'd have 2 threads. #1 runs the client function #2 sleeps until the timeout If #1 finishes it kills #2, so I don't get 1000s of sleeps in parallel, plugging up the available threads If #2 finishes, then it prints a message, and waits for #1 to finish (if ever), then reports the total time.
how you define “flow”?
(deftest flow
(testing "flow"
(is (do (prn "1") (= 1 1)))
(is (throw (ex-info "exception" {})))
(is (do (prn "2") (= 2 2)))))
like this ^?
if so then in case of unhandled exception it will not stop.would it be possible (from the clojure implementation perspective) to re-engineer the memoize
function so that when the java heap starts filling up, the cache gets flushed. Of course permission to do so would need to be an option in the call to memoize
. When I run huge numbers of randomly generated test cases the java heap fills up on what seems to be simple computation. I suspect it is the fact that several of my functions are memoized.
I think your snippet can be rewritten like this:
(deftest t-invalid-type
(testing "for invalid type within rte"
(with-compile-env ()
(is (thrown? Exception (canonicalize-pattern '(not (:or String Number)))) "test 0")
(is (thrown? Exception (canonicalize-pattern '(not (or String Number) (or Long Number)))) "test 1")
(is (thrown? Exception (canonicalize-pattern '(and (:or String Number) (:or :sigma)))) "test 2")
(is (thrown? Exception (canonicalize-pattern '(or (:and String Number)))) "test 3")
(is (canonicalize-pattern '(:or :epsilon (:cat Integer (:* Integer)))) "test 4"))))
so “test 4” will fail if exception thrownand it will be much more elegant if you add assertion into it (is (= some-data (canonicalize-pattern …
I can recommend read throw this chapter — https://www.braveclojure.com/core-async/
it is technically possible using the weaker java ref types (in fact, the interned keyword cache in Clojure is similar). hard to say whether that's a change we would make in core
the diversity of options is why the core.memoize lib exists
@alexmiller, what's the idea with the core.memoize library. Does it mean I'll have to implement a caching algorithm for my application, or does it mean I can chose from an existing one?
the latter
I'm looking for a critique of my implemenation. It's the basic procedure for a script I'm writing and does a lot of impure/stateful stuff. Would you write it different?
(defn process-oldest-unprocessed [{integration-id :integration/id pattern :integration/file_pattern ftp-info :integration/sftp-info}]
"Find oldest unprocessed file on sftp for integration. Copy it to Minio. Create entry in stage_candidates table."
(let [processed (->> (db/all-candidates integration-id) (map :stage_candidate/file_name))]
(sftp/with-sftp-channel ftp-info
(fn [channel]
(let [sftp-file-info (sftp/oldest-matching-excluding channel pattern processed)]
(minio/create (sftp/get-input-stream channel sftp-file-info))
(db/create-candidate sftp-file-info))))))
@skinner89 just off the top
1) db/create-candidate doesn't take a db argument - are you using some sort of global state for db? make it explicit, you'll thank me later
2) docstring indicates this should be three separate routines, with a fourth to orchestrate together. Is this the orchestration function?
3) what happens when either copy or db create don't work?
4) what does this function return? consider some sort of explicit record of what happened
minor:
put the argslist on the next line
destructuring is verbose, making needless extra names, leads to cognitive overhead. Consider {:integration/keys [id file_pattern sftp-info]}
. Don't worry about the - vs _ idioms. More important to have fewer names.
pretty sure that docstring is in the wrong place too
ah yes ^
(defn name "docstring" [arglist ...] .....
;)
Thanks! Hadn't considered the db arg @ghadi.
To answer 3) I would need to cleanup the minio work if db/create fails.
I've tried looking online, and did a quick search in this forum, but didn't find an answer. I'm trying to find a learning path to proficiency in modern, idiomatic, production Clojure--something that will tell me what I should learn (in what order, too?), so that I can have a solid sense of direction for my learning (I know that might be complex, as I'm guessing the field is huge, and there are a lot of paths---maybe that's why this doesn't exist, though I've seen things like this for Front End dev). I know about Brave Clojure, and a few other online resources that cover the basics of the language, but, naturally, there's so much more. http://Purelyfunctional.tv is great, but there doesn't seem to be any rhyme or reason to what's there. It feels like a big jumble of videos. I find myself getting stuck because I'm lacking direction. Does anyone here have recommendations for a learning path (or can they point me to something they know that already exists)?
Welcome to learning clojure! Unfortunately, I think you're experience is a common one. For my own learning, I found a thing I wanted to build, then figured out how to build it, piece by piece. That got me enough skill to land a job in clojure, and that gave me the support to keep going
For me, I focused on building an API first, while building the site in something i knew (Vue). Most of what I needed was just familiarity with writing functional code and clojure idioms, and you should be able to learn this no matter what thing you're working on
Hope that helps and YMMV. Best of luck! And I've found this community (and this message board specifically) to be quite helpful
How about https://practicalli.github.io/clojure/
two examples
John (who runs Practicalli) has a lot of youtube videos up too on the channel
What kind of projects are you interested in? • games • web servers • web ui • graphics • scripting • data processing • networking • procedural music generation • something else?
@alibris.lumos as Clojure is a general purpose language, there is not a single learning path except for that you make for yourself. Regardless of content used to learn Clojure, the only way you will make sense of things is identifying specific goals to achieve or projects to build. Without this, anyone learning any programming language will most likely end up lost and frustrated. Learning to write good idiomatic code does contribute to writing production code, however, that is just part of the engineering required to write a production quality system (what ever the context of that is). I suggest to anyone learning Clojure (or any general purpose language) to experiment at first and feel comfortable in understanding how to try things out. Getting comfortable using the Clojure REPL will give you a good foundation, along with learning some of the Clojure core functions (http://www.4clojure.com/ is excellent for this). Once you have a goal or a project in mind, you can start asking specific questions in that context and you should feel like you are making progress. If you can, find someone who will mentor you or someone to learn with. Or just ask lots of specific questions here, its what we are here for.
Clojure Applied is a reasonably good book for "modern, idiomatic, production Clojure" (although the author cautions that when they do a next edition, they will place less emphasis on records and keep to plain hash maps a lot more).
Is there an idiom for saving a value in the middle of a thread pipeline during RDD?
(doto tap>)
if you are using something that has tap watchers (such as Reveal or REBL or Portal).
Another option would be (as-> v (def saved-value v))
-- one of the few "good" uses of def
not at the top-level: this would create a global saved-value
containing the value from the pipeline.
I highly recommend https://github.com/vlaaad/reveal/ as an option here. I use it day-in, day-out for all my RDD @skinner89
(and for anyone who wants to try Reveal, there's a #reveal channel if you get stuck or have in-depth questions about it)
This is such a life saver!
planning to add tap-> for this https://clojure.atlassian.net/browse/CLJ-2538
Nice! Thank you
Nice! My vote would be to ignore tap>
failure because if you really want to detect that and do something different, you can always do (doto (-> tap> assert))
or similar...
(since most folks are probably using (doto tap>)
right now, they're ignoring the result/failure anyway)