beginners

Getting started with Clojure/ClojureScript? Welcome! Also try: https://ask.clojure.org. Check out resources at https://gist.github.com/yogthos/be323be0361c589570a6da4ccc85f58f.
berkeleytrue 2021-06-18T01:16:03.319700Z

Question around NS keywords. I was under the impression that #:foo {:bar "baz"} and {:foo {:bar "baz"} were equivalent. But if I do (assume ns is :foo) (::bar some-map) with the first one, I get "baz" but if I try it with the second one, I get nil. Are they not equivalent? Or is there another way to be able to get the value of :bar without being explicit about the NS?

phronmophobic 2021-06-18T01:17:55.320400Z

the equivalent of #:foo {:bar "baz"} is {::bar "baz"} aka {:foo/bar "baz"}

👍 1
berkeleytrue 2021-06-18T01:20:19.320700Z

hmm, ok. I think I see why my code isn't working. It's unfortunate

berkeleytrue 2021-06-18T01:20:24.320900Z

thanks you!

👍 1
seancorfield 2021-06-18T01:29:34.321200Z

@berkeleytrue namespaced keywords don’t all have to have the same qualifier in a hash map:

dev=> #:foo {:bar "baz" :quux/id 42}
{:foo/bar "baz", :quux/id 42}

seancorfield 2021-06-18T01:30:21.321400Z

The #:foo prefix provides a “default” namespace to use on any keys that don’t already have one.

berkeleytrue 2021-06-18T01:30:56.321600Z

oh that's interesting

seancorfield 2021-06-18T01:32:43.321900Z

https://clojure.org/guides/weird_characters#_and_namespace_map_syntax is a good read for this.

seancorfield 2021-06-18T01:33:16.322100Z

and https://clojure.org/guides/destructuring#_namespaced_keywords

berkeleytrue 2021-06-18T01:34:04.322300Z

It's that access of those inner properties. I was hoping to easily get properties off a map using the name space. (in some-ns) (::foo wide-flat-map) so that I can dynamically create a map later on (merge wide-flat-map {:some-ns (generate-data)}

berkeleytrue 2021-06-18T01:34:33.322500Z

Still learning so I'm mostly playing around

seancorfield 2021-06-18T01:47:13.322700Z

(-> wide-flat-map :foo :bar) or (get-in wide-flat-map [:foo :bar]) if you have nesting.

seancorfield 2021-06-18T01:47:28.322900Z

The names of keys and their depth in the hash map are orthogonal.

seancorfield 2021-06-18T01:47:50.323100Z

But qualified keys are idiomatic and I try to encourage folks to use them.

seancorfield 2021-06-18T01:48:39.323300Z

(and I’d advise against using :: unless you know what you’re doing since ::foo means something different in each ns)

seancorfield 2021-06-18T01:49:10.323500Z

(ns a.b.c)

::foo ;=> :a.b.c/foo

(ns x.y)

::foo ;=> :x.y/foo

berkeleytrue 2021-06-18T01:53:17.323700Z

That was kinda the point. I'm in the same ns but the generation is at runtime. I was hoping avoid doing :some-ns :foo because if I change the namespace name then I have to change all those calls. If ::foo worked then it wouldn't be a problem cause the compiler would put the right ns.

seancorfield 2021-06-18T01:54:36.323900Z

How would the namespace of the code end up tied to the keys in your nested map?

sova-soars-the-sora 2021-06-18T02:20:22.324700Z

brain fried question... how can I set all values in a map (on all keys) to the same value?

R.A. Porter 2021-06-18T02:24:47.324800Z

Here's one way...

(zipmap (keys <my map>) (repeat <my val>))

sova-soars-the-sora 2021-06-18T02:29:40.325Z

Neat!

seancorfield 2021-06-18T02:48:17.325200Z

If we get map-vals in Clojure 1.11 (it’s been mentioned a few times but not confirmed), you could do (map-vals (constantly <my val>) <my map>)

seancorfield 2021-06-18T02:48:49.325400Z

Currently available via a gist as a :git/url dep: https://gist.github.com/seancorfield/6e8dd10799e9cc7527da5510c739e52f

seancorfield 2021-06-18T02:52:58.325600Z

Go vote for it here: https://ask.clojure.org/index.php/1926/adding-functions-map-vals-and-map-keys

berkeleytrue 2021-06-18T02:53:23.325900Z

I was exporting (not sure if that is the right word) a map with the key as the namespace and a function to produce the state {(keyword (namespace ::r)) some-fn}. Pretty hacky and I'm not happy with this setup.

seancorfield 2021-06-18T02:54:15.326100Z

Yeah, that sounds well dodgy to me…

