beginners

Getting started with Clojure/ClojureScript? Welcome! Also try: https://ask.clojure.org. Check out resources at https://gist.github.com/yogthos/be323be0361c589570a6da4ccc85f58f.
adam-james 2021-02-26T00:32:38.409900Z

I was looking at s/fdef a bit, and as you say using instrument will essentially eliminate any need for :pre conditions. Orchestra I haven't heard of and that looks nice for the function output validation too, which would certainly help in my case. Thanks for the feedback

rafalw 2021-02-26T02:04:40.413500Z

Hi, I'm reading https://github.com/linpengcheng/PurefunctionPipelineDataflow/blob/master/doc/relational_model_on_hashmap.md and I wonder what this "empty" commas at the end mean

(defn join [db main_table join_table join_col]
  (let [f #(let [x (-> db main_table %2)]
              (->> x
		   join_col
		   (get (db join_table) ,)
		   (merge x ,)
		   (assoc %1 %2 ,)))]
  (->> db
       main_table  
       keys
       (reduce f {} ,)
       doall)))  
any hints ? never saw anything like this ...

2021-02-26T02:09:50.414700Z

Commas in clojure are whitespace, the reader ignores them

2021-02-26T02:10:44.416500Z

So they don't mean anything to clojure, but some people do that kind of thing to mark where threading macros will insert their arguments

👍 1
2021-02-26T02:11:18.417100Z

I don't much care for it

rafalw 2021-02-26T02:11:52.417500Z

thanks, I understan now ....

2021-02-26T02:44:58.419100Z

hi i tried to understand this https://clojuredocs.org/clojure.core/read-line in my doom-emacs, it'll prompt an input, but once i input it in my repl, it stuck, it doesn't return like that. how to do that in emacs?

(do (print "What's your name? ") 
           (flush) 
           (read-line))
What's your name? Clojure
"Clojure"
i have to ctrl+c twice and result in error
Execution error (InterruptedException) at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject/await (AbstractQueuedSynchronizer.java:1627).
null

dpsutton 2021-02-26T03:08:47.419900Z

emacs uses nrepl so things are a bit more complicated. when you attempt this, you'll notice in the bottom of your emacs window a prompt that looks like this:

dpsutton 2021-02-26T03:09:00.420300Z

emacs is wanting you to type there to send the input rather than in the repl buffer

✅ 1
2021-02-26T03:18:49.420500Z

@dpsutton I want to thank you from deepest of my soul!

😭 1
dpsutton 2021-02-26T03:19:07.420800Z

why you're quite welcome 🙂

2021-02-26T03:22:36.421Z

been looking for an answer since about 3 wks ago, now it comes to light. I'm so stupid

dpsutton 2021-02-26T03:23:12.421200Z

not at all

dpsutton 2021-02-26T03:23:31.421400Z

it makes sense to accept repl input from the repl. its kind of a quirk that it works this way. and the input request is tiny and out of site

2021-02-26T03:28:32.421600Z

couldn't be more agree than this

2021-02-26T05:01:11.421800Z

@dharrigan thank you so much for helping me. https://github.com/dharrigan/google-apis-example/tree/master/src/dharrigan it's because of i couldn't operate the emacs that well, but I got the concept of oauth2 because of you. still it's really simple, but I just found the answer today omg... lol :rolling_on_the_floor_laughing:.. again, thanks a lot!!

dharrigan 2021-02-26T07:16:17.422300Z

You're most welcome 🙂

dharrigan 2021-02-26T07:16:41.422500Z

Keep on 'learning! 🙂

pinealan 2021-02-26T07:27:59.424300Z

are there clojure libraries for hmac?

lassemaatta 2021-02-26T07:29:12.424400Z

perhaps buddy, https://funcool.github.io/buddy-core/latest/02-mac.html ?

phronmophobic 2021-02-26T07:39:01.424600Z

this can also be accomplished with a small amount of java interop, https://stackoverflow.com/questions/39355241/compute-hmac-sha512-with-secret-key-in-java

pinealan 2021-02-26T07:47:56.424900Z

thanks! I’ll try them out

Ryan Boldi 2021-02-26T08:16:45.427800Z

