# Types and casting

```python
import os
import tinychain as tc

# use the demo host at demo.tinychain.net, unless overridden by the environment variable `TC_HOST`
HOST = tc.host.Host(os.getenv("TC_HOST", "http://demo.tinychain.net"))
# this endpoint will attempt to resolve whatever state you send it, without committing any changes
ENDPOINT = "/transact/hypothetical"

# this assumes that `x` is of type `tc.tensor.Tensor`
def average(x):
    return x.sum() / x.size

if __name__ == "__main__":
    cxt = tc.Context()  # initialize a new Op context
    cxt.x = tc.tensor.Dense.ones([3])  # initialize a new Dense tensor
    cxt.result = average(cxt.x)  # call our custom function

    actual = HOST.post(ENDPOINT, cxt)  # execute the `Op` defined by `cxt`
    assert actual == 1  # verify the result
```

The `average` function in this example works well enough, but in a public library it might not handle every situation it should. For example, if a user calls `average(tc.URI("$x"))`, the `sum` method and `size` property won't be available because a `URI` doesn't have a `sum` method or `size` property. To handle cases like this, we can use TinyChain's built-in reflection annotations:

```python
# ...
 
# the `post_op` annotation tells TinyChain to reflect over this function
# and assume that it defines a POST Op 
@tc.post_op
# the annotation on `x` tells TinyChain to expect a `Tensor`
def average(x: tc.tensor.Tensor) -> tc.Number:
    # the return annotation tells the calling code to expect a `Number`
    return x.sum() / x.size

if __name__ == "__main__":
    cxt = tc.Context()  # initialize a new Op context
    # `average` is now a TinyChain `Op`, not a native Python function,
    # so it needs to be made addressable by the calling context
    cxt.average = average
    cxt.x = tc.tensor.Dense.ones([3])  # initialize a new Dense tensor
    cxt.result = cxt.average(x=tc.URI("$x"))  # call our custom `Op`
    actual = HOST.post(ENDPOINT, cxt)  # execute the `Op` defined by `cxt`
    assert actual == 1  # verify the result

```

Now, even though the type of `x` in the calling code is a `URI`, the `average` Op still works as the caller expects because the type annotations tell the code in `def average` what to expect.

{% hint style="warning" %}
**Important!** In the TinyChain Python client, types define *what to expect.* They don't necessarily instantiate or cast types, like they do in native Python code.
{% endhint %}

To illustrate this, let's change the return type of `average` to a `String`:

{% hint style="danger" %}

```python
# ...

@tc.post_op
def average(x: tc.tensor.Tensor) -> tc.String:  # <-- return type `String`
    return x.sum() / x.size

if __name__ == "__main__":
    # ...
    actual = HOST.post(ENDPOINT, cxt)
    assert actual == "1"  # this assertion fails!
```

{% endhint %}

Now, the return annotation `tc.String` tells the calling code to expect a `String` but the `Op` still actually returns a `Number`, so the assert fails. To fix this, we'll have to explicitly cast the return value:

```python
# ...

@tc.post_op
def average(x: tc.tensor.Tensor) -> tc.String:
    avg = x.sum() / x.size
    return avg.cast(tc.String)  # explicitly cast `avg` to a `String`

if __name__ == "__main__":
    # ...
    actual = HOST.post(ENDPOINT, cxt)
    assert actual == "1"  # assert that the result is in fact a string

```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.tinychain.net/guides/types-and-casting.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
