This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2019-07-15
Channels
- # aleph (9)
- # announcements (6)
- # beginners (42)
- # calva (4)
- # cider (9)
- # clara (2)
- # clj-kondo (1)
- # cljdoc (108)
- # cljs-dev (10)
- # clojure (25)
- # clojure-brasil (1)
- # clojure-chicago (1)
- # clojure-europe (4)
- # clojure-italy (42)
- # clojure-nl (14)
- # clojure-uk (66)
- # clojurebridge (3)
- # clojurescript (23)
- # clojutre (2)
- # community-development (1)
- # cursive (2)
- # datomic (4)
- # figwheel-main (21)
- # fulcro (23)
- # jobs-discuss (1)
- # kaocha (1)
- # off-topic (10)
- # pedestal (4)
- # reitit (2)
- # shadow-cljs (41)
- # spacemacs (7)
- # sql (20)
- # xtdb (3)
Sorry if this is a silly question, but I'm really irritated by this.
Why doesn't this overflow the stack?
(reduce (fn [a b] (inc a)) 0 (partition 1 (range 10000000)))
I have been noticing that several essential seq-functions are implemented as recursive functions returning lazy-seqs. This seemed weird to me, because I assumed they'd overflow the stack - but they don't.
So I figure there must be something going on with how lazy-seqs are implemented, or what their semantics actually are, but I really don't get it.
lazy-seq is not a recursive function, it is a macro
No, it’s not
lazy-seq is a macro expansion - it does not happen in the runtime call stack
macro expansion happens at compile time, not at runtime
Okay I understand that. One step back though,
artition features this line (cons p (partition n step pad (nthrest s step)))
- why is this not recursive?
because it's in the body of lazy-seq
a simpler example to look at would be and
or or
Is there a way to do stdio interactively with ProcessBuilder and http://clojure.java.io/reader and http://clojure.java.io/writer with a subprocess? Or what is the correct way of doing this?
did you look at https://clojure.github.io/clojure/#clojure.java.shell ?
specifically clojure.java.shell/sh ?
(let [pbuilder (ProcessBuilder. (into-array String ["..."]))
process (.start pbuilder)]
(with-open [reader ( (.getInputStream process))
writer ( (.getOutputStream process))]
(let [line1 (.readLine ^java.io.BufferedReader reader)]
(println line1)
(.write ^java.io.BufferedWriter writer "test\n")
(let [line2 (.readLine ^java.io.BufferedReader reader)]
(println line2)))))
or for a lib with a lot more functionality, https://github.com/Raynes/conch
@alexmiller ah thanks, the liberary seems to solve the buffering issues
yeah, properly buffering and draining the process streams is tedious
also, fyi the http://clojure.java.io/reader and http://clojure.java.io/writer can help with making buffered readers and writers
@finn.volkel Conch is part of clj-commons now, which is where maintenance and new releases happen https://github.com/clj-commons/conch /cc @alexmiller
sorry, thx!
Hi guys! I'm running some tests though cider-test-run-* and I'm having a real hard time finding out if outputs I log in log/info
are output anywhere during these tests
well then, looks like it outputs in the linked cider REPL. No clue how I missed that. Nothing like coming back from the weekend to solve your problems 🙂
In C++ we can access maps/hashmaps with any kind of value (as long as there is a comparison function, or a hashing function), but in Clojure we can just interact with them with keywords, how can I achieve the same things if I can't use any kind of data? what is the Clojure-way of solving this?
Please don't use mutable objects as keys - it makes bad things happen. But clojure won't stop you.
in fact there are built in functions in clojure.core that would be nearly useless if we didn't allow arbitrary keys
user=> (group-by count ["hello" "goodbye" "OK" "yes" "no" "stop" "start"])
{5 ["hello" "start"], 7 ["goodbye"], 2 ["OK" "no"], 3 ["yes"], 4 ["stop"]}
Oh, great, from what I have read it seemed that you weren't supposed to use nothing more than keywords as keys. So as long as I use immutable objects as keys there should be no problem, right?
right - strings, numbers, immutable data structures, symbols - all work great as keys
keywords are common for implementing named fields, but you can mix in whatever makes sense for your domain
eg. I'd rather have "json key"
as a key than attempt to turn that into a keyword
You can use maps containing maps containing maps containing sets of vectors as a key of a map, if you feel so inclined.
I can almost picture a use case for that
sometimes can be useful to make composite keys [primary-id secondary-id] with vectors, though rarely use anything but keywords or strings as keys
If you don't care if the map is sorted or not, then no comparison function is needed, the built-in clojure.core/hash function is used and works fine. If you want sorting, then the built-in clojure.core/compare function doesn't do anything useful for you to compare sets or maps to other things, and you may or may not want its default behavior for comparing sequential things to each other.
with group-by I end up using all sorts of keys
also, if you use memoize
, you are implicitly using a map from List to Object
There are guide articles on writing custom comparator functions: https://clojure.org/guides/comparators and on a few corner cases of equality/hash for non-sorted sets you should avoid: https://clojure.org/guides/equality
in the C++ case you probably have to implement a comparator / hash, with Clojure you rarely have to do this on your own (I haven't had to at all)