seancorfield 2021-06-18T02:55:36.326400Z

I guess my basic question is “why?” — what semantics does the namespace name specify in this hash map?

berkeleytrue 2021-06-18T02:57:27.326600Z

It is just a way to prevent name clashes on a large flat map. I just had a thought of just using some arbitrary ns key instead of trying to get the namespace of the file {::state some-fn} and accessing would be (get-in wfm [::state :foo]) .

Ovidiu Stoica 2021-06-18T03:01:05.327Z

In learning clojure, what is the ONE thing that if you practice regularly, you will become a great clojure programmer?

seancorfield 2021-06-18T03:01:17.327100Z

Better to use semantically meaningful qualified names, in my opinion. :person/first-name, :address/street, etc.

seancorfield 2021-06-18T03:02:25.327300Z

Make them as unique as the context requires — more global data should probably use something like reverse-domain-name + entity style qualifiers, less global data can use a simple symbol for the qualifier.

seancorfield 2021-06-18T03:03:13.327500Z

If you work with JDBC via next.jdbc, you’ll find yourself with column names that are qualified by the table name (so you can do a JOIN and get distinct, meaningful names).

phronmophobic 2021-06-18T03:08:44.327700Z

I would reject the premise of the question. The difference between good and great isn't a handful of big things, it's 10,000 little things. Bonus answer from the FAQ posted not too long ago: https://gist.github.com/reborg/dc8b0c96c397a56668905e2767fd697f#how-can-i-achieve-programming-mastery

👆 1
Ovidiu Stoica 2021-06-18T03:14:38.327900Z

Hmm. Let me rephrase then: If you had only 20 minutes to dedicate to clojure programming every day, what would you learn to have the highest impact?

phronmophobic 2021-06-18T03:19:43.328100Z

It kinda depends on what you're hoping to get out of it. • Learn general programming concepts to apply in other languages? • Learn programming to automate workflows? • Generally learn more about how computer programs work? • Programmatic art/music? • Build a website? • For fun • something else?

Dane Filipczak 2021-06-18T04:12:36.328400Z

After becoming comfortable with the core library, the highest impact set of concepts for me was becoming effective with clojure style polymorphism. defmultis, protocols, records, etc. Reading library code is often a good way to see effective usages of these features.

👍 1
2021-06-18T05:18:12.328700Z

20min per day? I think going through the 4clojure exercises can be a good start, becoming good at the core functions to be able to manipulate data-structures is pretty important.

💯 1
2021-06-18T05:23:26.328900Z

Once you got that down, and you have recursion all figured out, and you also see how you don't always need to use loop/recur, but can often just compose core functions instead, map/reduce/range/partition/juxt/etc. I would spend some time on different topics. Like go through all Collections and their functions and play with those at the REPL to understand them well. Then learn about sequence and laze-sequences and all of their functions, play with that at the REPL until you understand it well. Then I'd spend another few sessions on learning namespaces, Vars, what all you can do with those all their features and all that. Then I'd learn about the bootstrapping, how a Clojure program starts, where it loads its dependencies from, where it loads its module from. Then I'd try to write a full command line program, like a command line TODO app. As part of that, each time you struggle with something, I'd take a side-track to fully master that part, so say you struggle with managing the TODO lists state, I'd go learn about state management in Clojure, etc.

👍 1
2021-06-18T05:26:25.329200Z

There's a lot to cover. You could also go here: https://clojuredocs.org/quickref and spend one 20min each day on each sections in here. Do one on arithmetics, then one on comparison, then one on bitwise ops, then one on cast, etc. top to bottom, order doesn't matter. And then I'd also go here: https://clojure.org/reference/reader and spend a 20min on each of those sections too (you might need more than 20min for some of these). Do one on the reader, then on repl and main, then on evaluation, etc. Until you grasp each one. After all that, you should start to feel comfortable doing full on projects, and that'd be my next move from this point on.

1
Alexander Moskvichev 2021-06-18T08:05:50.331Z

