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

Resolving variable ambiguity #151

Open
prevwong opened this issue Mar 8, 2024 · 0 comments
Open

Resolving variable ambiguity #151

prevwong opened this issue Mar 8, 2024 · 0 comments

Comments

@prevwong
Copy link
Owner

prevwong commented Mar 8, 2024

Overview

Currently, Reka resolve variables by their names and scope:

{
  type: "Program",
  globals: [ { type: "Val", name: "counter", ... }
  components: [
    {
      type: "RekaComponent", 
      name: "App", 
      state: [ { type: "Val", name: "counter", ... }
      template: {
	type: "TagTemplate",
        tag: "text",
        props: { 
	  "value": { 
	      type: "Identifier",
	      name: "counter" // refers to the state variable
	   } 
        },
      }
    }
  ]
}

In the above example, the counter variable used as prop refers the counter state variable in the App component, rather than the global variable. This design is simple and straightforward and it's based on what programmers typically expect when writing code.

However, this does make referencing the global counter variable impossible. More importantly, when building a page editor — the names of these variables are going to be defined by users and chances are we’re going to need to build some user friendly UI (ie: a dropdown to list variables). In which case, having variables to be resolved by names and scopes is going to cause a lot of confusion.


Removing ambiguity in the State

To solve this, we need a more explicit way to resolve variables. We can achieve this by requiring identifiers to specify the id of the variable explicitly:

{
  type: "Program",
  globals: [ { id: "hhghak1", type: "Val", name: "counter", ... }
  components: [
    {
      type: "RekaComponent", 
      name: "App", 
      state: [ { id: "kbamk10", type: "Val", name: "counter", ... }
      template: {
	type: "TagTemplate",
        tag: "text",
        props: { 
	   "value": { 
		type: "Identifier",
		ref: "hhghak1" // refers to the global variable
	    } 
        },
      }
    }
  ]
}

Parser

To support this change, we will need to make some changes to the Parser as well. An easy way to achieve a non-ambiguous to require identifiers to specify the “path” of the variable they are referencing:

val counter = 0;

component App() {
  val counter = 1;
} => (
  <text value={$state.counter} />
)

Here, $state.counter explicitly specifies that we’re referencing the state variable. Similarly we can allow the following:

  • $counter to reference a global counter variable
  • $prop.counter to reference a prop counter variable

One other place where we need to take care of this is in templates with the @each directive. Currently consumers can create a variable to reference each item in the iterator:

<div @each={item in [1,2,3]}>
   <div @each={item in [1,2,3]}>
	<text value={item} /> // item refers to the nested item 
   </div>
</div>

In this case, it is also impossible to reference the outer iterators item using our existing model. Using the same solution with the counter example, we can do the following:

<div @each={item in [1,2,3]}>
   <div @each={item in [1,2,3]}>
       <text value={$each.0.item} /> // item refers to the outer item 
   </div>
</div>
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

1 participant