clojure

New to Clojure? Try the #beginners channel. Official docs: https://clojure.org/ Searchable message archives: https://clojurians-log.clojureverse.org/
2020-09-26T00:04:24.170100Z

This is going STRAIGHT to the brain bin

2020-09-26T17:35:32.188200Z

It’s https://notion.so. I’ve been using it for notes, todos, and docs since 2016 but recently discovered Zettelkatsen and created a database in Notion for it. It’s working quite well!

p-himik 2020-09-26T17:44:11.188500Z

Thanks!

2020-09-26T00:49:21.171Z

(map inc [1 2 3])
;; => [2 3 4]
(map #(update % 1 inc) {:a 1 :b 2 :c 3})
;; => ([:a 2] [:b 3] [:c 4])

2020-09-26T00:49:55.171700Z

Could that be considered an example of Clojure’s polymorphism or is there a different term for it?

2020-09-26T00:57:08.172Z

eh, ish

2020-09-26T00:58:05.172500Z

so the first thing that happens is seq is called on your map

2020-09-26T00:58:36.173100Z

that’s kind of polymorphic, in that different data structures implement seq in different ways

2020-09-26T00:58:55.173500Z

maps return a sequence of map entries

2020-09-26T00:59:12.173900Z

you can call key or val on each entry

2020-09-26T01:01:09.175300Z

map entries are also vectors, so you can get assoc or update by index (like you just did)

2020-09-26T01:01:31.175700Z

So that’s also kind of polymorphic

2020-09-26T01:02:06.176300Z

But usually when people talk about Clojure’s polymorphism, they’re talking about the user-level facilities: protocols and multimethods

2020-09-26T01:02:58.177100Z

I recall in a talk Rich had a $5 word for that but maybe I’m mis-remembering?

2020-09-26T01:03:32.177400Z

for protocols and mulitmethods?

2020-09-26T01:04:27.178300Z

Not quite. For that ability to operate on vectors, hash-maps, sets, strings with the same collection functions if I remember right.

2020-09-26T01:04:47.178500Z

ah, yeah. I dunno.

seancorfield 2020-09-26T03:43:05.178900Z

It's all about abstractions.

p-himik 2020-09-26T06:49:57.179Z

What is this screenshot from? Looks neat.

Joe 2020-09-26T13:11:32.179900Z

@tomisme Super interesting, thanks for the link!

vncz 2020-09-26T13:47:44.180700Z

Am I wrong or — since update-in does not take the target map as the last argument, I cannot use it in a threaded expression?

vncz 2020-09-26T13:50:41.181100Z

Ok seems like I was wrong

p-himik 2020-09-26T14:43:01.181700Z

(= 0 (county bountyDeck)) should be replaced with (empty? bountyDeck). Or just swap the branches in if and replace the condition with (seq bountyDeck). Unless, of course, boundyDeck is some custom collection type. When you want to get-in a path of only keywords, you can just use the -> macro: (-> current-state :firstPlayer :deck). Both shorter and faster. update-in with a path of a single item can be just update. (update-in [:bountyDeck] (disj drawn-card)) and the lines below it don't od anything - you should remove the parentheses around the call to disj.

vncz 2020-09-26T14:46:50.181900Z

@p-himik Thanks for the suggestions — I do have a doubt about the last line indeed. I made a mistake in the copy paste

vncz 2020-09-26T14:46:56.182100Z

What I'm doing at the moment is (update-in [:secondPlayer :deck] #(disj % second-player-card))

vncz 2020-09-26T14:47:09.182300Z

Using an anonymous function, but if there's a way to avoid that, even better. I haven't yet found one.

p-himik 2020-09-26T14:48:36.182500Z

Just use (update-in [:secondPlayer :deck] disj second-player-card)

p-himik 2020-09-26T14:48:54.182700Z

update-in internally does (apply f v args).

vncz 2020-09-26T14:49:05.182900Z

Ah ok I understand, this is because update-in takes an additional array of parameters that will feed to the function after the main arugment

p-himik 2020-09-26T14:49:06.183100Z

When in doubt, check the source code. :)

vncz 2020-09-26T14:49:08.183300Z

Didn't notice that

vncz 2020-09-26T14:49:32.183500Z

vncz 2020-09-26T14:49:39.183900Z

Ok so this is what I have now

p-himik 2020-09-26T14:52:45.184100Z

LGTM

