You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: CHANGELOG.md
+5Lines changed: 5 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -33,11 +33,16 @@ If you still use 3.4 and find something in `unpythonic` doesn't work there, plea
33
33
-`box` now supports `.set(newvalue)` to rebind (returns the new value as a convenience), and `unbox(b)` to extract contents. Syntactic sugar for rebinding is `b << newvalue` (where `b` is a box).
34
34
-`islice` now supports negative start and stop. (**Caution**: no negative step; and it must consume the whole iterable to determine where it ends, if at all.)
35
35
36
+
**Non-breaking changes**:
37
+
38
+
-`setscape`/`escape` have been renamed `catch`/`throw`, to match the standard terminology in the Lisp family. **The old nonstandard names are now deprecated, and will be removed in 0.15.0.**
39
+
36
40
**Fixed**:
37
41
38
42
- Fix initialization crash in `lazyutil` if MacroPy is not installed.
39
43
- Fix bug in `identity` and `const` with zero args (#7).
40
44
- Use standard Python semantics for negative indices (#6).
45
+
- Escape continuation analysis in `unpythonic.syntax.util` now interprets also the literal name `throw` as invoking an escape continuation.
This feature is known as`catch`/`throw`in several Lisps, e.g. in Emacs Lisp andin Common Lisp (as well as some of its ancestors). This terminology is independent of the use of `throw`/`catch`in C++/Java for the exception handling mechanism. Common Lisp also provides a lexically scoped variant (`BLOCK`/`RETURN-FROM`) that is more idiomatic [according to Seibel](http://www.gigamonkeys.com/book/the-special-operators.html).
Escape continuations can be used as a *multi-return*:
2181
2179
2182
2180
```python
2183
-
from unpythonic importsetescape, escape
2181
+
from unpythonic importcatch, throw
2184
2182
2185
-
@setescape() # note the parentheses
2183
+
@catch() # note the parentheses
2186
2184
def f():
2187
2185
def g():
2188
-
escape("hello from g") # the argument becomes the return value of f()
2186
+
throw("hello from g") # the argument becomes the return value of f()
2189
2187
print("not reached")
2190
2188
g()
2191
2189
print("not reached either")
2192
2190
assert f() =="hello from g"
2193
2191
```
2194
2192
2195
-
**CAUTION**: The implementation is based on exceptions, so catch-all``except:`` statements will intercept also escapes, breaking the escape mechanism. As you already know, be specific inwhat you catch!
2193
+
**CAUTION**: The implementation is based on exceptions, so catch-all``except:`` statements will intercept also throws, breaking the escape mechanism. As you already know, be specific inwhich exception types you catchin an `except` clause!
2196
2194
2197
-
In Lisp terms, `@setescape` essentially captures the escape continuation (ec) of the function decorated with it. The nearest (dynamically) surrounding ec can then be invoked by `escape(value)`. The function decorated with`@setescape` immediately terminates, returning ``value``.
2195
+
In Lisp terms, `@catch` essentially captures the escape continuation (ec) of the function decorated with it. The nearest (dynamically) surrounding ec can then be invoked by `throw(value)`. When the `throw`is performed, the function decorated with`@catch` immediately terminates, returning ``value``.
2198
2196
2199
2197
In Python terms, an escape means just raising a specific type of exception; the usual rules concerning ``try/except/else/finally``and``with`` blocks apply. It is a function call, so it works also in lambdas.
2200
2198
2201
2199
Escaping the function surrounding an FP loop, from inside the loop:
2202
2200
2203
2201
```python
2204
-
@setescape()
2202
+
@catch()
2205
2203
def f():
2206
2204
@looped
2207
2205
def s(loop, acc=0, i=0):
2208
2206
if i >5:
2209
-
escape(acc)
2207
+
throw(acc)
2210
2208
return loop(acc + i, i +1)
2211
2209
print("never reached")
2212
2210
f() # --> 15
2213
2211
```
2214
2212
2215
-
For more control, both ``@setescape`` points andescape instances can be tagged:
2213
+
For more control, both ``@catch`` points and``throw`` instances can be tagged:
2216
2214
2217
2215
```python
2218
-
@setescape(tags="foo") #setescape point tags can be single value or tuple (tuples OR'd, like isinstance())
2216
+
@catch(tags="foo") #catch point tags can be single value or tuple (tuples OR'd, like isinstance())
2219
2217
def foo():
2220
2218
@call
2221
-
@setescape(tags="bar")
2219
+
@catch(tags="bar")
2222
2220
def bar():
2223
2221
@looped
2224
2222
def s(loop, acc=0, i=0):
2225
2223
if i >5:
2226
-
escape(acc, tag="foo") #escape instance tag must be a single value
2224
+
throw(acc, tag="foo") #throw instance tag must be a single value
2227
2225
return loop(acc + i, i +1)
2228
2226
print("never reached")
2229
2227
returnFalse
@@ -2232,20 +2230,24 @@ def foo():
2232
2230
assert foo() ==15
2233
2231
```
2234
2232
2235
-
For details on tagging, especially how untagged and tagged escapes and points interact, and how to make one-to-one connections, see the docstring for``@setescape``.
2233
+
For details on tagging, especially how untagged and tagged throw and catch points interact, and how to make one-to-one connections, see the docstring for``@catch``.
2234
+
2235
+
**Etymology**
2236
+
2237
+
This feature is known as`catch`/`throw`in several Lisps, e.g. in Emacs Lisp andin Common Lisp (as well as some of its ancestors). This terminology is independent of the use of `throw`/`catch`in C++/Java for the exception handling mechanism. Common Lisp also provides a lexically scoped variant (`BLOCK`/`RETURN-FROM`) that is more idiomatic [according to Seibel](http://www.gigamonkeys.com/book/the-special-operators.html).
We provide ``call/ec`` (a.k.a. ``call-with-escape-continuation``), in Python spelled as``call_ec``. It's a decorator that, like ``@call``, immediately runs the function and replaces the def'd name with the return value. The twist is that it internally sets up an escape point, and hands a **first-class escape continuation** to the callee.
2242
+
We provide ``call/ec`` (a.k.a. ``call-with-escape-continuation``), in Python spelled as``call_ec``. It's a decorator that, like ``@call``, immediately runs the function and replaces the def'd name with the return value. The twist is that it internally sets up an catch point, and hands a **first-class escape continuation** to the callee.
2241
2243
2242
2244
The function to be decorated **must** take one positional argument, the ec instance.
2243
2245
2244
-
The ec instance itself is another function, which takes one positional argument: the value to send to the escape point. The ec instance and the escape point are connected one-to-one. No other ``@setescape`` point will catch the ec instance, and the escape point catches only this particular ec instance and nothing else.
2246
+
The ec instance itself is another function, which takes one positional argument: the value to send to the catch point. The ec instance and the catch point are connected one-to-one. No other ``@catch`` point will catch the ec instance, and the catch point catches only this particular ec instance and nothing else.
2245
2247
2246
2248
Any particular ec instance is only valid inside the dynamic extent of the ``call_ec`` invocation that created it. Attempting to call the ec later raises ``RuntimeError``.
2247
2249
2248
-
This builds on ``@setescape``and``escape``, so the caution about catch-all``except:`` statements applies here, too.
2250
+
This builds on ``@catch``and``throw``, so the caution about catch-all``except:`` statements applies here, too.
2249
2251
2250
2252
```python
2251
2253
from unpythonic import call_ec
@@ -2427,7 +2429,7 @@ def result():
2427
2429
print(result) # (6, 7)
2428
2430
```
2429
2431
2430
-
(But see ``@setescape``, ``escape``, and``call_ec``.)
Copy file name to clipboardExpand all lines: macro_extras/README.md
+2-2Lines changed: 2 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -914,9 +914,9 @@ The ``tco`` and ``continuations`` macros actually share a lot of the code that i
914
914
915
915
It is important to recognize a call to an escape continuation as such, because the argument given to an escape continuation is essentially a return value. If this argument is itself a call, it needs the TCO transformation to be applied to it.
916
916
917
-
For escape continuations in ``tco`` and ``continuations`` blocks, only basic uses of ``call_ec`` are supported, for automatically harvesting names referring to an escape continuation. In addition, the literal function names ``ec``and ``brk`` are always *understood as referring to* an escape continuation.
917
+
For escape continuations in ``tco`` and ``continuations`` blocks, only basic uses of ``call_ec`` are supported, for automatically harvesting names referring to an escape continuation. In addition, the literal function names ``ec``, ``brk``and ``throw`` are always *understood as referring to* an escape continuation.
918
918
919
-
The name ``ec``or ``brk`` alone is not sufficient to make a function into an escape continuation, even though ``tco`` (and ``continuations``) will think of it as such. The function also needs to actually implement some kind of an escape mechanism. An easy way to get an escape continuation, where this has already been done for you, is to use ``call_ec``.
919
+
The name ``ec``, ``brk``or ``throw`` alone is not sufficient to make a function into an escape continuation, even though ``tco`` (and ``continuations``) will think of it as such. The function also needs to actually implement some kind of an escape mechanism. An easy way to get an escape continuation, where this has already been done for you, is to use ``call_ec``. Another such mechanism is the ``catch``/``throw`` pair.
920
920
921
921
See the docstring of ``unpythonic.syntax.tco`` for details.
0 commit comments