beginners

Getting started with Clojure/ClojureScript? Welcome! Also try: https://ask.clojure.org. Check out resources at https://gist.github.com/yogthos/be323be0361c589570a6da4ccc85f58f.
2021-05-22T00:05:50.206900Z

Hash maps are great for carrying around named information, so that seems reasonable to me.

Scott Starkey 2021-05-22T13:14:43.216500Z

I'm playing around with the "orc names" code from the Brave & True book: https://www.braveclojure.com/zombie-metaphysics/ but instead of 3000-length names, let's have 10-letter names and instead of a few thousand names, I'd have billions. Can I do that with a lazy sequence?

(defn random-string
  "Returns a random string of specified length"
  [length]
  (apply str (take length (repeatedly #(rand-nth letters)))))
  
(defn random-string-list
  [list-length string-length]
  (doall (take list-length (repeatedly (partial random-string string-length)))))

(def orc-names (lazy-seq (random-string-list 10 60000000000)))
It was my understanding that the whole idea of a lazy-seq was it only processed what I need. So, (in my mind) I should be able to get the (first orc-names) without computing the whole sequence, right? But when I do that, I'm getting a java.lang.OutOfMemoryError (Java heap space). Am I missing something about the nature of a lazy-seq?

2021-05-24T16:25:18.322Z

just a small thing - take is redundant on repeatedly - you can replace (take n (repeatedly f)) with (repeatedly n f)

2021-05-24T16:28:09.322200Z

with those changes:

(defn random-string-list
  [list-length string-length]
  (repeatedly list-length
              (fn []
                (apply str (repeatedly string-length
                                       #(rand-nth letters))))))

NoahTheDuke 2021-05-22T14:59:44.218300Z

You have a doall, which realizes the whole list

lassemaatta 2021-05-22T15:14:16.219600Z

Also, I think the arguments are in the wrong order (list len & string len)

Scott Starkey 2021-05-22T15:55:06.220100Z

ahh, yes. Thanks.

Ivan Koz 2021-05-22T16:07:40.221400Z

@yekrats take in random-string-list already returns lazy-seq, second call in def orc-names is redundant

Erik B Good 2021-05-22T16:28:37.222500Z

Hello, I was wondering if there was any way of differentiating these two expressions ? (= (first [nil]) (second [1]))

dpsutton 2021-05-22T16:38:24.223200Z

(nth [nil] 1 ::not-found). will return your value for value not present versus the value there

Ivan Koz 2021-05-22T16:44:17.224Z

@dpsutton aren't you off by one in nth?

dpsutton 2021-05-22T16:44:59.225100Z

The question was how to distinguish nil from a collection that didn’t have an element there versus one that had an element there but the value was nil

dpsutton 2021-05-22T16:45:46.226100Z

So I combined both into that. Changing to 0 will return the nil in the collection. Asking for the next element will return the sentinel value

Ivan Koz 2021-05-22T16:46:11.226300Z

ty

Juλian (he/him) 2021-05-22T17:21:11.228900Z

is it preferred to use {:foo/bar some-val :foo/baz some-other-val} or #:foo{:bar some-val :baz some-other-val} - putting namespace in front of each keyword of a map or putting namespace in front of map when all keywords of a map use same namespace? which is more readable/understandable?

dpsutton 2021-05-22T17:43:17.229300Z

totally personal opinion. do what looks nicer to you or what your team has settled on

Juλian (he/him) 2021-05-22T17:52:33.230600Z

I think I'll put the namespace in front of each keyword, since it's more explicit and I can't confuse myself when destructuring or using get/assoc/etc...

dpsutton 2021-05-22T17:55:16.231200Z

you can read (doc *print-namespace-maps*) and (set! *print-namespace-maps* true|false) to adjust how the repl's printer prints maps as well

Juλian (he/him) 2021-05-22T17:56:33.232Z

thanks! it even adjusts the output of pr-str 🙂

Michael Lan 2021-05-22T18:12:09.233Z

I am confused as to what the idiomatic way of working with date and times is. I have a long representing milliseconds as a Unix timestamp and I want to get a nicely formatted date.

dpsutton 2021-05-22T18:12:45.233400Z

Use interop with Java time

Michael Lan 2021-05-22T18:13:27.233800Z

would that be java.time or java.util.Date?

dpsutton 2021-05-22T18:13:37.234100Z

Java time

dpsutton 2021-05-22T18:16:01.235200Z

<https://docs.oracle.com/javase/8/docs/api/java/time/package-summary.html> Definitely worth the time to read these javadocs for 15 minutes. Stay with interop only (no wrapper libs) while you learn the basic types and ways to manipulate them. Once comfortable, feel free to use a wrapper if you like but understanding the core concepts of the package will benefit you immensely

Michael Lan 2021-05-22T18:18:53.235400Z

thank you for the advice

gibi 2021-05-22T19:10:13.235700Z

hi, I'm a newbie and trying to use ring coercion to transform the type of a path parameter to int. I've written this code https://pastebin.com/J7LGiqgs following an example from https://cljdoc.org/d/metosin/reitit-ring/0.2.13/doc/ring/pluggable-coercion#full-example but I still can't see the value as int.

gibi 2021-05-22T19:11:37.236100Z

Juλian (he/him) 2021-05-22T19:28:15.236300Z

I think you got the handler function wrong. Following the docs, it should look like this:

:handler (fn [{:keys [parameters]}]
           (let [id (-&gt; parameters :path :id)]
             {:status 200 ... etc ...

Juλian (he/him) 2021-05-22T19:28:38.236500Z

btw, your link is for the docs of a relatively old version

indy 2021-05-22T19:36:37.243900Z

Hello, why do some operations that are mostly meant to be applied on lists take the list as the last argument (e.g. cons, take, drop..) while most other operations take a collection as the first argument (e.g. conj, nthnext, select-keys, subvec..)?

indy 2021-05-23T07:19:00.254900Z

Thanks Sean and Rakyi, I read Rich’s explanation and couldn’t quite follow the train of thought. How does “sequences being read from left and being fed from right” along with the "sequence functions like map, filter and having variadic args" influence the choice of having the sequence as the last arg?

indy 2021-05-23T08:17:50.255900Z

Particularly why does “sequences being read from left and being fed from right” influence (map f sequence) , (filter pred sequence) not being (map sequence f) , (filter sequence pred). We could still chain them the same way we do it for other collections (-&gt; sequence (map f) (filter f)) .

indy 2021-05-23T08:22:07.256100Z

Oh okay maybe it is this bit "partial allows for direct parameterization as above" that majorly affected this decision. But I rarely do something like this ((partial map inc) '(1 2)). Can't think of many sequence functions that have more than one arg before the source.

seancorfield 2021-05-23T16:36:17.272800Z

@kslvsunil A lot of those sequence functions have transducer-producing arities: (map f), (filter pred) etc.

seancorfield 2021-05-23T16:37:10.273Z

As you get more familiar with Clojure, this argument ordering will start to make more sense and you’ll come to understand what Rich means.

indy 2021-05-23T16:43:20.274900Z

Okay Sean. But transducers were introduced much later. Will probably have to reread the motive a few times.

seancorfield 2021-05-23T16:45:49.275100Z

Those transducer arities were only possible because of the argument ordering conventions.

indy 2021-05-23T16:50:07.277700Z

Yeah, very interesting. Can’t imagine transducers composing easily without this arg ordering of sequence functions. Not sure if it was extreme foresight or if we just got lucky. :)

indy 2021-05-23T16:58:24.281100Z

Or more like a good design decision allowing the easy evolution and birth of transducers

👍 1
2021-05-24T16:36:05.322800Z

my hunch (or vague recollection of the actual explanation) is that things that act like entities coming as first arg works with message passing / OO conventions from smalltalk (as later adapted by java, c++ and friends) (message thing arg) and things that act like collections coming last (action parameter things) works with data processing idioms coming from lisp (map, filter, etc. etc.) - for me personally the flip in order helps me categorize them as they are different idioms of programming

1
2021-05-24T16:38:59.323Z

as the RH quote above describes, both idioms existed in common lisp with the introduction of CLOS (the OO system for common lisp), and clojure just follows along

1
2021-05-24T16:39:43.323200Z

fun trivia, many don't realize that common lisp was one of the first few languages with a full featured object system

indy 2021-05-22T19:43:04.246Z

Is it some kind of idiom that for functions that return lazy seqs, the coll be the last arg?

2021-05-22T19:50:24.246200Z

Good question. I think your intuition is good, likely lazyness.

rakyi 2021-05-22T19:59:59.246500Z

https://stackoverflow.com/q/50275513/9846837

gibi 2021-05-22T20:00:55.246800Z

@julian608 thanks !

Lukas 2021-05-22T21:36:37.248500Z

Hey, is it possible to bind a value in an or clause with core.match? e.g. something like this

(let [x 1 y 2]
  (match [x y]
    [1 (:or 1 2 :bind-as b)] b
   :else nil))

Juλian (he/him) 2021-05-22T22:28:05.248800Z

you could use something like this:

(let [x 1 y 2]
  (match [x y]
    [1 (b :guard #{1 2})] b
   :else nil))