# Dictionaries

Dictrionaries are maps from keys to values. We designed the syntax closely to JSON. **Note that entries are are given by reference** (like geometric objects).

###  Elementary Dictionary Operations

**Description:**
Without arguments, this creates an empty dictionary.

    > {}
    < {}

------

### Creating a simple dictionary: `{"key" : val, ...}`

**Description:**
The expression `{"key1" : val, ...}` created a basic dictionary. 

    > {"a" : 1, "b" : 2};
    < {a:1, b:2}

------

### Printing a dictionary

**Description:**
As usual the function `print` will output the object. This will generally be not a valid JSON object, since CindyJS uses different data types than JavaScript.

    > print({"a" : 1, "b" : false, "c": "mystring"});
    * {a:1, b:false, c:mystring}

**Circular Dictionaries**
Circular objects are allowed, but a printout will be shortened. The default recursion depth is 1000 but can be adjusted with the modifier `maxDepth`:

    > dic={"a" : 1}; dic.b = dic; print(dic, maxDepth->3);
    * Warning: We visited a key-value pair very often or encountered a very deeply nested dictionary. Dictionary is probably cyclic. Output will be probably incomplete.
    * {a:1, b:{a:1, b:{a:1, b:{a:..., b:...}}}}


------

### Accessing Elements of Lists: `‹dict›.name`

**Description:**
Basic (static) access is possible via the dot operator. The variable after the dot is **not** evaluated.

    > json = {"a" : 1, "b" : 2};
    > json.a
    < 1

------
### Retrieving all keys and values of a dictionary: `keys(‹dict›)` and `values(‹dict›)`

**Description:**
To retrieve all keys or values of a dictionary as a list one can use `keys(‹dict›)` and `values(‹dict›)`


    > json = {"a" : 1, "b" : 2};
    > keys(json);
    < ["a", "b"]
    > values(json);
    < [1, 2]

------

### Dynamically accessing Elements of Lists: `‹dict›_‹var›` and `take(‹dict›,‹var›)`

**Description:**
One can dynamically access the individual elements of a dict either with the infix operator `‹list›_‹var›` or the functional operator `take(‹list›,‹var›)`. The keys (`var`) can be of any printable type.


    > json = {"a" : 1, "b" : 2};
    > json_"a"
    < 1
    > take({"a" : 1, "b" : 2}, "b")
    < 2

------

### Applying an expression: `apply(‹dict›,‹expr›)`

**Description:**
This operator generates a new list by applying the operation `‹expr›` to all elements of a dict (but not to the keys) and collecting the results.
As usual, `#` is the run variable, which successively takes the value of each element in the list.

    > apply({"a" : 1, "b" : 2}, #^2);
    < {a:1, b:4}

------

### Applying an expression: `apply(‹dict›,‹var›,‹expr›)`

**Description:**
Similar to `apply(‹list›,‹expr›)`, but the run variable is now named `‹var›`.
The variable is local to the expression.

    > v = 123;
    > apply({"a" : 1, "b" : 2}, v, v^2);
    < {a:1, b:4}
    > v
    < 123

------


### Applying an expression: `apply(‹dict›,‹varVal›, ‹varKey›,‹expr›)`

**Description:**
Similar to `apply(‹list›,‹var›, ‹expr›)`, but with two running variables: `‹varVal›` for the value and `‹varVal›` for the key.
The variables are local to the expression.

    > apply({"a" : 1, "b" : 2}, v, k, k+v);
    < {a:a1, b:b2}

------

### Selecting elements of a list: `select(‹list›,‹boolexpr›)`

**Description:**
This operator selects all elements of a dict for which a certain condition is satisfied.
The condition is supposed to be encoded by `‹boolexpr›`.
This expression is assumed to return a `‹bool›` value.
As usual, `#` is the run variable, which successively take the value of all elements in the list.

    > select({"a" : 5, "b" : 2}, isodd(#));
    < {a:5}

------

### Selecting elements of a list: `select(‹list›,‹var›,‹boolexpr›)`

**Description:**
Similar to `select(‹dict›,‹boolexpr›)`, but the run variable is now named ‹var›.
The variable is local to the expression.

    > v = 123;
    > select({"a" : 5, "b" : 2}, v, isodd(v))
    < {a:5}
    > v
    < 123

------

### The forall loop: `forall(‹dict›,‹expr›)`

**Description:**
This operator is useful for applying an operation to all elements of a dict.
It takes a `‹dict›` as first argument.
It produces a loop in which `‹expr›` is evaluated for each **value** of the list.
For each run, the run variable `#` takes the value of the corresponding list value.

**Example:**

    > a={"a" : 5, "b" : 2};
    > forall(a,println(#))

This code fragment produces the output

    * 5
    * 2

**Modifiers** 

forall supports the modifier `iterator` that changes the behavior of the running variable: "value" iterates of the dictionary values (the default), "key" iterates over the dictionary keys and "pair" returns an elementary dictionary element that key and value can be accessed using the ".key" and ".value property".

**Example iterator key:**

    > a={"a" : 5, "b" : 2};
    > forall(a,println(#), iterator->"key")

This code fragment produces the output

    * a
    * b


**Example iterator pair:**

    > a={"a" : 5, "b" : 2};
    > forall(a,println([#.key, #.value]), iterator->"pair")

This code fragment produces the output

    * [a, 5]
    * [b, 2]

------

### The forall loop: `forall(‹dict›,‹var›,‹expr›)`

**Description:**
Similar to `forall(‹dict›,‹expr›)`, but the run variable is now named `‹var›`.
The variable is local to the expression.

    > v=994;
    > k=123;
    > forall({"a" : 5, "b" : 2},v,println(v))
    * 5
    * 2
    > v
    < 994
    > k
    < 123

------


### Deleting keys from a dictionary:

A key-value pair can be deleted from a dictionary by setting its value to an undefined value.

    > json = {"a":1, "b": 2};
    > json.a = nada;
    * Warning: Accessing undefined variable: nada
    > forall(json, k, println(k));
    * 2
    > keys(json)
    < ["b"]

------

# Deprecated `dict`

This should not be used anymore.

## Creating a new: `dict()`

Without arguments, this creates an empty dictionary.

    > dict()
    < {}

## Constructing a dict using modifiers: `dict(‹modif1›,‹modif2›,…)`

It is however possible to add elements to this dictionary
by using modifiers in the function invocation.
The names of the modifiers will be used as string keys.

    > dict(foo->"bar", baz->123)
    < {"baz":123, "foo":"bar"}

It is not possible to define a dictionary with non-string keys in this way.

## Adding a mapping: `put(‹dict›,‹expr1›,‹expr2›)`

Creates a new dictionary with is equivalent to `‹dict›` but in which
the key ‹expr1› is mapped to the value ‹expr2›.

    > d = dict();
    > d = put(d, 12, 34);
    > d
    < {12:34}

This does *not* modify the dictionary passed in the first argument, so
you have to store the result back to permanently alter an existing dictionary.

    > put(d, 56, 78)
    < {12:34, 56:78}
    > d
    < {12:34}

It is possible to use the undefined value as a dictionary key.

    > put(dict(), (;), "what?")
    < {___:"what?"}

Different complex numbers correspond to different keys,
even if they have the same real part.

    > d = dict();
    > d = put(d, 32 + 1*i, 321);
    > d = put(d, 32 - 1*i, 329);
    > d = put(d, 32, 320);
    > d = put(d, "32", 23);
    < {32 - i*1:329, 32:320, 32 + i*1:321, "32":23}

Note that the use of quotation marks here in this documentation
is specific to the documentation.  The usual stringification of values
in Cinderella and CindyJS does not apply quotation marks, which may lead
to confusing output.  For example, the above dict may *appear* to have
to identical keys `32`:

    > println(d)
    * {32 - i*1:329, 32:320, 32 + i*1:321, 32:23}

## Retrieving a value: `get(‹dict›,‹expr›)`

Retrieves the value associated with the key `‹expr›`,
or `___` if that key is not present in the dictionary.

    > d = dict(k->77);
    > get(d, "k")
    < 77
    > get(d, "d")
    < ___
