# Let / Const / Set / Global

Pulsar comes with  **full support for scoped variables** exactly as you know them from other languages. This means you can define a variable within a specific scope, mutate it (or create one that is immutable), and read its value.&#x20;

Similar to dynamically typed languages, variables are not constrained to specific data types, and as such, there are no type definitions when you declare them.

Variable flows don't define a body, and shorthand flow syntax is recommended.

### Let

`let` flow allows you to define a variable within the current scope:

```
{* Declaring variable *}
{[ let dogName = "Rex" /]}
{{ dogName }} // Rex
```

**Variables declared with `let` are mutable,** meaning you can change their value inside the same scope they were defined at. When you try to re-define a variable that was already defined, an error is thrown.&#x20;

### Const

`const` flow allows you to define a variable within the current scope:

```
{* Declaring variable *}
{[ const dogName = "Rex" /]}
{{ dogName }}                 // Rex
```

**Variables declared with `const` are immutable,** meaning you can't change their value inside the same scope they were defined at. When you try to re-define a variable that was already defined, an error is thrown. When you try to mutate this variable, an error is thrown as well.

### Set

`set` flow allows you to modify a variable defined using `let` flow:

```
{* Declaring variable *}
{[ let dogName = "Rex" /]}
{{ dogName }}                // Rex

{* Mutating variable *}
{[ set dogName = "T-Rex" /]}
{{ dogName }}                // T-Rex
```

Only variables declared as mutable (`let`) can be mutated, otherwise, an error is thrown. Also, `set` expects variable to be already defined in the current scope, and it can't define new variables.

You can also use shorthand `set` as you would in other languages:

```
{* Declaring variable *}
{[ let dogName = "Rex" /]}
{{ dogName }}              // Rex

{* Mutating variable *}
{[ dogName = "T-Rex" /]}   // Note the missing "set"
{{ dogName }}              // T-Rex
```

### Global

Variables defined with `global` flow are always defined at the top-most scope, regardless of the scope used to execute this definition. This makes them available to any executed code as soon as they are defined:

```
{[ if true ]}
   {[ global variableInsideBody = "Text" /]}
   {{ variableInsideBody }}            // Properly executes
{[/]}

{{ variableInsideBody }}               // Also properly executes
```

**Variables declared with `global` are immutable**. The purpose behind this flow is to use it for variables that are needed throughout a blueprint, everywhere, and are constants. A good use for `global` flow are configuration values:

```
{[ global mySettings = "1.0" /]}
{[ global myOtherSettings = "abcdefgh" /]}
```

When defined, you can use them anywhere from that point onwards.

{% hint style="warning" %}
Global variables are not the same as in some languages where they are available to all scripts that run. In Pulsar, globals are only available within a specific blueprint that defined them. If you want to define variables that span the entire execution, [refer to our javascript guide](https://supernova-developers.gitbook.io/supernova-dsm/building-exporters/creating-new-exporter/using-javascript) to learn how to define a custom payload.
{% endhint %}

### Scopes

Variables (with the exception of those defined using `global`) are always created within the executed scope. Take the following example:

```
{[ if trueOrFalse ]}
   {[ const variableInsideBody = "Text" /]}
   {{ variableInsideBody }}              // Properly executes
{[/]}

{{ variableInsideBody }}                 // Throws error
```

Since variables are scoped (and `for` flow creates a new variable within its body/scope), the substitution will fail because the variable was defined inside another body, out of scope.

Parent/child scopes are supported as well. Take this example:

```
{[ if trueOrFalse ]}
   {[ const variableInsideBody = "Text" /]}
   {{ variableInsideBody }}             // Properly executes
   {[ for number in numbers ]}
      {{ variableInsideBody }}          // Properly executes as well
   {[/]}
{[/]}

{{ variableInsideBody }}                // Throws error
```

Because `for` loop is inside the scope that was used to define `variableInsideBody` , we can use any property that was defined in parent scopes as well.

**Null support**

Null or empty values are handled gracefully, but most [transformers](https://supernova-developers.gitbook.io/supernova-dsm/pulsar-language/transformers) consider them an error. You can check for whether a value is null by using `@isNull(variable)` [function](https://supernova-developers.gitbook.io/supernova-dsm/pulsar-language/functions).
