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

No/Limited Destructuring #39

Open
jamiebuilds opened this issue Aug 26, 2019 · 1 comment
Open

No/Limited Destructuring #39

jamiebuilds opened this issue Aug 26, 2019 · 1 comment

Comments

@jamiebuilds
Copy link
Owner

jamiebuilds commented Aug 26, 2019

Destructuring has been part of my design for Ghost for a really long time. But I've come to avoid destructuring in my JavaScript code, and I'm actually starting to think it's a bad language feature.

For the record, I think destructuring is fine in the simple case:

let { name, followerCount } = user
let str = "{name} ({followerCount}"

Although, I kinda think it's better to just write it out like:

let str = "{user.name} ({user.followerCount}"

But people take it to an uncomfortable extreme:

let {
  propertyOne = false,
  propertyTwo = null,
  propertyThree as someThing,
  propertyFour: {
    nestedProperty: {
      anotherNestedPropertyA as a = defaultValue,
      anotherNestedPropertyB as b
    } = {}
  } = {}
} = props

I've seen destructuring code 4-5x longer than this too.

It's not great on it's own, but it gets much much worse when you have references to destructured values all over the place and have no idea where any of them came from.

let {
  propertyOne = false,
  propertyTwo = null,
  propertyThree as someThing,
  propertyFour: {
    nestedProperty: {
      anotherNestedPropertyA as a = defaultValue,
      anotherNestedPropertyB as b
    } = {}
  } = {}
} = props

# ...100 lines later...

doSomething(a, b) # ... where the heck did `a` and `b` come from?

Sure it's easy enough to "click to definition", but it's not a great experience to jump back and forth in the same file over and over many times.

It's much better to read things like:

fn(entity.field, otherEntity.anotherField) 

I think this comes down to "thinking in entities", which is an aspect of more object-oriented-style programming that I actually like a lot. I think it's good when people define their data structures clearly.

I think that destructuring encourages people to throw out their data structures and merge them into giant records that contain every little piece of data you would want.

# Bad: What is any of this data supposed to be?
let f = fn ({ id, name, setting1, setting2 }) {
  # ...
}

# Good: More clear about where this data should be coming from.
let f = fn (user, userSettings) {
  # ...
}

As a result of this, I would like to either remove destructuring from Ghost or severely limit it in the syntax.

I'm 90% sure I don't want to allow destructuring in function parameter lists (It's kind of weird that you'd want to considering Ghost has named parameters):

let f = fn ({ value, otherValue }) {
  # ...
}

I'm 90% sure I don't want to allow nested destructuring:

let { nested: { value } } = obj

I think I do want to keep destructuring for imports and for variable initializers:

import Math as { sin, cos, tan }
let { one, two, three } = rec

I'm not sure if I would want to keep features like defaults, spread, or renaming. Allowing one seems to necessitate the others, and spread seems valuable enough to keep. Part of me wants to keep them out of Ghost so that destructuring has limited usefulness, but I don't want to make them totally unusable.

let { value = 42 } = obj
let { value, ...rest } = obj
let { value as other } = obj
@SCKelemen
Copy link

I think out of these changes, the only thing I would miss is spread. I think spread is very useful, and it's helpful for builder patterns, cloning, etc. Nested destructuring is a beast. I think I would like to keep simple destructuring but nested and renaming have never been that useful to me, and I would suspect the burden of supporting those features combined with the possibility of foot-gunning yourself in the future, would be sufficient reason to avoid it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants