Fork me on GitHub
#beginners
<
2023-03-07
>
Can12:03:19

Hello everyone! :)) I need little help, can you take a look my Stackoverflow post please? https://stackoverflow.com/questions/75661963/hyperfiddle-electric-clojure-how-to-add-new-values-into-table-as-table-forma

delaguardo13:03:29

there is also #hyperfiddle channel

Can13:03:50

Thank you, I joined in it know 🙂

quan xing14:03:45

I have two maps

(def m1 {:a "a1" :c {:c1 "c1" :c2 "c2"}})
(def m2 {:a "a1new" :c {:c1 "c1new" :c3 "c3"}})
I want to merge two maps. use m2 update and append to m1
(merge-maps m1 m2) => {:a "a1new" :c {:c1 "c1new" :c2 "c2" :c3 "c3"}})
I use the (merge m1 m2), but the result is not my result
(merge m1 m2) => {:a "a1new" :c {:c1 "c1new" :c3 "c3"}})
the child of the :c :c2 was lost

delaguardo14:03:32

look at the merge-with function. Also merge and merge-with functions doesn't work recursively

Alex Miller (Clojure team)14:03:16

Some utility libraries have deep-merge functions

quan xing01:03:44

Thanks @U04V4KLKC Which utillity libraries have deep-merge functions? @U064X3EF3

Patrick Brown03:03:30

Dude, deep-merge in https://weavejester.github.io/medley/medley.core.html is supremely perfect for your case. The whole library is the most useful utility functions around. I use it daily. As a beginner you can learn a ton from that code. It’s worth reading for it’s elegance.

stantheman10:03:19

Interesting. I used this as a challenge to write a deep-merge (fn my-deep-merge below). Then I saw the splendid deep-merge in @U04V4KLKC’s link (enc as deep-merge below). Now I am trying to work out how I could possibly produce that code in deep-merge ; clearly I have not got the where-withal!

slk50014:03:37

I'm little confuse with 'headings forms'. In e.g: (when test & body) (do exprs*) Is there any difference between '& body' and 'exprs*' ?'

delaguardo14:03:39

Where did you find them?

slk50014:03:29

in clj commands: (doc when) (doc do) or even here https://clojure.org/reference/special_forms#def

delaguardo14:03:49

yeah, not perfect. But there is no real difference between exprs* and & body . The former some sort of informal description inspired by regular expression and the later more how it is often written in the code.

slk50014:03:23

hmm a what about 'for': (for seq-exprs body-expr)

slk50015:03:16

As I understand there is some inconsistency in the use of the two styles: 1. some sort of informal description inspired by regular expression 2. how it is often written in the code But 'exprs*' and '& body' means exactly the same? @U064X3EF3 is creating the site https://clojure.org/reference/special_forms#def maybe he can say something more about it?

dgb2315:03:11

do and def are special forms. when is a macro that expects a test and than any number of expressions for can have any number of expressions before the body expression. (<-edit) The & can't be used for for here! It means "the rest of the parameters" so to speak.

Alex Miller (Clojure team)15:03:28

there is no difference between & body (a common macro arg list) and exprs* as a reference doc syntax expression

dgb2315:03:50

Oh.. I assumed & something is a variadic argument list

dgb2315:03:59

Right so there is a difference? You can't put it before a single argument?

dgb2315:03:22

Meaning for cannot use it for the binding expressions

Alex Miller (Clojure team)15:03:28

I don't know what we're talking about anymore

Alex Miller (Clojure team)15:03:22

are we talking about for specifically now?

dgb2315:03:29

I thought OP is confused about the specific difference between those parameter lists. But now I'm confused too!

Alex Miller (Clojure team)15:03:31

for takes a single body-expr

slk50015:03:49

let's stick with : "there is no difference between & body (a common macro arg list) and exprs* as a reference doc syntax expression" if there is no difference maybe would be better to just use one style

delaguardo15:03:09

the problem is connected with what is beeing printed when one called (doc ...)

(doc when)
-------------------------
clojure.core/when
([test & body])
Macro
  Evaluates test. If logical true, evaluates body in an implicit do.
and
(doc do)
-------------------------
do
  (do exprs*)
Special Form
  Evaluates the expressions in order and returns the value of
  the last. If no expressions are supplied, returns nil.

  Please see 
in the docstring for do there is informal description that uses exprs* to describe that do takes zero or more expressions and the docstring for when uses more formal & body

👍 2
Alex Miller (Clojure team)15:03:09

a lot of the special forms use the regex/bnf-ish syntax (see also let loop etc)

Alex Miller (Clojure team)15:03:13

some macros / special forms are effectively defining custom syntax and they use syntax style descriptive language

slk50015:03:07

I find it confusing. Should be one style regex or code format.

dgb2315:03:05

It seems quite consistent to me. The exprs* style comes up in doc strings and meta data to describe macros/special forms in compressed form.

dgb2315:03:27

It's not a 1:1 mapping to arg lists

delaguardo15:03:59

those are not a part of docstring btw. exprs* comes from :forms part of metadata and & body is from :arglists

delaguardo15:03:18

maybe the format of how doc prints could be more explicit for better explaining that difference

Alex Miller (Clojure team)15:03:45

we're not planning to make any changes in this area

slk50015:03:09

ok, but thanks for the clarification 🙂

skylize16:03:52

I am not 100% keeping up with the other explanations given. However, I see a pretty sharp grammatical usage difference when comparing the 2 examples from the original post.

(when test & body)
(do exprs*)
For when, you have a first argument test, followed by any number of additional arguments. Those additional arguments have a relation to test: being the "bodies" of expressions to be evaluated if test "passes". For do, you simply have any number of arbitrary expressions. There is no implication that any relation is inherent between any of those expressions or to anything else. Just 0+ expressions, and that's it. Despite noticing these differences, I'm not a huge fan of the choice of the singular body for when. I think bodies would be more honest naming. And exprs would be slightly less descriptive, but therefore also less prescriptive. (The one big plus here is that since body implies singular until you look closer, it discourages noobs from attempting to use when as a container for listing off a bunch imperative side-effects.) If it were up for debate (which Alex has clearly pointed out, it is not), I would vote to replace both exprs* and & body with & exprs, which is cleanly generic and unified, and leans on Clojure syntax instead of syntax imported from some unspecified grammar.

👍 2
Jakub Šťastný23:03:00

Hey guys, another noob question 🙂

(defn projection-table
  ([products channel duration] (projection-table products channel duration []))
  ([products {sales-forecasts :sales-forecasts} duration acc]
   (if (> duration 0)
     (recur products sales-forecasts (- duration 1)
            (conj acc (projection-from-forecast forecast products))))
   acc))
It fails with Can't recur here. It's CLJS, but I suppose that's irrelevant in this case. Why can't it recur? I know recur should be last? But I'm not sure what counts as last and how to change it? Like do I need to assign all the calculations in let first and then recur?

hiredman23:03:48

not last, but in the tail position

hiredman23:03:11

you missed a paren and have acc outside of the if

hiredman23:03:32

a function's body has an implicit do

hiredman23:03:47

and in a do the tail has to be in the last expression

Jakub Šťastný23:03:45

Ah stupid copy&paste 🙈

Jakub Šťastný23:03:01

I thought I was very off and it's actually working minus that copy&paste error.