Skip to content

Commit

Permalink
Bring up to date
Browse files Browse the repository at this point in the history
  • Loading branch information
nielstron committed Jan 9, 2024
1 parent 623de48 commit ce45a77
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 28 deletions.
21 changes: 18 additions & 3 deletions src/language_tour/classes.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@ class Person(PlutusData):
birthyear: int
```

PlutusData may contain only `bytes`, `int` or other dataclasses.
> PlutusData may contain only `bytes`, `int`, dicts, lists or other dataclasses.
Note that `str` and `None` are not valid field types of PlutusData.

#### Constructing objects

Expand Down Expand Up @@ -87,7 +89,7 @@ if isinstance(a, Person):
print(a.birthyear)
```

*New in 0.16.0:* We can combine isinstance calls and access shared attributes across classes.
We can combine isinstance calls and access shared attributes across classes.

```python
if isinstance(a, Person) or isinstance(a, Animal):
Expand All @@ -97,10 +99,23 @@ if isinstance(a, Person) or isinstance(a, Animal):
print(a.name)
```

You can also form the complement of type casts.

```python
a: Union[Person, Animal] = ...
if isinstance(a, Person):
# a is of type Person in this branch
print(a.birthyear)
else:
# a is of type Animal in this branch
print(a.owner)
```


> Note that you can also use `str` / `print` directly to get a very informative representation of the object
> ```python
> print(a)
> # prints "Person(name=b'Billy', birthyear=1970)"
> # "Person(name=b'Billy', birthyear=1970)"
> ```
#### `.to_cbor()`
Expand Down
63 changes: 38 additions & 25 deletions src/language_tour/functions.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,30 +2,54 @@

## Regular Functions

Functions in Opshin should have type annotations for the arguments and the return.
There must be one `return` statement at the end of a function.
If it is omitted, the function returns `None`.

> Note that the `return` statement must be the last statement in a function, if present
Functions in Opshin should have type annotations for the arguments and the return value.
Return statements can be placed anywhere inside a function.
Note that all return statements must have a type compatible with the annotated
return type.

```python
def fibonacci(n: int) -> int:
if n < 2:
res = 1
return 1
else:
res = fibonacci(n-1) + fibonacci(n-2)
return res
return fibonacci(n-1) + fibonacci(n-2)
```

As shown, Opshin functions support recursion. A function `foo` is called as `foo(x, y, ...)` with arguments `x`, `y`, etc.

If the function does not have a return statement in some path, the implicit return value is `None`.
This can be useful for code that has side-effects, such as assertion checks.

```python
def check_valid(n: int) -> None:
assert n > 0, f"Invalid negative int encountered: {n}"
```

As shown, Opshin functions support recursion.
If the type annotation is missing for any field, the implicit annotation is `Any`.
This may be fine for your use case, but note that this is slightly less efficient (and less clear to the reader) than a properly type annotated function.

Note that you can define functions locally and within other functions, so that they do not clutter your namespace and can not be used in the wrong context.
The following is legal.

```python
def mul_twice(x: int) -> int:

def mul_once(x: int) -> int:
return x * x

return mul_once(x) * mul_once(x)

print(mul_twice(5))
# "625"
```

## Lambda and Local Functions
## Lambdas and list expressions

Generally OpShin discourages the use of lambda functions, as they don't allow specifying types in the function signature.
Generally OpShin does not support the use of lambda functions, as they don't allow specifying types in the function signature.
Instead, consider using a local function definitions or list expressions. For example instead of the following expression

```python
ys = map(lambda x: 2*x, filter(lambda x: x > 0, xs))
ys = map(lambda x: 2*x, filter(lambda x: x > 0, xs)) # does not work.
```

You could either define local functions like this
Expand All @@ -37,23 +61,12 @@ def greater_zero(x: int) -> bool:
def mul_2(x: int) -> int:
return 2*x

ys = map(mul_2, filter(greater_zero, xs))
ys = map(mul_2, filter(greater_zero, xs)) # does not work.
```

Or you can express this very compactly and readable directly in a list expression like this

```python
ys = [2*x for x in xs if x > 0]
ys = [2*x for x in xs if x > 0] # works!
```

Note that you can define functions locally and within other functions, so that they do not clutter your namespace and can not be used in the wrong context.
The following is legal.

```python
def mul_twice(x: int) -> int:

def mul_once(x: int) -> int:
return x * x

return mul_once(x) * mul_once(x)
```
3 changes: 3 additions & 0 deletions src/language_tour/variables.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,9 @@ z: Union[A, B] = y

This will allow you to also store objects of type `B` in `z` later in the code.

> Note that the type of a variable can not be changed after initialization.
> This is true as of version 0.19.0 and may change again in a later version.
## Tuple Assignments

Opshin supports Python's tuple assignment syntax:
Expand Down

0 comments on commit ce45a77

Please sign in to comment.