eww icon indicating copy to clipboard operation
eww copied to clipboard

[FEATURE] Let-in syntax in simplexpr

Open elkowar opened this issue 3 years ago • 4 comments

Description of the requested feature

The more complexity simplexpr allows for, the more use there would be for variables within expressions. Given #324, it might make sense to try and come up with some unified syntax or principle for this, although having separate syntax in simplexpr might not be an issue, either. Alternatively, it could be stated that it'd make sense to just rely on the local variables requested in #324, and have separate expressions.

However, I could still see having let-in syntax for simplexpr explicitly be a worthwhile addition.

Proposed configuration syntax

let foo = "hi"; bar = "ho"; in foo + bar

let
  foo = "hi"
  bar = "ho"
in
  foo + bar

(not sure about newline sensitive stuff here, not really a fan :/

Additional context

One alternative to this has been proposed with the with function in #407

elkowar avatar Feb 24 '22 12:02 elkowar

The with function from #407 works as follows:

  • with(name, value, expression): Evaluate the simple expression (which must be a string), where the variable name has value value

Example:

with('a', '{"0": "hello ", "1": "world"}', 'a[0] + a[1]')
hello world

That implementation can be found here: https://github.com/MartinJM/eww/commit/a4e2095a8a6d50dab28cd69681fe2eb818e15226


I do have a question about the let-in syntax: What would the scope of the variable be? The first expression after the in, or all expressions until the end?

If I may also add my own opinions:

If (Simplexpr) variables are not supported in local variables, I think it would make sense to have a different syntax. If the syntax is the same, I think it will lead people to believe that the functionality is the same as well.

I'm personally also not really a fan of newline-based stuff. But besides that, I think that newlines in a Simplexpr aren't really supported at the moment? At least, I haven't found a way to have them in a Simplexpr.

MartinJM avatar Feb 24 '22 14:02 MartinJM

Would it make sense to instead follow what ml does here with

let
  ; reserved keywords let you know where the next def starts, and what part is a name
  val a = someValDef
  val b = someValDefAgain
in
  ; some expr using a & b
end ; clear closing here

oldwomanjosiah avatar Apr 17 '22 05:04 oldwomanjosiah

Is the in really necessary ? Can't we just have the variables be implicitly scoped to the whole expression ? Also for the newlines, maybe just add a end delimiter like a coma ?

let a = valOrExpr, a + 1 ; Or any other expression that uses a

viandoxdev avatar Apr 18 '22 08:04 viandoxdev

Is the in really necessary ? Can't we just have the variables be implicitly scoped to the whole expression ? Also for the newlines, maybe just add a end delimiter like a coma ?

let a = valOrExpr, a + 1 ; Or any other expression that uses a

I would say that while in isn't strictly necessary, it decreases the cognitive and implementation overhead of the feature. On the cognitive side, I would much prefer to have a clear delimitation between definition list and use.

For instance, how would you go about telling a new user that while this is allowed

let
  len = length(list)
  first = list[0]
  len == 1 ? first : "${first} of ${len}
end

this is not

let
  len = length(list)
  len == 0 ? "Nothing" :
    first = list[0]
    len == 1 ? "${first}" : "${first} of ${len}

you would probably get some "not in definition scope" error at line 4, but it would be unclear why (especially if a user hasn't used this specific functional construct before).

let
  val len = length(list)
in
  len == 0 ? "nothing" : 
    ; The def scope has clearly ended, so writing this is clearly incorrect as it does not have a scope
    first = list[0]
    len == 1 ? "${first}" : "${first} of ${len}
end

oldwomanjosiah avatar Apr 19 '22 05:04 oldwomanjosiah