I wrote a code that is suddenly extremely slow. (:require [clojure.data.xml :as data-xml]             `[clojure.xml :as xml]`             `[http://clojure.java.io :as io]`             `[clojure.zip :as zip]`             `[clojure.pprint :refer [pprint]]`             `[fipp.edn :refer [pprint] :rename {pprint fipp}])` (defn iter-zip [zipper]     `(->> zipper`          `(iterate zip/next)`          `(take-while (complement zip/end?))))` (with-open [r (<http://clojure.java.io/input-stream|clojure.java.io/input-stream> "data/data_202106160959.xml")]     `(with-open [w (http://clojure.java.io/writer "data/goods.edn")]`       `(-> r`           `xml/parse ;; about 15sec`           `zip/xml-zip ;; another 15sec`           `iter-zip ;; plus 60 sec`           `;(filter loc-category?)`           `(fipp {:writer w}))))` It takes minutes for a 15Mb input file. What I'm doing wrong?

borkdude 2021-06-18T11:23:04.332200Z

@alexander.moskvichev what is the zipper doing?

borkdude 2021-06-18T11:23:45.332700Z

I think the iter-zip function is creating lots and lots of objects

2021-06-18T11:36:15.333400Z

Even so, 15 sec to parse 15 mb xml seems a lot, no?

Alexander Moskvichev 2021-06-18T13:13:02.334400Z

@borkdude This is my first attempt to use clojure.zip Zipper suppose to be lazy, but I can use it wrong. In between reading and writing will be the filtering and transforming stage, I planned to use clojure.zip for navigating through XML.

borkdude 2021-06-18T13:14:09.335400Z

@alexander.moskvichev It seems you are printing all intermediate zipper objects

borkdude 2021-06-18T13:14:28.335800Z

you should at least call zip/node on it, to get back xml

borkdude 2021-06-18T13:14:39.336100Z

I don't know what you're trying to do really

borkdude 2021-06-18T13:14:48.336300Z

Start with a small example

Alexander Moskvichev 2021-06-18T13:40:37.338900Z

@qmstuart I think so, but 15 sec is ok for now.. clojure.xml/parse not lazy, in that file roughly 20k items each with 10-20 properties. Maybe it's a normal time for one thread.

Alexander Moskvichev 2021-06-19T07:49:10.353100Z

@emilaasa @borkdude Thanks. I was calling pprint for the whole file for every zipper iteration. Of course, it was slow, lol. @zengxh Switched to data-xml. I appreciate that you spent time testing.

Apple 2021-06-18T13:55:22.339100Z

I used clojure.data.xml/parse and it is lazy.

Alexander Moskvichev 2021-06-18T14:26:21.339300Z

@zengxh That right. But I use clojure.xml, not clojure.data.xml. Sorry for the mess in (:require...)

Apple 2021-06-18T14:31:44.339700Z

Perhaps for large xml file clojure.data.xml is better. It mentions this as one of its features "lazy - should allow parsing and emitting of large XML documents"

MatthewLisp 2021-06-18T14:41:48.340800Z

Hello fellow clojurists Is there an equivalent of Leiningen's :java-source-paths for clj deps.edn ?

Alexander Moskvichev 2021-06-18T14:42:12.340900Z

@zengxh.. Shure, I even 'require it already. 🙂 But I think my main problem somewhere else

2021-06-18T14:43:45.341500Z

deps.edn on its own does no java compilation for you

2021-06-18T14:43:59.341900Z

there are various tools for deps that do this, they have their own config

MatthewLisp 2021-06-18T14:46:09.342300Z

ok, just found a guide using 'badigeon' https://gamlor.info/posts-output/2019-10-24-compile-java-with-clojure-deps/en/

Apple 2021-06-18T15:02:34.342600Z

I have a 90MB xml file 2.2 mil lines I replace fipp with just count and clojure.xml with clojure.data.xml Test briefly with time and it's inside a virtualbox vm. It takes 1.7sec 2.0sec 17.3sec up to parse xml-zip iter-zip respectively and the final count is 4.6mil

alexmiller 2021-06-18T15:22:29.342900Z

coming soon ...

👏 3
6
😎 4
emilaasa 2021-06-18T20:01:20.345Z

The zipper object is the whole tree (xml doc) and your position so printing it might be expensive.

walterl 2021-06-18T23:50:43.349600Z

Speaking of RDD: how do you guys eval a form in the REPL that contains symbols defined outside of that form? E.g. I'd like to eval the (super-hard-calc x) form in the body of the let in this contrived example:

(def super-hard-calc inc)

(let [x 1]
  (super-hard-calc x))
Currently I copy the form into a Rich comment, and then replace or let values for all required symbols. But it means that, if I make any changes, I've now added a syncing problem. 😛 I'm using vim + Conjure, but solutions in any env are welcome.

emilaasa 2021-06-19T08:08:09.355400Z

I do what (I gather) Sean does; (def x 1) anywhere in the file, for me in a comment block, will make x available anywhere, as long as you don't overwrite it. So in this case you'd avoid evaluating the surrounding let and just eval the calculation.

❤️ 1
emilaasa 2021-06-19T08:09:25.355600Z

(def super-hard-calc inc)

(let [x 1]
  (super-hard-calc x)) ; 11

(comment
  (def x 10) ; #'conjure.internal/x
  ,)