This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2018-02-01
Channels
- # beginners (117)
- # boot (8)
- # cider (22)
- # clara (3)
- # clojure (79)
- # clojure-italy (3)
- # clojure-spec (34)
- # clojure-uk (34)
- # clojurescript (74)
- # cursive (7)
- # datascript (5)
- # datomic (28)
- # defnpodcast (1)
- # dirac (9)
- # docker (25)
- # duct (1)
- # emacs (14)
- # fulcro (67)
- # graphql (1)
- # hoplon (15)
- # jobs (4)
- # juxt (6)
- # off-topic (76)
- # parinfer (3)
- # re-frame (25)
- # reagent (4)
- # rum (6)
- # shadow-cljs (1)
- # spacemacs (30)
- # sql (15)
- # unrepl (36)
- # yada (1)
hello all, does anyone know of a simple gist that could exemplify one of the methods to keep the main thread running cited here? https://github.com/stuartsierra/component#entry-points-in-production
I’ve recently done this: https://gist.github.com/dball/21eaa1f003c03217bdad83c03571669b
We do something similar, but the exit promise is injected into the component system itself. This lets us provide an HTTP endpoint on the service to ask for a graceful shutdown.
Yup, we also put an exit promise in the component, and have -main
wait on it, so we can shut things down gracefully (although we don't currently have a use case for that).
i'm trying to find common or repeated subsections among lists
for example, find (1, 2) given the lists (1,2,3) and (1,2)
i can think of a nested imperative way
for m in l1:
for n in l2:
if n == m:
# continue checking consecutive elements along both lists
is there a declarative way?
can anyone point me in the right direction?
@michael740 What if the input were the two lists (5, 7, 1, 2, 3, 4, 5) and (9, 11, 1, 2, 9, 1, 2, 3, 6). Should it return (1, 2, 3), because it is the longest common subsequence, even though it doesn't start at the beginning of the lists?
And should the common sections be consecutive elements?
yes, and yes
I remember doing this in APL years ago -- it was easy there 🙂
The algorithm was something like build a grid of list A elements equal to list B elements, then rotate each row in the grid by its index, then reduce down the grid to get the (sub) sequences of matching elements... then sort by length (in this case)
So for "equality", you'd want to return the element if equal else nil
. so for the example above your grid would be
\ 5 7 1 2 3 4 5
9 . . . . . . .
11 . . . . . . .
1 . . 1 . . . .
2 . . . 2 . . .
9 . . . . . . .
1 . . 1 . . . .
2 . . . 2 . . .
3 . . . . 3 . .
6 . . . . . . .
and when you rotate the rows, the sequences will line up.The reduce "down" the rotated grid would by (partition-by nil? ...)
and then (sort-by count ...)
and (last ...)
wow, that's really sophisticated
I think you can (apply map vector ...)
to the rotated rows to get columns... so that would be the step between the rotate and the column reduction.
And you can rotate the grid by using (take n (drop i (cycle row)))
where n
is the length of all the rows -- 7 in the case above -- and i
in the index in a map-indexed
call...
(mostly doing this off the top of my head... I should pull up an editor and actually write some code)
@seancorfield, thank you. i'll puzzle over this tomorrow, after some sleep
this really is a lot more sophisticated than I would have expected
Yeah, here's a REPL session showing what I'm thinking...
boot.user=> (defn rotate [i coll] (take (count coll) (drop i (cycle coll))))
#'boot.user/rotate
boot.user=> (for [x [5 7 1 2 3 4 5]] (for [y [9 11 1 2 9 1 2 3 6]] (when (= x y) x)))
((nil nil nil nil nil nil nil nil nil) (nil nil nil nil nil nil nil nil nil) (nil nil 1 nil nil 1 nil nil nil) (nil nil nil 2 nil nil 2 nil nil) (nil nil nil nil nil nil nil 3 nil) (nil nil nil nil nil nil nil nil nil) (nil nil nil nil nil nil nil nil nil))
boot.user=> (map-indexed rotate *1)
((nil nil nil nil nil nil nil nil nil) (nil nil nil nil nil nil nil nil nil) (1 nil nil 1 nil nil nil nil nil) (2 nil nil 2 nil nil nil nil nil) (nil nil nil 3 nil nil nil nil nil) (nil nil nil nil nil nil nil nil nil) (nil nil nil nil nil nil nil nil nil))
boot.user=> (apply map vector *1)
([nil nil 1 2 nil nil nil] [nil nil nil nil nil nil nil] [nil nil nil nil nil nil nil] [nil nil 1 2 3 nil nil] [nil nil nil nil nil nil nil] [nil nil nil nil nil nil nil] [nil nil nil nil nil nil nil] [nil nil nil nil nil nil nil] [nil nil nil nil nil nil nil])
boot.user=> (map (partial partition-by nil?) *1)
(((nil nil) (1 2) (nil nil nil)) ((nil nil nil nil nil nil nil)) ((nil nil nil nil nil nil nil)) ((nil nil) (1 2 3) (nil nil)) ((nil nil nil nil nil nil nil)) ((nil nil nil nil nil nil nil)) ((nil nil nil nil nil nil nil)) ((nil nil nil nil nil nil nil)) ((nil nil nil nil nil nil nil)))
boot.user=> (map (partial filter (partial every? some?)) *1)
(((1 2)) () () ((1 2 3)) () () () () ())
boot.user=> (mapcat (partial filter (partial every? some?)) *2)
((1 2) (1 2 3))
boot.user=> (sort-by count *1)
((1 2) (1 2 3))
boot.user=> (last *1)
(1 2 3)
boot.user=>
I'm off to bed too @michael740 -- my beer's all gone 🙂 Let me know tomorrow what you think!
:thumbsup:
why does (apply = true '(true true))
work to ensure that all elements of the list are true
?
I thought the apply would effectively be (= true '(true true))
, which isn't true
With that arity, apply
calls list*
: (list* = true '(true true)) ;;=> (#object[clojure.core$_EQ_ 0x601daba4 "clojure.core$_EQ_@601daba4"] true true true)
apply will always apply the last argument as a list, and keep the other arguments
I see, so it is actually (= true true true)
, which is true
(apply + 1 1 1 [1 1 1])
=> (+ 1 1 1 1 1 1)
thanks!
Hi there, I am trying to use environment-variables in clojurescript. I am using luminus with cprop and need the url for the requests to change in dev and prod. How do you do that?
I would probably just store the environment variables in a global object using https://github.com/arohner/scriptjure
you simply output them in your index.html
alternatively, if you don't need this to be dynamic, use goog defines in cljsbuild definition
for example you could have different :closure-defines
in the dev cljsbuild and the prod one, or use System/getenv
to fetch the values from the environment
Any suggestions on where a noob can start WRT a template/library for making a desktop UI - looking at Gonzih's cljs-electron ATM ?
i started with descjop, didn't get too far
still working on it
@ackerleytng I see that descjop hasn't seen a commit in about a year IIRC - the dev must have moved on or is too busy now.
hey guys, is bootstrap the right decision? anyone prefers something else? I dislike loading 300kb with jquery and fontawesome? I thought actually that cljs only takes the required parts but my luminus-app loads all of it. Any suggestions?
I mean, what I thought is that the google-closure-compiler only takes the necessary parts of the js-files and leaves the other stuff out? but this is not the case right?
I use the bootstrap css files but not the js stuff. That's partly because I'm using re-frame, and it's easier for me to let cljs handle all the actions.
hi, https://clojure.org/guides/deps_and_cli about this, we won’t need lein or boot?
i'm trying to write a nested (loop (recur
but having trouble passing some return value from inner loop to outer loop
bronsa, that's ok, as far as i can tell. i'll wait for the inner loop to finish, move to next iteration of outer loop
it's basically (for [x (range 3) y (range 5)] (+ x y))
but i need more fine grained control over which values of x and y i recur with
let, that does it
remember that in clojure everything has is an expression, there’s no statements in clojure
is it idiomatic to put a complex expression in the let bindings like that?
(loop [x 0
outer-acc '()]
(if (> 5 x)
(let [inner-ret
(loop [y 0
inner-acc '()]
(if (> 3 y)
(recur (inc y) (cons (vector x y) inner-acc))
inner-acc))]
(recur (inc x) (concat inner-ret outer-acc)))
outer-acc))
i'm going to have more complex logic over what to pass to recur
eventually
i'd prefer to use for
or map/reduce
if possible, but i don't know how yet.
This produces the same output
(->> (range 5)
(mapcat #(map vector (repeat %) (range 3)))
(reverse))
that makes sense.
but i'm looking for a way to have more dynamic control over the elements in both the inner and the outer loop, as i iterate
the example i originally gave doesn't really express that, unfortunately...
i want to jump forward n iterations in the outer loop depending on the result of some inner expression with x and y
imperatively, this is dead simple
def compare_lists(l1, l2):
out = []
inner_list, outer_list = sorted([l1, l2], key=len)
i = 0
while i < len(outer_list) - 1:
j = 0
while j < len(inner_list) - 1:
if outer_list[i] == inner_list[j]:
shared_sequence = find_shared_sequence(outer_list[i:],
inner_list[j:])
if len(shared_sequence) >= MIN_PHRASE_LENGTH:
i += len(shared_sequence)
out.append(shared_sequence)
j += 1
i += 1
return out
actually, you were saying i can't recur to an outer loop... maybe that's what this is trying to do
this is possible by inverting the logic - instead of passing the args to the outer loop, you return a collection and the outer loop can then construct a recur call. Or, you can use trampoline and letfn, so that each "loop" becomes a function call that returns an anonymous function that invokes the apropriate body (inner or outer), or the final value
wow, ok. thank you for the response
at what point would you say to yourself, gosh, the imperative code i'm now trying to express functionally/declaratively is simple enough and maybe i'm not gaining much expressiveness when i have to go to such lengths?
i suppose that varies person to person
it really does improve things to use basic collection ops when traversing a collection (for example)
usually my first step is to consider whether the imperative thing I think I want to do can be expressed via a built in traversal with a higher order function
afaik you can't do destructuring in a if-let
well, you can but it's not what you expect
@yvendruscolo if-let
uses the right hand side to determine the success of the test, not the left-side binding
i run into this all the time - (map fn collection)
throws arityException because fn takes 2+ args and each element in collection is another collection
solution is to use apply, i think?
@michael740 sounds like you want (partial apply fn)
in this case
if you want each item in the coll to be an arg that is
(map #(* %1 %2) (list [1 2] [3 4]))
(map (apply fn) coll)
?
yeah , change that to (partial apply *)
or the equivalent #(apply + %)
(apply fn) will error because apply needs a collection
this is horrible
should i not be in this position in the first place?
i have a list of arg-collections i want to feed into a function, one by one
this seems too convoluted
but, it works!
maybe i should transform my collection of args [[a1 a2] [b1 b2]] into [[a1 b1] [a2 b2]] and then map over that with implicit zipping
did you try the functions I suggested? they work
it worked great
oh, wait, with args like that use (apply map * coll)
err...
right.
@michael740 you might notice one is the flipped version of the other
my collection is currently in the second form
:thumbsup: