Entries

Entries are key-value pairs that exist in the scope where they are declared.

Naming

Entry names (keys) cannot start with an uppercase letter, which is the distinction compared to types. Identifiers are case-sensitive, so "frenchfries" and "frenchFries" would be considered different entries.

The recommended convention is to use camelCase for entries.

you may use an arbitrary name as key by using dynamic nomination

Declaration and assignment

In FatScript, you can declare entries by simply assigning a value:

isOnline: Boolean = true
age: Number       = 25
name: Text        = 'John'

Types can also be inferred from assignment:

isOnline = true    # Boolean
age      = 25      # Number
name     = 'John'  # Text

Immutable entries

In FatScript, declaring an entry defaults it to being immutable, meaning once assigned, its value cannot be changed. This immutability ensures consistency throughout the program's execution:

fruit = 'banana'
fruit = 'apple'  # raises an error because 'fruit' is immutable

Exception to the Rule

The immutability in FatScript applies to the binding of the entry, not to the contents of scopes. Even though an entry is immutable, if it contains a scope, the content of that scope can be modified, either by adding new entries or by modifying mutable entries within the scope:

s = { a = 1, b = 2 }
s.c = 3  # even though 's' is immutable it accepts the new value of 'c'
s        # now { a = 1, b = 2, c = 3 }

This design choice offers flexibility with scope modifications. In contrast, lists enforce stricter immutability, preventing the addition of new entries to immutable lists.

Also note that scopes are always passed by reference. To modify a scope's content without altering its original reference, use the copy method from the Scope prototype extension to create a duplicate.

Mutable entries

Yes, you can declare mutable entries, also known as variables. To declare a mutable entry, use the tilde ~ operator:

~ fruit = 'banana'
fruit   = 'apple'  # ok

Note that even a mutable entry cannot immediately change its type, unless it's erased from the scope. To erase an entry, assign null to it, and then redeclare it with a new type. Changing types is discouraged by the syntax and not recommended, but it is possible:

~ color = 32    # creates color as a mutable Number entry
color = 'blue'  # raises a TypeError because color is a Number
color = null    # entry is erased
color = 'blue'  # redefines color with a different type (Text)

you have to declare the entry as mutable again using tilde ~ when redefining after erasure if you want the next value to be mutable

Dynamic entries

You can create entries with dynamic names using square brackets [ ref ]:

ref = 'popCorn'  # text will be the name of the entry

options = { [ ref ] = 'is tasty' }

options.[ref]    # dynamic syntax: yields 'is tasty', with read and write access
options(ref)     # get syntax:     yields 'is tasty', but value is read-only
options.popCorn  # dot syntax:     yields 'is tasty', but has to follow naming rules

all dynamic declarations are mutable entries

This feature allows to dynamically define the names inside a scope and create entries with names that otherwise would not be accepted by FatScript.

Dynamic entries can also use numeric references, however the reference is converted into text automatically, e.g.:

[ 5 ] = 'text stored in entry 5'
self.['5']                      # yields 'text stored in entry 5'
self.[5]                        # yields 'text stored in entry 5'

in a different context, not followed by assignment = or preceded by dot notation ., dynamic syntax will be interpreted as a list declaration

Special entries

Entries with names starting with underscore _ are completely free and dynamic, they don't require tilde ~ and can also change type without the need of erasure, like variables in JavaScript or Python.

Destructuring assignment

You can copy values of a scope into another scope like so:

_ <- fat.math
distance = (position: Scope/Number): Number -> {
  { x, y } = position    # destructuring assignment into method scope
  sqrt(x ** 2 + y ** 2)  # calculates distance between origin and (x, y)
}
distance({ x = 3, y = 5 })  # 5.83095189485

The same syntax works similarly for lists:

distance = (position: List/Number): Number -> {
  { x, y } = position    # extracts first and second items to 'x' and 'y'
  sqrt(x ** 2 + y ** 2)
}
distance([ 3, 5 ])  # 5.83095189485

You can also use destructuring assignment to expose a certain method or property from a named import:

console <- fat.console
{ log } = console
log('Hello World')

using this syntax with imports, you can choose to bring to the current scope only the elements of the library that you are interested in using, thus avoiding polluting the namespace with names that would otherwise have no use or could clash with those of your own writing

JSON-like syntax

FatScript also supports JSON-like syntax for declaring entries:

"nothing": null,                # Void entry - distinct behavior, see bellow
"isOnline": true,               # Boolean entry
"age": 25,                      # Number entry
"name": "John",                 # Text entry
"tags": [ "a", "b" ],           # List entry
"options": { "prop": "other" }  # Scope entry

However it might appear that declaring "nothing" creates a "nothing" value of null, it's important to note that the "resulting entry" doesn't actually exist in the scope. When you try to access that "nothing", FatScript does return null, but if you attempt to map over the scope, the name of that entry will be missing since it was never truly created.

It's important to note that JSON-like declarations always create immutable entries, so you can't prepend them with the tilde ~ character to make them mutable.

results matching ""

    No results matching ""