Skip to content

Commit

Permalink
Add "SPEC.md"
Browse files Browse the repository at this point in the history
  • Loading branch information
Azureblade3808 committed Aug 27, 2024
1 parent 293062a commit b649961
Showing 1 changed file with 127 additions and 0 deletions.
127 changes: 127 additions & 0 deletions SPEC.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
# Specifications

## `defer` can be used in two forms

There are two ways to use `defer`. One is called _sugarful_ and the other is called _sugarless_.

A typical _sugarful_ usage is like

```python
>>> from deferrer import defer

>>> def f():
... defer and print(0)
... print(1)

>>> f()
1
0

```

A typical _sugarless_ usage is like

```python
>>> from deferrer import defer

>>> def f():
... defer(print)(0)
... print(1)

>>> f()
1
0

```

You may use either of them, or mix them up.

```python
>>> from deferrer import defer

>>> def f():
... defer and print(0)
... defer(print)(1)
... print(2)

>>> f()
2
1
0

```

## `defer` can only be used in functions

The implementation of `defer` relies on the fact that the local scope, along with some temporary objects we put in it, will eventually be released when the function ends.

It is never the same case for a global scope or a class scope, whereas a global scope will nearly never get disposed and objects in a class scope are copied into the class and therefore retained.

As a prevention, when `defer` is (incorrectly) used in a global scope or a class scope, a `RuntimeError` is raised.

```python
>>> from deferrer import defer

>>> defer and print()
Traceback (most recent call last):
...
RuntimeError: ...

>>> defer(print)()
Traceback (most recent call last):
...
RuntimeError: ...

>>> class C:
... defer and print()
Traceback (most recent call last):
...
RuntimeError: ...

>>> class C:
... defer(print)()
Traceback (most recent call last):
...
RuntimeError: ...

```

## A deferred function’s arguments are evaluated when the defer statement is evaluated

(Paragraph title is borrowed from [The Go Blog](https://go.dev/blog/defer-panic-and-recover))

```python
>>> from deferrer import defer

>>> def f():
... x = 0
... defer and print(x)
... x = 1
... defer and print(x)
... x = 2
... print(x)

>>> f()
2
1
0

```

```python
>>> from deferrer import defer

>>> def f():
... x = 0
... defer(print)(x)
... x = 1
... defer(print)(x)
... x = 2
... print(x)

>>> f()
2
1
0

```

0 comments on commit b649961

Please sign in to comment.