This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2018-10-24
Channels
- # announcements (1)
- # aws (2)
- # beginners (147)
- # boot (19)
- # cider (57)
- # clara (52)
- # cljdoc (18)
- # cljs-dev (14)
- # cljsrn (4)
- # clojure (176)
- # clojure-conj (9)
- # clojure-dev (9)
- # clojure-germany (2)
- # clojure-italy (4)
- # clojure-spec (13)
- # clojure-uk (56)
- # clojurescript (72)
- # code-reviews (11)
- # cursive (17)
- # data-science (1)
- # datomic (52)
- # duct (26)
- # emacs (6)
- # events (9)
- # figwheel (1)
- # figwheel-main (21)
- # fulcro (132)
- # funcool (1)
- # graphql (3)
- # jobs-discuss (42)
- # leiningen (3)
- # luminus (45)
- # mount (10)
- # off-topic (2)
- # re-frame (17)
- # reagent (12)
- # reitit (20)
- # ring-swagger (7)
- # rum (3)
- # shadow-cljs (256)
- # slack-help (15)
- # sql (7)
- # tools-deps (50)
- # uncomplicate (1)
- # yada (9)
(let [winner (promise)] (future (search-google-fn) (deliver winnner :google)) (future (search-bing-fn) (deliver winner :bing)) @winner)
yes, i'm saying parallelism because as i'm studying, it's said that concurrency is more about running in alternating mode, and parallelism is about running together. and i'm seeing futures delays and promises as concurrency mechanisms
thanks @noisesmith that makes sense, because promises can only be delivered once right...
right, and it's a no-op to deliver to one that is already delivered, so it's safe
so, for a lot of concurrent problems we can just combine futures delays and promises :thinking_face:
yeah - my example could deadlock if both futures failed btw
so for real code you might need a timed-out deref or some other failsafe
oh, right
deref takes an optional timeout arg if you use the function form and not the reader macro
it's pretty straightforward to use
`(deref winner 10000 :fail)`
declare simple failure if both take more than 10 secs, in that example
awesome, concurrent programming seems very easy and fun to code with CLJ
one problem, the timeout option to deref doesn't work with promises
I just installed leiningen on majaro/arch, and it does not like me using it as non sudo user. I don't have anything special in my system. Any ideas??
"This could be due to a typo in :dependencies, file system permissions, or network issues."
I bet when you used sudo you made broken perms on .m2
the re-frame template is fine, I was able to use it
what lein version?
ls ~/.m2 -alfg total 12 drwxr-xr-x 74 andy 4096 Oct 23 19:12 repository drwx------ 84 andy 4096 Oct 23 19:04 .. drwxr-xr-x 3 andy 4096 Oct 16 08:22 .
A follow up on 'idiomatic' (seq x)
rather than (not (empty? x))
. The idiomatic seq
pulls a whole sequence - not friendly to lazy.
An example (with the side effects being intentional to show the difference):
(not (empty? (for [i '(1 2)] (do (println "i:" i) i))))
i: 1
true
but
(seq (for [i '(1 2)] (do (println "i:" i) i)))
i: 1
(i: 2
1 2)
Plus, idiomatic (seq [1 2 3])
turns it into a sequence. If all you want is to act if it's not empty, isn't that processing into a sequence a waste?because seq treats empty collections as nil
and nil
is falsey
@peter.kehl seq
is pulling the whole sequence in your example only because it is the top level form at the REPL, so you are asking it to print the entire result, if it can.
It won't do that if you use it in a context where you are not forcing it to evaluate the entire result.
(if (seq (for [i '(1 2)] (do (println "i:" i) i))) :not-empty :empty)
How do I design/organise functional code in a simple system?
Do I put some data structures in separated namespace? Would the core.clj
include all namespaces to use their functions?
Any resource/advice? 🙂
@andy.fingerhut Thank you.
@leandrotk100 First quick suggestion, but then I'm close to out of advice given my mostly hobby use of Clojure -- There is no need to have a file named core.clj
in a project, even though the Leiningen templates often create one. In fact, you may want not to have such a file name, because stack traces often include only the last component of the file name in addition to function names (not the whole file path name), and clojure.core functions show up as in file core.clj
It is useful to try to make as much of your code as you can in pure functions of their arguments, taking immutable data and returning immutable data, and try to keep IO and any mutable data "at the edges", if you can.
@leandrotk100 In IntelliJ / Cursive instead of adding .clj files, you have a menue to add a namespace. IntelliJ will then automatically create the file in the right folder. I like this feature. It makes it more logic to Clojure, namely you only think of namespaces, and not of source-code files. This does not answer your question, I just thought you might want to have a look at this feature.
@andy.fingerhut And how do I know how to separate functions in a different file/namespace?
@leandrotk100 The book "Clojure Applied" has a section with recommendations on this topic, but unfortunately I haven't read it yet. Passing on the info in case it might be of interest. I would bet others with more experience may add their suggestions here later.
A rough example - You want to read in some chunk of data from a database or file, transform it in some way, then push it to another database or file, where the assumption for this example that the 'transform' step can be written as a pure function taking immutable data as args, and returning immutable data. Rather than combining all of that into one function, separate out the 'transform' part into a pure function, and the reading and writing parts into their own functions, then have a combined small function that calls all 3. The 'transform' function is then potentially easier to do example-based or generative tests on.
Good Tip @andy.fingerhut
I’m writing a small function which takes a java process object and a “line handler” function, traces the stdout of the process and calls the line handler for each line of output. Specific problem, but I have a generic question. I would like to use lineseq
for the above if possible as it seems like the highest level abstraction. What closure construct would be most suitable for iterating through a seq and optionally exiting the iteration on certain conditions. I.e. doseq et al are out it seems. Am I reduced to using reduce ; ) or is there a more suitable tool?
Hi all!
I'm trying to split a string into sentences while preserving all punctuation.
Using regular split
removes the matched delimeters.
I thought I could achieve this with a regex group like this, but no 🙂
> (clojure.string/split "goo. boo? foo! no!!" #"(<=[.!?]|[.!?][\\'\"])\s+")
["goo. boo? foo! no!!"]
Can't figure out what am I missing...(clojure.string/split "goo. boo? foo! no!!" #"(?=[.!?]|[.!?][\\'\"])")
["goo" ". boo" "? foo" "! no" "!" "!"]
@rakhim I’d recommend using re-seq
instead of clojure.string/split
, you’ll have more control over what you get back.
I can give you an example unless you’d rather have a hack at it yourself.
I got this so far
> (clojure.core/re-seq #"[a-z,;'\"\\s]+[.?!]" "goo. boo? foo! no!!")
("goo." "boo?" "foo!" "no!")
Thank you, @manutter51!
:thumbsup:
Here is a better version, if anyone is interested
> (clojure.core/re-seq #"[^\.\!\?]*[\.\!\?]+" "Free goo etc. and else. Boo? Foo! no!!")
("Free goo etc." " and else." " Boo?" " Foo!" " no!!")
This actually matches sentences, not just one-word sentences like the prev. version. Now, the next challenge is to ignore common words that end with a period, but don't necessarily signal the end of a sentence (`e.g.`, etc.
, Dr.
and such)I actually tried writing some code to separate sentences in books many years ago, and yeah, it isn't as simple as it sounds at first 🙂
So many things humans with 10 years of education can do that are hard to write down.
human language is insanely hard from a computing point of view. TeX's logic for splitting text into multiple lines with hyphenation is as complex as the AI for a modest game, weighing the "badness" of possible ways to break the lines.
i think emacs solves this by insisting on two spaces after periods to disambiguate it from a period after an abbreviation
There may be some open source NLP (Natural Language Processing) libraries that already cover a lot of these things, but I've not used any of them to give any recommendations. If you are hacking for fun, go for it! If you have a paid job to do with lots of requirements, might want to look into existing code to see if it does what you want.
running checkdoc on elisp code will throw warnings with docstrings without proper punctuation or only a single space after a period
Huh, I just came across a person from France recently who wondered why so much text they were reviewing, written by others, used double spaces. There are whole factions and articles written saying that two spaces is a hold-over from manual/electric typewriters with monospace 'fonts', and single spaces should always always always be used in this modern age.
Emacs being on the double-space side of that argument makes sense 🙂
Even "studies" written: A Google search for the following terms finds a bunch of them, in case you wish to indulge time on the matter: single vs. double spaces at end of a sentence
It's a hobby project, but regexes are no fun 🙂 I'll look into NLP libraries, thanks for a suggestion.
This looks promising https://github.com/dakrone/clojure-opennlp
(pprint (get-sentences "First sentence. Second sentence? Here is another one. And so on and so forth - you get the idea..."))
["First sentence. ", "Second sentence? ", "Here is another one. ",
"And so on and so forth - you get the idea..."]
This is pretty cool, but, from the first glance, seems like it's for a different case.
Is there a nice "utils" library that has all the little things clojure doesn´t, like leftpadding a string, that works in both clojure and clojurescript?
there are several!
well, by which I mean there are several public utils libraries. Most likely none of them include everything you might wish for.
@hiredman format in Clojure/Java is based on JVM format, which has different format strings than the ClojureScript implementation, doesn't it?
I have a function
(defn do-a-thing
[account-number & [{:keys [unpublish?]}]]
(do-stuff account-number unpublish?))
that I want to call from both lein run -m
, and inside my program. It accepts args like: (do-a-thing 100 {:unpublish? true})
. Can I call that from the command line? Maybe stringify it? But then, how do I parse the options? I could do:
(defn do-a-thing
[s]
(apply do-a-thing (parse-opts s))
[account-number & [{:keys [unpublish?]}]]
(do-stuff account-number unpublish?))
but i've never seen anyone else do that. seems nonobvious that the one arity is for calling from the command line.Have you considered looking into CLI libraries for Clojure?
The heavy lifting for parsing command line arguments can be done with libraries like clojure/tools.cli. I presume there is a way to take args and build a map.
yeah i got parse-opts
there; i was referring to tools.cli in that case. i'm thinking about it!
Yeah, actually the public utils libraries I am most familiar with might be specific to Clojure on Java -- I suspect there are some that stress working similarly/same on both Clojure and ClojureScript, but I am not as familiar with which ones those are.
Hello, all! I am a beginner in Clojure, and I have got a bit of a problem with my code. I am trying to write a simple function that will simply generate pairs of adjacent numbers of a collection to check if the collection is sorted. I tried without using eval
, but the code doesn't work (presumably due to laziness). I would rather not use eval
. What would be the best way to approach this without changing the main logic itself? Here is the code for the same:
(ns sorted)
(defn pairs [xs ys]
(partition 2 (interleave xs ys)))
(defn sorted [xs]
(eval (apply #'and (doall (for [pair (pairs xs (rest xs))] (< (first pair) (second pair)))))))
(defn -main []
(let [coll [1, 2, 3, 4, 5]]
(sorted coll)))
It's convention to end predicate names with ?
. Also, <
is polymorphic so you can implement it like so
(defn sorted? [xs] (apply < xs))
Make sure you want <
and not <=
. Depends on whether you want to check for an increasing sequence or a non-decreasing sequence.
If you want to do the pairwise comparison, you can do it more concisely using partition like so:
(defn sorted? [xs] (->> xs (partition 2 1) (every? #(apply < %))))
@mfm The command line is strings only, not Clojure data, so I don't see a way to provide a CLI interface that tries to leave out the parse step. The parse step can be as simple as calling an existing function like clojure.edn/read-string, if you want that syntax for the strings in your CLI
@timmyjose Maybe a better way would be to check if the sequence is monotonic. Only checking two at a time in the collection xn-1 < xn and short circuiting if any pairs fail.
I know some of my code will be re-used in the clojurescript front-end... so I was trying to minimize having to rewrite some stuff later.
@hiredman Yes, that works indeed. Just curious how the original approach could be made to work without eval
(using list comprehensions) without getting bogged down by the lazy seq?
Hello all, beginner to clojurescript, trying out hoplon, How does one get the mouse position on mouse events?
@andy.fingerhut thanks! i was thinking of parse-opts
in tools.cli because that'd handle multiple arguments from the command line, but edn/read-string
would be simple, and less of a dependency. thanks!
@christian.gonzalez Yup.. that's what I thought would work by using and
... no luck though
@mfm it does require your users to appropriate quote the strings, if they have internal spaces, braces, etc. stuff that the shell has its own ideas about.
<=
is used for checking if collections are monotonic so andy.fingerhuts suggestion is probably best
<= does a loop recur on multiple args that does what I suggested
but I was trying to apply
the and
macro, and forcing it with eval
... so avoid this approach entirely?
apply
does not work with macros, only functions
Same for any other function like map
, filter
etc. that takes a function as its arg.
if you wanted to use eval, you cannot just apply and like that, you need to build a form to call eval on
Okay, so getting some garbage value like (clojure.core/let [and__5236__auto__ true] (if and__5236__auto__ (clojure.core/and true) and__5236__auto__))
when using (apply #'and (for [pair (pairs xs (rest xs))] (< (first pair) (second pair))))
is totally expected, right?
macros take forms and return forms
also, they have two invisible args (you can provide nil for each) before the real args
user=> (apply #'and nil nil '(:a :b :c :d))
(clojure.core/let [and__5236__auto__ :a] (if and__5236__auto__ (clojure.core/and :b :c :d) and__5236__auto__))
user=> (pprint *1)
(clojure.core/let
[and__5236__auto__ :a]
(if and__5236__auto__ (clojure.core/and :b :c :d) and__5236__auto__))
nil
except it threw two of your args away