vncz 2020-09-26T14:53:17.184300Z

Glad to hear that!

vncz 2020-09-26T14:53:47.184500Z

I've also reversed the if order as suggested and avoided the new state symbol

vncz 2020-09-26T14:54:01.184700Z

p-himik 2020-09-26T15:39:38.186300Z

One tiny thing - it's better to have a new line right after [current-state] to avoid shifting everything to the right too much and creating too much empty space on the left.

schmee 2020-09-26T15:40:22.186600Z

looking good! :thumbsup: small nitpick/fyi: variables and keywords in clojure are usually `:snake-case` rather than `:camelCase`

vncz 2020-09-26T15:57:26.186800Z

@schmee I've changed them all 🙂

vncz 2020-09-26T15:58:35.187Z

@p-himik Great suggestions, it looks way better now

Clypto 2020-09-26T16:26:42.187700Z

yes, I am

jdhollis 2020-09-26T17:13:55.188Z

One of my favorite books. Nice.

2020-09-26T17:35:32.188200Z

It’s https://notion.so. I’ve been using it for notes, todos, and docs since 2016 but recently discovered Zettelkatsen and created a database in Notion for it. It’s working quite well!

p-himik 2020-09-26T17:44:11.188500Z

Thanks!

practicalli-john 2020-09-26T17:51:50.188700Z

hopefully the nice people on #calva can help you if you are still having issues.

emccue 2020-09-26T19:06:39.189700Z

@vincenz.chianese It might sound dumb, but you can maybe improve your code by having named functions broken out

emccue 2020-09-26T19:06:42.189900Z

so

emccue 2020-09-26T19:06:48.190200Z

instead of

emccue 2020-09-26T19:07:25.191Z

(-> current-state       
    (update-in [matchWinner :score] inc)
    ...)

emccue 2020-09-26T19:08:31.192100Z

(defn increment-score-for [game-state player]
  (update-in game-state [player :score] inc))

emccue 2020-09-26T19:08:32.192300Z

and

emccue 2020-09-26T19:08:53.192800Z

(-> current-state
    (increment-score-for matchWinner))

1👍
vncz 2020-09-26T20:03:56.193800Z

Yeah, I guess that might be another thing to do!

evocatus 2020-09-26T21:15:20.195400Z

Hi! Would you choose Leiningen or cli-tools for a new project and why? Does anyone use clj-tools on Windows?

oxalorg (Mitesh) 2020-09-28T11:50:38.259600Z

If you're new (like me) I'd suggest going with lein. Just use it, and start writing clojure/business code. You can forget about it until you hit a roadblock and then re-evaluate.

evocatus 2020-09-26T21:17:48.196Z

Is it possible to use Docker Clojure image on Windows with VSCode and Calva?

p-himik 2020-09-26T21:22:57.196100Z

Definitely the latter. It's much more simple and much more composable. deps.edn is also just an EDN map, whereas project.clj is not - a tool cannot simply parse it without using Leiningen code.

schmee 2020-09-26T21:27:43.196300Z

Leiningen works great and gets the job done, try both and go with the one that makes the most sense to you

evocatus 2020-09-26T21:28:57.196500Z

I'm eager to try cli-tools but current Windows implementation requires to change Powershell script security settings which I don't want to (maybe because I don't know nothing about it)

evocatus 2020-09-26T21:29:18.196700Z

That's why my second question is about Docker

evocatus 2020-09-26T21:29:51.196900Z

Maybe I'll stick with Leiningen for a while. I can change it later, can't I?

seancorfield 2020-09-26T21:39:44.197300Z

@gr.evocatus I have two Windows machines that I do Clojure work on -- but I use WSL2 (and Ubuntu) and linuxbrew (the Linux version of Mac's brew/homebrew package manager) so I install/update the Clojure CLI via brew on both Windows machines (in Linux) and on my Mac as well.

seancorfield 2020-09-26T21:40:13.197500Z

A lot of tutorials still feature Leiningen, so there's no harm in having both Leiningen and the Clojure CLI on your system.

seancorfield 2020-09-26T21:41:09.197700Z

Also, if you want to use Powershell but don't want to deal with the security stuff, you could install Scoop (a Windows package manager) and then install the Clojure CLI -- and various other useful Windows tools like Babashka and clj-kondo -- using Scoop.

seancorfield 2020-09-26T21:41:28.197900Z

See the bottom section of https://github.com/clojure/tools.deps.alpha/wiki/clj-on-Windows

seancorfield 2020-09-26T21:42:02.198100Z

Also, if you have any questions about the CLI tools on Windows, or you get stuck, there's a #clj-on-windows channel.

1👍
seancorfield 2020-09-26T21:42:45.198300Z

@borkdude Can speak to that in detail since he just set up Docker/VS Code/Calva and gave a great talk at WSL Conf recently about it.

seancorfield 2020-09-26T21:46:14.198600Z

See https://blog.michielborkent.nl/2020/07/26/remote-wsl2-clojure/

borkdude 2020-09-26T21:46:22.198900Z

I've only used Docker from WSL2, not from Powershell / cmd.exe. Personally I don't run Clojure in docker, but all the other stuff like Postgres etc. VSCode has great support for connecting to remote machines or Docker containers, so you can run your entire dev env in a Docker container if you want.

1👍
seancorfield 2020-09-26T21:47:26.199100Z

Yeah, my setup is Docker via WSL2 (and I actually run Atom via WSL2 as well but I know VS Code has a great "remote" option to run on Windows but talk to code etc on WSL).

borkdude 2020-09-26T21:48:39.199300Z

That too. In WSL2 it's just a matter of installing the command line script and then typing code, and tadaa, it works.

borkdude 2020-09-26T21:54:01.199800Z

Scoop also requires the security setting from Powershell

seancorfield 2020-09-26T21:54:38.200Z

Oh, I thought it used some local installation like brew to circumvent that? Good to know.

borkdude 2020-09-26T21:54:54.200400Z

To install scoop, you need to enable some security setting

seancorfield 2020-09-26T21:55:10.200600Z

Ah, gotcha!

borkdude 2020-09-26T21:55:46.200800Z

@gr.evocatus If the Powershell security setting is absolutely a dealbreaker, here is a port of the Clojure CLI that is just 1 binary which you can place anywhere on your path: https://github.com/borkdude/deps.clj

seancorfield 2020-09-26T21:55:52.201100Z

(it's been a while, I don't remember having to change that, but I guess that's less worrisome than needing to do it for some random .ps1 script off the Internet 🙂 )

borkdude 2020-09-26T21:57:00.201400Z

It says so on <https://scoop.sh/> : > Set-ExecutionPolicy RemoteSigned -scope CurrentUser

chucklehead 2020-09-26T22:01:42.203900Z

@seancorfield if you enable all the developer experience settings in windows 10 I think it changes that setting as well.

chucklehead 2020-09-26T22:04:46.206800Z

There’s also a -Scope Process option that only applies to the current session that may work for the install, but I suspect scoop relies on it being set persistently since I think it also uses ps scripts for its packages.

Vincent Kowalsky 2020-09-26T22:08:31.208200Z

Is there standard function in clojure that lets you create the cartesian product of functions? I.e. some function X such that ((X f1 f2) x y) = ((f1 x) (f2 y))?

Vincent Kowalsky 2020-09-27T20:34:13.241200Z

Yes, exactly this. I was just wondering if that exists out of the box. Juxt is similar, but it applies all functions to the same argument rather than creating a n-ary function.

2020-09-26T22:33:01.208300Z

I don't know of a standard function that does exactly that, but you could accomplish something similar with

(map (fn [f v] (f v)) [f1 f2] [x y])

jsn 2020-09-26T22:41:52.208500Z

@codonnell no, the point, if understand it correctly, is to apply (f1 x) to (f2 y)

2020-09-26T22:42:23.208700Z

Ah, it was unclear to me if that return was supposed to be a list or a function invocation

p-himik 2020-09-26T22:45:38.208900Z

And it's not really a Cartesian product either way. That would be [[(f1 x) (f1 y)] [(f2 x) (f2 y)]] or something like that. The juxt function could help with that, maybe.

jsn 2020-09-26T22:46:05.209100Z

(defn X [f g] (fn [x y] ((f x) (g y)))) , or something

jsn 2020-09-26T22:50:00.209400Z

On the other hand, Wikipedia says https://en.wikipedia.org/wiki/Cartesian_product#Cartesian_product_of_functions

jsn 2020-09-26T22:50:46.209800Z

Then the map answer should do the trick, indeed

jsn 2020-09-26T22:54:07.210Z

(map #(%1 %2) [f g] [x y]) , I guess