Fork me on GitHub
#beginners
<
2019-05-24
>
robertfrederickwarner00:05:46

Is clojure.data.xml the recommended way to go for basic reading/writing of xml? are there any community libraries that I should look at? I had a look around but didn't spot anything, thought I would ask here before embarking down the data.xml path

noisesmith00:05:41

for basic read/write I'd use clojure.data.xml, there are also bindings to xpath / tagsoup and there's a zipper implementation for xml in clojure.zip

noisesmith00:05:12

the zipper being for cases where you have to do complex alterations or extractions

davecompton700:05:15

@hiredman Thank you. Putting the -w option before the -c option got source file monitoring to work as I had expected. Sorry for the slow response - took me a few minutes to test.

robertfrederickwarner00:05:01

@noisesmith thanks, I'll take a look at those. i had seen the clojure.zip referenced.

noisesmith00:05:28

zippers are cool, they are a whole sub-language for manipulating complex data structures

noisesmith00:05:40

definitely not what you need most of the time, but pretty great when you need them

robertfrederickwarner00:05:24

Yeah I was just learning about them last week. Definitely something I'm glad to have in the tool belt

alexmiller00:05:00

and use the latest version, even though it's alpha or beta or whatever

jyad186611:05:53

I succeeded in running "hello world" in clojure. I used vs code and also I tried Emacs. I'm using vs code very well in JavaScript development. My question is it worth to learn Emacs in 2019 , are still recommendation from "Clojure for the Brave and True" book relevant ?

michael.e.loughlin12:05:23

like learning vim bindings, it's probably only worth it for a long term investment, using with multiple languages. I wouldn't learn it just to write Clojure. That said, it's not particularly hard to get up and running with Emacs. Maybe someone else who uses VS Code for Clojure can chime in and say if it's missing any features.

lucascoffey12:05:54

Hello Yadia - as someone who is also new to Clojure / ClojureScript … I would recommend that you watch this video:

lucascoffey12:05:19

Its going to be mentally consuming enough — learning Clojure … so I would not try learning a bunch of tools on top of that. --- You can always learn those later.

jyad186612:05:02

@lucascoffey Thanks. It's good point

jyad186612:05:41

@michael.e.loughlin Sorry , I didn't get your second point. As I understand you are not agree to learn Emacs just for Clojure.

lucascoffey12:05:45

I think Vim & Emacs are very valuable tools to learn

lucascoffey12:05:55

however I come from the world of Python / PyCharm - so using Intellij Idea w/ Cursive is wonderful

lucascoffey12:05:27

So if VS Code has something similar that you are used to, then by all means use it.

michael.e.loughlin12:05:49

@jyad1866 It's a judgement call. It's good to learn Emacs if you want to use that, but you will be learning and thinking a lot about Emacs and not Clojure, as @lucascoffey said

michael.e.loughlin12:05:17

I personally don't think it's worth learning Emacs just for Clojure

jyad186612:05:31

I think knowing vim or Emacs and being productive in those editor is different. I'm using vim occasionally but I don't use it for writing a serious project. because I can't remember all that key bindings. It take times but it's not worth for web development at least for me.

michael.e.loughlin12:05:34

if you don't want to learn lots of keybinds, then I don't recommend emacs!

jamie96212:05:18

I’m working in Clojure with VS Code, which was also my editor of choice before I starting using the language. The setup can be a little fiddly, but the clojure, cljfmt and parinfer extensions are excellent and it doesn’t seem to miss much from emacs / cursive / alternatives

jamie96212:05:28

I even get intellisense suggestions and docstrings

jyad186612:05:14

@michael.e.loughlin I know some of keybinding in Vim also in Emacs today I learned some and I can learn it. but as you said I see it took months for me to be enough productive.

jyad186612:05:26

also thanks for your good points

jyad186612:05:09

@jamie962 thanks for the points. how do you get intellisense, do you special extention?

jamie96212:05:30

The ‘clojure’ extension, when connected to an nREPL should do it 🙂

jyad186612:05:00

I used Calva

jamie96212:05:01

You’ll need to boot a repl up in the terminal with lein repl, then connect it with the command

jyad186612:05:29

I used Calva do you use this, or other extention

jamie96212:05:56

I’ve used both Calva and Clojure

jamie96212:05:09

I’m not sure which I prefer. They appear to be the same. and they both work well.

