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

Shorthand for specifying objects with keys and values from current scope #522

Open
ekimekim opened this issue May 26, 2018 · 4 comments
Open

Comments

@ekimekim
Copy link

ekimekim commented May 26, 2018

I find myself having to frequently write things like:

  {foo: foo, bar: bar, baz: baz}

ie. an object that takes some local variable, and includes it under the same name.

I'd like to propose a sugar for this which does {foo} -> {foo: foo}.
ie. the above example would become {foo, bar, baz}.

This is similar in spirit to jq's syntax for this, where {foo} -> {foo: .foo}.

@seh
Copy link

seh commented Jun 16, 2018

It would help to see the larger context for code like this.

This shorthand would encourage choosing names for variables that are likely to match field names, which is an unusal pressure to exert. That is, "Choose your names well and you can avoid some typing," but the field names may be of someone else's choosing, so we're either penalizing abstraction (use of different names) or rewarding adoption (using other peoples' field names for our variable names).

It's also an unusal punning technique. As I understand it, today in Jsonnet you can get the names of an object's fields as strings, but you can't convert a string to symbol for variable binding lookup. Hence, I don't think you can implement this transformation yourself in Jsonnet.

@ekimekim
Copy link
Author

The context in which it comes up the most is complex string formatting:

|||
  A long and complex string involving things about %(foo)s, such as how %(foo)s has %(things)d things,
  and is associated with %(bar)s. Note how I refer to %(foo)s many times,
  making the object-based formatting more practical than array-based.
||| % {foo: foo, bar: bar, things: things}

Indeed, a significant portion of my use-cases for this would equally be served by a ruby-like interpolation syntax where arbitrary expressions can be specified in the format string, though I realise that's a more drastic change.

To take a real world example: We use jsonnet to define grafana dashboards for a prometheus query backend. I wanted to create a generic function for defining a graph that takes some histogram metric, and returns a graph showing the 50th, 90th and 99th percentiles.
So I have variables metric and labels (the prometheus labels to match on) passed in as function args, and I use a list comprehension to define one query per quantile value [0.5, 0.9, 0.99], and because some of my users expressed a desire to customise the time range my rate()s are taken over, I end up passing a timespec (like 5m) in to the function as well.

Then my query expression looks like this:

|||
  histogram_quantile(%(quantile).2f,
    sum(
      rate(%(metric)s_bucket{%(labels)s}[%(timespec)s])
    ) by (le)
  )
||| % {quantile: quantile, metric: metric, labels: labels, timespec: timespec}

Under my proposal, the last line would become:

||| % {quantile, metric, labels, timespec}

This is admittedly only a minor hassle, a small piece of syntactic sugar. I understand if it's deemed not worth the extra complexity and amount of language features to learn.

@sparkprime
Copy link
Contributor

re: ruby style intepolation, there was this request #45 which is just as much work now as it was then

@sparkprime
Copy link
Contributor

Javascript allows what you're asking for:

foo = "1"
bar = "2"
{ foo, bar } == {foo: "1", bar: "2"}

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

No branches or pull requests

4 participants