Hey guys! I just started trying to use incanter to draw some plots, but whenever I do:

(ns main
  (:use [incanter core charts stats datasets]))
clj-kondo yells at me for using :use. Is there a succinct way to achieve the same thing using :refer :all? (p.s. it also underlines all my incanter functions like histogram due to unresolved symbol even though the code works)

borkdude 2021-02-26T08:18:27.428600Z

@ryan.boldi123 clj-kondo yells at you because it has no way of knowing where some of the symbols in your code are coming from and therefore it discourages :use and :refer :all for that matter.

borkdude 2021-02-26T08:19:25.429400Z

As a human I often have the same problem as clj-kondo, that's why I also don't use :use myself, I find that the code becomes more confusing. Just use :require + :as or :refer

Ryan Boldi 2021-02-26T08:20:36.430600Z

@borkdudeSo would I need to always use fully qualified names whenever I call incanter functions? Something like incanter.core/view ?

borkdude 2021-02-26T08:21:15.431300Z

@ryan.boldi123 No: (ns main (:require [incanter.core :refer [view]]))

borkdude 2021-02-26T08:22:00.431900Z

Or: (ns main (:require [incanter.core :as i])) and then write (i/view ...)

Ryan Boldi 2021-02-26T08:23:09.432800Z

@borkdude So I would need to write 4 require lines, one for core, charts stats and datasets?

borkdude 2021-02-26T08:23:28.433200Z

yeah, well you don't have to, you can use nested libspecs, but that's another story ;)

😅 1
Ryan Boldi 2021-02-26T08:23:57.433800Z

@borkdude Thank you very much!

borkdude 2021-02-26T08:24:31.434500Z

(ns main (:require [incanter [core :refer [view]] [charts :refer [foo]]]))
This works, but this syntax has gone a bit out of fashion in favor of just writing the namespace names in full

😮 1
Ryan Boldi 2021-02-26T08:25:43.435400Z

This is very helpful. I don't mind sticking to doing 4 separate requires for the sake of readability.

dharrigan 2021-02-26T08:34:21.435700Z

Oh, I just answered that also in discord

solf 2021-02-26T09:42:13.436100Z

What discord? I tried googling and found a couple in years-old reddit comments, is there a "recommended" one?

dharrigan 2021-02-26T11:10:01.439Z

It's called Clojurians

dharrigan 2021-02-26T11:11:03.439200Z

Discord doesn't make it easy to find out the server URL

dharrigan 2021-02-26T11:13:19.439600Z

Try this one : <https://discord.gg/UyKyKzwa>

dharrigan 2021-02-26T11:13:25.439800Z

It was on Invite Someone

solf 2021-02-26T11:18:22.440200Z

Thanks!

dharrigan 2021-02-26T11:19:35.440400Z

you're most welcome! 🙂

FiVo 2021-02-26T12:13:24.442Z

Does seq (and thereby keys and vals ) give some guarantee with respect to ordering for maps with identical keys ?

FiVo 2021-02-26T12:15:02.442900Z

For example

(defn gen []
  (-&gt;&gt; (for [i (range 1000)]
         [i (rand-int 1000)])
       (into {})))
does it always hold that
(= (keys (gen)) (keys (gen)))

ghadi 2021-02-26T13:40:11.443500Z

no, it doesn't hold across different maps @finn.volkel

FiVo 2021-02-26T13:48:31.445100Z

@ghadi so the guanrantee is not given, but the implementation always yields the same order or the implemenation does not always yield the same order?

2021-02-26T13:49:03.445900Z

If you add equal keys in same order to two maps the implementation today will have same order

2021-02-26T13:50:12.447800Z

If you add same keys in different orders to two maps, their order of seq, keys, and Vals can differ

FiVo 2021-02-26T13:50:54.448Z

thanks, that makes sense

adam-james 2021-02-26T13:53:25.449200Z

Is there an appropriate way to 'pull in' functions from different namespaces into a namespace such that the symbols become accessible in that ns from other namespaces? That seems unclear... what I mean is to be able to do something like this:

(ns svg-clj.main
  (:require [clojure.string :as st]
            [svg-clj.utils :as utils]
            [svg-clj.specs :as specs]
            [svg-clj.transforms :as transforms :refer [translate rotate scale centroid bounds]]
            [svg-clj.path :as path]))