qythium13:05:04

I'm trying to introduce some beginners to programming via Clojure, given no prior experience with with either would VS Code + Calva or Atom + ProtoREPL a better choice?

qythium13:05:49

Also is it a good idea to start things out with Parinfer? The Atom plugin for that looks a lot better developed

penryu16:05:51

IIUC, the Parinfer author has focused development on Atom for now, but I believe it will continue to support other editors, and I'd except any advances made in Atom to be adapted to other implementations.

qythium13:05:07

( hope this is the right place to be asking these questions)

manutter5113:05:05

Sure, this is a good place for questions like that

manutter5113:05:16

I think personally I would go with Atom and parinfer

afoltzm13:05:14

for an even easier introduction try: https://www.maria.cloud/

afoltzm13:05:28

no installation / plugins required!

qythium14:05:21

Yup! I've been starting them off with Maria which is absolutely awesome for this sort of thing

qythium14:05:18

but after a while they need some external dependencies (for some domain-specific application), which can't be done in Maria

d.ian.b18:05:15

there's a way to do this?

d.ian.b18:05:37

(-> arg (update :attributes decodejson
                    :created-by str
                    :invited-user-id str
                    :channel-id str))

d.ian.b18:05:12

"multiarity update"

michael.gaare18:05:14

you'd need to do multiple update calls

michael.gaare18:05:40

since update supports passing arbitrary extra args to the transformation function, it's kinda locked down to doing just one at a time

noisesmith18:05:54

you can use reduce-kv plus a function using a map from key to updating function if this is a performance concern

noisesmith18:05:24

