Skip to content

[Feature Request Runes] Change $derived() to accept a function with a return value #9250

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

Closed
D-Marc1 opened this issue Sep 23, 2023 · 8 comments

Comments

@D-Marc1
Copy link

D-Marc1 commented Sep 23, 2023

Describe the problem

While $derived() is a welcomed Rune addition, I don't quite understand why it has a confusing syntax of:

const area = $derived(width * height)

Multi line code ends up adding way too much noise too, as it requires an IIFE:

const area = $derived((() => {
  return width * height
})())

Describe the proposed solution

It would be much more idiomatic in JavaScript for it to accept a function with a return value, so:

const area = $derived(() => width * height)

This is also more flexible for multiline code:

const area = $derived(() => {
  return width * height
})

Alternatives considered

There's no alternative in Runes that I'm aware of.

Importance

would make my life easier

@D-Marc1 D-Marc1 changed the title Change $derived() to accept a function with a return value [Feature Request Runes] Change $derived() to accept a function with a return value Sep 23, 2023
@brunnerh
Copy link
Member

I get where you are coming from, but runes already add so much noise to components that I personally would rather keep it as is.

@Conduitry
Copy link
Member

$derived(...) was chosen over $derived(() => ...) for just that reason - it's several fewer characters which do not serve any purpose. The current syntax is admittedly slightly less nice in the uncommon when you need to write some multi-line code, because you then need to write an immediately-invoked function expression, but when do expressions eventually land, we want to be ready for that as well by having a syntax that lets us take advantage of that.

@Conduitry Conduitry closed this as not planned Won't fix, can't repro, duplicate, stale Sep 23, 2023
@D-Marc1
Copy link
Author

D-Marc1 commented Sep 23, 2023

@Conduitry, I'm surprised why this feature request was shut down so quickly, without much consideration.

So the justification for keeping this unnatural and less flexible syntax is that even though $derived(width * height) is clearly unnatural to a JavaScript user, compared to $derived(() => width * height), and requires an IIFE for multiline code, you believe it's worth it because you save a few characters on a single line, and that a stage 1 proposal, do expressions, could help mitigate multiline ugliness?

I would appreciate it if my proposal could at least be given some consideration, rather than just being abruptly closed.

With a returned function as the argument, multiline code becomes incredibly easy and idiomatic to already do in JavaScript.

let price = $state(23)
let taxRate = $state(0.06)

const totalPrice = $derived(() => {
  const tax = price * taxRate
  
  return price + tax
})

@PP-Tom
Copy link

PP-Tom commented Sep 24, 2023

@Conduitry, I'm surprised why this feature request was shut down so quickly, without much consideration.

So the justification for keeping this unnatural and less flexible syntax is that even though $derived(width * height) is clearly unnatural to a JavaScript user, compared to $derived(() => width * height), and requires an IIFE for multiline code, you believe it's worth it because you save a few characters on a single line, and that a stage 1 proposal, do expressions, could help mitigate multiline ugliness?

I would appreciate it if my proposal could at least be given some consideration, rather than just being abruptly closed.

With a returned function as the argument, multiline code becomes incredibly easy and idiomatic to already do in JavaScript.

let price = $state(23)
let taxRate = $state(0.06)

const totalPrice = $derived(() => {
  const tax = price * taxRate
  
  return price + tax
})

I actually think this is a great argument to why it should also accept a function. Otherwise you would have to use another state and effect to update that state, if I’m understanding Svelte 5 correctly. While I understand this is how you would have done it in Svelte 4, I think that would be one of the many benefits of moving to signals.

I know you can do $derived(price + (price * taxRate)) but I’m sure there will be instances where this would be useful.

@intrnl
Copy link

intrnl commented Sep 26, 2023

Tradeoff: why not a separate $computed rune that accepts a function? I'm more on the function side because it doesn't seem right to be doing this instead, which adds a lot of noise the moment you go beyond simple derivations

const computeX = () => {
  // ....
};

const x = $derived(computeX());

I suppose Svelte could have some optimizations here to prevent generating this code:

// Why not just (computeX) directly?
const x = $.derived(() => computeX());

@brunnerh
Copy link
Member

@intrnl You can inline the function and call it directly, this adds a few parentheses but probably does not warrant adding a separate rune.

const x = $derived((() => {
  // ...
})());

@D-Marc1
Copy link
Author

D-Marc1 commented Sep 29, 2023

@brunnerh, but the current $derived implementation adds way more noise and requires more thinking than if it were simply:

// Single line
const area = $derived(() => width * height)

// Multi line
const area = $derived(() => {
  return width * height
})

The previous example is much more consistent, predictable and idiomatic than the current $derived implementation of:

// Single line
const area = $derived(width * height)

// Multi line
const area = $derived((() => {
  return width * height
})())

@intrnl
Copy link

intrnl commented Sep 29, 2023

Yeah, I think the added () => for simple derivations is worth it given that derivations aren't always for simple stuff, and it seems weird to limit itself to that
(which yes, can be solved with an IIFE, but also adds a bunch of noise and I'd say it's still a limiting factor, as if it wasn't intended to be that way)

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

5 participants