Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added destructuring section to new-guidelines.md #18731

Merged
merged 16 commits into from
Mar 4, 2024

Conversation

nazariifenii
Copy link
Contributor

@nazariifenii nazariifenii commented Feb 6, 2024

Summary

Here's a quick PR to add a destructuring section to the new guidelines.

To review the rendered file, please, go to https://github.com/status-im/status-mobile/blob/251fccf7b6d3e00f7a5dc93ea70bbc76dc5433f1/doc/new-guidelines.md#default-value-when-destructuring.

Review notes

The guidelines should contain a section explaining the use cases of destructuring function parameters to improve code style.

status: ready

@status-github-bot status-github-bot bot added this to REVIEW in Pipeline for QA Feb 6, 2024
@status-im-auto
Copy link
Member

status-im-auto commented Feb 6, 2024

Jenkins Builds

Click to see older builds (32)
Commit #️⃣ Finished (UTC) Duration Platform Result
✔️ 251fccf #1 2024-02-06 12:17:54 ~6 min tests 📄log
✔️ 251fccf #1 2024-02-06 12:18:30 ~7 min ios 📱ipa 📲
✔️ 251fccf #1 2024-02-06 12:20:41 ~9 min android-e2e 🤖apk 📲
✔️ 251fccf #1 2024-02-06 12:20:48 ~9 min android 🤖apk 📲
✔️ 302c22f #3 2024-02-06 12:58:06 ~5 min tests 📄log
✔️ 302c22f #3 2024-02-06 12:58:22 ~5 min ios 📱ipa 📲
✔️ 302c22f #3 2024-02-06 12:59:29 ~6 min android 🤖apk 📲
✔️ 302c22f #3 2024-02-06 12:59:44 ~7 min android-e2e 🤖apk 📲
3e53c65 #7 2024-02-07 14:26:38 ~1 min android 📄log
✔️ 3e53c65 #7 2024-02-07 14:32:07 ~6 min tests 📄log
✔️ 3e53c65 #7 2024-02-07 14:32:58 ~7 min ios 📱ipa 📲
✔️ 3e53c65 #7 2024-02-07 14:34:32 ~9 min android-e2e 🤖apk 📲
24a143e #8 2024-02-07 14:43:35 ~3 min android 📄log
✔️ 24a143e #8 2024-02-07 14:46:06 ~6 min ios 📱ipa 📲
✔️ 24a143e #8 2024-02-07 14:49:45 ~9 min tests 📄log
✔️ 24a143e #8 2024-02-07 14:50:45 ~10 min android-e2e 🤖apk 📲
✔️ eaa0bbf #9 2024-02-09 10:49:40 ~7 min android 🤖apk 📲
✔️ eaa0bbf #9 2024-02-09 10:51:08 ~5 min tests 📄log
✔️ eaa0bbf #9 2024-02-09 10:52:24 ~6 min ios 📱ipa 📲
✔️ eaa0bbf #9 2024-02-09 10:53:44 ~7 min android-e2e 🤖apk 📲
✔️ 1b53df9 #11 2024-02-22 08:05:49 ~5 min tests 📄log
✔️ 1b53df9 #11 2024-02-22 08:07:15 ~7 min android 🤖apk 📲
✔️ 1b53df9 #11 2024-02-22 08:07:25 ~7 min ios 📱ipa 📲
✔️ 1b53df9 #11 2024-02-22 08:08:00 ~7 min android-e2e 🤖apk 📲
✔️ 67e8dcf #12 2024-02-22 08:17:27 ~5 min tests 📄log
✔️ 67e8dcf #12 2024-02-22 08:19:24 ~7 min ios 📱ipa 📲
✔️ 67e8dcf #12 2024-02-22 08:20:00 ~8 min android-e2e 🤖apk 📲
✔️ 67e8dcf #12 2024-02-22 08:20:15 ~8 min android 🤖apk 📲
✔️ 580f56e #13 2024-02-26 12:24:02 ~5 min tests 📄log
✔️ 580f56e #13 2024-02-26 12:24:50 ~6 min android 🤖apk 📲
✔️ 580f56e #13 2024-02-26 12:26:04 ~8 min android-e2e 🤖apk 📲
✔️ 580f56e #13 2024-02-26 12:29:26 ~11 min ios 📱ipa 📲
Commit #️⃣ Finished (UTC) Duration Platform Result
✔️ b9997d3 #14 2024-03-01 18:56:41 ~7 min android-e2e 🤖apk 📲
✔️ b9997d3 #14 2024-03-01 18:56:47 ~7 min android 🤖apk 📲
✔️ b9997d3 #14 2024-03-01 19:01:07 ~12 min ios 📱ipa 📲
✔️ f12d0c5 #15 2024-03-04 14:16:49 ~7 min tests 📄log
✔️ f12d0c5 #15 2024-03-04 14:18:12 ~8 min android-e2e 🤖apk 📲
✔️ f12d0c5 #15 2024-03-04 14:18:18 ~8 min android 🤖apk 📲
✔️ f12d0c5 #15 2024-03-04 14:19:06 ~9 min ios 📱ipa 📲

Comment on lines 79 to 100
Too often callers pass nil values because values can be wrapped in a `when` for example.
In this case, the default value is not applied, because :or macro will use default only when the value is absent.
Instead, use `(or value some-default-value)` in a `let` expression or as a parameter value.

```clojure
;; bad (unreliable)
(defn- view-internal
[{:keys [auto-focus?
init-value
return-key-type]
:or {auto-focus? false
init-value 0
return-key-type :done}}])

;; good
(defn- view-internal
[{:keys [auto-focus?
init-value
return-key-type]}])
(let [auto-focus? (or auto-focus? false)
init-value (or init-value 0)
return-key-type (or return-key-type :done)])
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't fully agree with this approach.

I understand the problems it's creating, but it doesn't look clean, we are also suggesting to shadow vars.

I think this technique should be followed only sometimes, when needed, but these guidelines are thought to be applied everywhere and the code will become (even) more verbose.

to avoid the shadowing, I see cleaner:

(defn view [{default-auto-focus? :auto-focus?
             default-init-value  :init-value}]
  (let [auto-focus? (or default-auto-focus? 20)
        init-value? (or default-init-value 0)]))

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice suggestion @ulisesmac. I prefer that way too without shadowing.

I think this technique should be followed only sometimes, when needed, but these guidelines are thought to be applied everywhere and the code will become (even) more verbose.

I agree with you. I think we should adjust the wording in the guidelines. Not all guidelines should be followed 100% of the time. This one I think should be considered by all developers. I personally try to never rely on default destructuring in quo components. Too often I've seen arguments been passed as nil. And I believe a good proportion of the dev team doesn't know nil will overrule default destructured values.

Even with Malli it doesn't help much because we're defining schemas for components with heavy usage of the :maybe schema, so nils can still flow in.

Searching by usages of :or, I see many have fragile code, waiting to cause small UI bugs or even exceptions, like here (if :size is passed as nil an exception will be thrown)

:or {size 24}}]
[base-tag/base-tag
{:accessibility-label accessibility-label
:background-color background-color
:size size
:type :permission
:on-press on-press}
[rn/view
{:flex-direction :row
:align-items :center
:justify-content :flex-end}
[rn/view
{:padding-left (case 32
8 24
6)

Maybe this guideline should be considered mostly for quo components? So it could be moved to quo/README.md.

Copy link
Contributor

@ulisesmac ulisesmac Feb 6, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe this guideline should be considered mostly for quo components?

Yeah, that and fix the wording will make it better :)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've moved the guideline to the quo/Readme.md, please, take a look.

Also, I don't prefer the naming with the default- prefix, as the actual default will be the second prop to or fn, ex. 20 in (or default-auto-focus? 20). For me, the better naming can be smthng like param-auto-focus? or external-auto-focus?. Probably, shorter is better.

Comment on lines 127 to 129
[{:keys [{default-auto-focus? :auto-focus?
default-init-value :init-value
default-return-key-type :return-key-type}]}])
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This might be wrong actually. It should be without :keys, so just:

(defn- view-internal
   [{default-auto-focus?     :auto-focus?
     default-init-value      :init-value
     default-return-key-type :return-key-type}]}])

We'd have to do this for all props, even ones that have no default values, so using this might be too verbose. Is avoiding shadowing them worth it @ulisesmac @ilmotta?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe it's better to not use destructuring for props that have default values e.g.

(defn- view-internal
   [{:keys [theme size something] :as props}]
   (let [auto-focus? (or (:auto-focus? props) false)]
     ...)}])

Copy link
Contributor

@ulisesmac ulisesmac Feb 13, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey @clauxx

We'd have to do this for all props, even ones that have no default values

We can mix destructuring sintax, so we can use {a :a} and {:keys [x]} together., but honestly, I prefer to have only one style.

I like your idea @clauxx, destructuring doesn't look dirty, we avoid shadowing vars and no need to names prefixed with default- 👍

And yeah, the guideline is wrong about the use of :keys

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shadowing arguments requiring default values in a top-level let form is harmless and quite common in Clojure code I have seen. But I can totally live with the final suggestion to avoid destructuring when there are default values, that's good too, maybe better 👍🏼

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ilmotta, @ulisesmac, @clauxx, I've updated the PR according to the discussion, please, review it

Copy link
Contributor

@ilmotta ilmotta left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM with the latest changes based on our discussions. Thanks @nazariifenii!

@nazariifenii
Copy link
Contributor Author

LGTM with the latest changes based on our discussions. Thanks @nazariifenii!

@ilmotta, could you please take care of merging the PR, because it seems like I don't have access to do that.

@ilmotta
Copy link
Contributor

ilmotta commented Mar 1, 2024

LGTM with the latest changes based on our discussions. Thanks @nazariifenii!

@ilmotta, could you please take care of merging the PR, because it seems like I don't have access to do that.

Sure @nazariifenii. I'm sorry you have to do this again, but could you rebase against develop? I'll merge right away.

@ilmotta
Copy link
Contributor

ilmotta commented Mar 1, 2024

@nazariifenii, the build failed for reasons unrelated to your PR. Other PRs are having the same problem. For now, I think the best is to wait and we can try to merge it next Monday.

@ilmotta
Copy link
Contributor

ilmotta commented Mar 4, 2024

Hey @nazariifenii, the pipeline seems to be stable enough. Could you rebase again, please? Thanks!

@nazariifenii
Copy link
Contributor Author

Done, @ilmotta, thanks for monitoring!

@ilmotta ilmotta merged commit fcdd6c5 into status-im:develop Mar 4, 2024
5 checks passed
Pipeline for QA automation moved this from REVIEW to DONE Mar 4, 2024
@nazariifenii nazariifenii deleted the update-guidelines branch March 4, 2024 14:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Archived in project
Development

Successfully merging this pull request may close these issues.

None yet

6 participants