(def updaters {:attributes decodejson :created-by str ... ...}) (persistent! (reduce-kv (fn [m k v] (assoc! m k ((updaters k identity) v)) (transient {}) original-map))

lvbarbosa18:05:19

Guys, I just wanted to share with you that got an offer to my first full-time Clojure job! You are all definitely part of this, since you helped me multiple times during my initial learning process. Thanks a lot!

zane18:05:24

Hooray! Congratulations, Lucas! 🎉

alexmiller18:05:51

Keep hanging out and pay it forward to the next one!

ericcervin20:05:24

Would be ace if you typed a short description of your learning process into the main beginner thread. A bulleted list even.

lvbarbosa18:05:49

@ where is that thread?

ericcervin18:05:55

Sorry, I mean channel. Hopefully you'll say something out in the main #beginners channel.

michael.gaare18:05:02

@noisesmith into might be better in this case for performance, no? Especially if there are a lot of keys in the map not being updated. Something like:

(into original-map (map (fn [[k f]] [k (f (get original-map k))])) updaters)

noisesmith18:05:09

@michael.gaare that's a good call yeah

alexmiller18:05:14

if you're updating just 4 attributes, it likely doesn't matter. why not just assoc them all in one go?

alexmiller18:05:31

(assoc arg :attributes decodejson
                    :created-by str
                    :invited-user-id str
                    :channel-id str)

michael.gaare18:05:21

don't think that's gonna do what what OP was asking for - decodejson and str are meant to be applied to the values in arg

alexmiller19:05:03

(let [{:keys [attributes created-by invited-user-id channel-id]} arg]
  (assoc arg :attributes (decode-json attributes)
              :created-by (str created-by)
              :invited-user-id (str invited-user-by)
              :channel-id (str channel-id)))

michael.gaare19:05:52

that should do it. we'll get this shed painted yet 😉

alexmiller19:05:04

for me, it's real obvious what that code is doing. I'm sure there's a faster way, but I'll take obvious over fast as a first pass

alexmiller19:05:05

but you could easily write an update-many macro/function that did the fast thing and was probably easier to read than reduce-kv or into would be directly

michael.gaare19:05:38

just chained updates would probably be pretty good, not requiring the triple-redundancy of mentioning the key names. I have a personal thing where if I have a chance to use into with transducing arity I will do it 10/10 times

petterik20:05:23

the new supdate library is kind of neat for doing multiple updates to structured data:

(require '[vvvvalvalval.supdate.api :as sup])
(sup/supdate data {:attributes decode-json
                   :created-by str
                   :invited-user-id str
                   :channel-id str})

petterik20:05:06

FWIW, I'd recommend writing your own function over reaching for libraries. Especially when starting out

ericcervin21:05:50

I saw this recently in someone's code. Part of an animation of falling rain.

(-> drop
         (update :y + speed)
         (update :speed + accel))

theeternalpulse17:05:38

I've since switched to some specter libs since they offer a lot easier updating of mixed types in data structures (arrays nexted in object nested in arrays etc

ericcervin18:05:05

Ya. I skipped the experiment where you used specter. I've seen Mr Marz demo Specter and it's amazing, but I'm just resistant to learning new libraries, though clojure2d might be in the queue.

theeternalpulse19:05:28

It does have an understanding curve, but when I came back to it after a while it clicked into place. I've found actually having the pressing need to solve something helps understand the tool better

ericcervin20:05:19

You drawing ideas, as in 04_projection.clj, are a bit more involved than anything I imagineer. Most of the time I'm imagining what I'd do with an xacto knife and a glue stick.

theeternalpulse00:05:17

yeah, that one is basically me trying to project 3d points onto 2d. Something I wrote down to work out before coding. I doubt it's 100% correct, it's only working off of a vanishing point. I want to try some shading and simple 3d models with that one but never got back to it

ericcervin00:05:56

Ah yes. Getting back to it. I'm just now resuming my study of 10_photo_manip.clj . As far as I know, quil doesn't have anything as slick as clojure2d's filter-channel , so I'm doping out the filtering myself. Just posted an aside in #quil

theeternalpulse03:05:56

Glad my experiments are useful. They're mostly just my testbed when I think of random things, so completeness isn't always the goal

ericcervin03:05:28

Ya. (Re)learned about clojure2d, destructuring, and threading. In June I'll probably need to work on something sad and practical like Python

bones21:05:05

Hi, I'm trying to create cljs and tools.cli to create an svg viewer. I'd like to be able to set paper sizes from the cli e.g clj -m cljs.main -m svg.core --format a3 but can't figure how to call my namespace properly

bones21:05:44

svg.core uses parse-opts and Ive created a list of possible cli options, taking my cue from the example under tools.cli GitHub page

lilactown21:05:14

hey bones. I don't believe this will work; a couple reasons: 1. you can't have two "mains" (in Clojure / JVM speak) right now, so your two -m commands won't work 2. your CLJS code, svg.core, will be executed in the browser, and there's no way pass these command line options to your browser code

iagwanderson21:05:31

hi ppl, I am writing an application and I would like to test my functions that interact with the database. I'm using toucan to manage the mysql database. However, I noticed that I have many functions with the following pattern

(defn feature2 [args]
   (db/insert model/Table args))

(defn feature1 [params]
    ....
    (feature2 ... ))

The problem I'm facing with this nested-pattern is way worse than this example. If I want to test the feature1 function, I'm not able to use the test niceties of toucan which creates a mockup object of my table because feature1 can't inject the mockup object into feature2. Am I thinking right? What is a good pattern for this problem? Thanks

noisesmith21:05:07

if possible the cleanest way to fix things like this is to avoid hiding IO inside abstractions

noisesmith21:05:25

pure functions can nest seamlessly inside IO functions, the reverse often causes problems

noisesmith21:05:48

so put the IO stuff at the top level, and then inside the IO doing function, call the pure functions (when possible)

noisesmith21:05:52

you can also use dynamic bindings, or a "context data" map that gets passed recursively down through the layers of code

noisesmith21:05:25

but often the pervasive usage of "context data" is a sign of poor organization, or even your entire stack being "upside down"

iagwanderson21:05:18

yes, I am leaning to your last option here. I think things are not right.

iagwanderson21:05:39

do you have any material with recommendations to app organization?

iagwanderson21:05:09

I'm still at the very beginning of this solution, for now a good refactor would do good

noisesmith22:05:37

Zach Tellman's book "Elements of Clojure" is excellent

lucascoffey13:05:46

I am actually in the process of reading it right now and could not agree more. — Even though its kind of dense / deep at times I highly recommend it to newbies like me because when you are first starting out there is nothing more helpful than having someone to say: -- “Here is how you do it”

lucascoffey13:05:21

— At this point I don’t know enough to form my own judgements about — “Theories on best software practices.” --- So I just need someone to hold my hand for now until I “learn to walk on my own.”

noisesmith22:05:28

and there are state management libraries that work well with the pattern of putting side effecting / config dependent things at the top of your abstraction stack (stuartsierra/component, integrant, mount)