(some-kind-of-pull translate) ;; something to make the symbols accessible, incl. docstring and args
(some-kind-of-pull rotate) 
...
Then, a user would use svg-clj as follows:
(ns user.drawing
  (:require [svg-clj.main :refer [circle translate rotate]])) ;; user doesn't need to know about svg-clj.transforms

walterl 2021-02-26T14:50:00.449400Z

My guess: (intern *ns* 'translate translate), etc.

oly 2021-02-26T15:13:53.451Z

https://clojurescript.org/reference/repl-options where can I put these ? I want to set a static path to resources/public so when i jack in I can ajax files tried in build.edn but either thats wrong or I am doing something else wrong 😕

adam-james 2021-02-26T15:23:53.451600Z

Hmm... tried that and it almost works. I do have the symbols accessible when :requiring main, but I don't see the argslist show up in my editor (my minibuffer in emacs usually shows the args as I type a fn)

seancorfield 2021-02-26T18:03:56.452600Z

@adam.james That's because the metadata is lost on that intern -- but you can get the metadata from the original var and add it to the new interned var. Something like this: https://github.com/clojure-expectations/clojure-test/blob/develop/src/expectations/clojure/test.cljc#L538-L546

seancorfield 2021-02-26T18:05:58.452900Z

I'm using update to append the line about "Imported from..." but you could just do (insert *ns* 'translate (with-meta translate (meta #'translate))) I think. #' gets the var behind the function translate and you need that for the metadata.

2021-02-26T18:26:28.453500Z

is there a better way to write this?

(let [m {:foo "ab" :bar "cd"}
        bar (list (:bar m))
        foo (list (:foo m))]
    (concat bar foo))
=&gt; ("cd" "ab")

2021-02-26T18:27:33.454200Z

I basically want to take two keys from a map and make a list out of the values

2021-02-28T19:18:20.009800Z

juxt is awesome, and yes the map contains more than 2 keys

borkdude 2021-02-28T19:40:20.010Z

Just for the record, juxt works with any (positive) amount of keywords (or other fns)

sb 2021-02-26T18:31:03.455400Z

Maybe this post is helpful https://blog.mrhaki.com/2021/02/clojure-goodness-destructuring-maps.html?m=1 how to destructuring maps

sb 2021-02-26T18:31:32.456200Z

If I understand good

seancorfield 2021-02-26T18:33:51.456400Z

@david.daigml Is there a reason not to just use [(:bar m) (:foo m)] rather than creating a singleton list for each item and then gluing them back together?

2021-02-26T18:34:21.456600Z

(let [m {:foo "ab" :bar "cd"}
      {bar :bar foo :foo} m]
  (list bar foo))

seancorfield 2021-02-26T18:34:53.456800Z

And as sb says, destructuring can make this cleaner:

(let [{:keys [bar foo]} {:foo "ab" :bar "cd"}]
  [bar foo])

👍 1
2021-02-26T18:35:06.457Z

yeah

2021-02-26T18:35:37.457300Z

cool, this is much more idiomatic, thanks

seancorfield 2021-02-26T18:36:21.457500Z

This form of destructuring is rarely used, unless you want to rename the keys to something else: {bar :bar foo :foo}, i.e. {one :bar two :foo} -- so one is bound to (:bar m) and two is bound to (:foo m)

seancorfield 2021-02-26T18:36:59.457700Z

(sometimes that is absolutely necessary, so it's good to know about, as well as the more common :keys destructuring)

2021-02-26T18:37:53.457900Z

in my use case, :keys destructuring would work, there is no need to rename the keys

adam-james 2021-02-26T18:38:40.458100Z

I was just messing around with meta! Your linked code example gave me the hint I needed. I did not know about 'resolve' and was struggling to attach meta to the var as opposed to the symbol. Thanks for the help!

borkdude 2021-02-26T19:28:30.458900Z

user=&gt; ((juxt :bar :foo) {:foo "ab" :bar "cd"})
["cd" "ab"]

👀 1
seancorfield 2021-02-26T19:54:34.459100Z

Another good use for juxt 🙂