coconut-develop 3.0.2.post0.dev3__tar.gz → 3.0.2.post0.dev5__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (87) hide show
  1. {coconut-develop-3.0.2.post0.dev3 → coconut-develop-3.0.2.post0.dev5}/DOCS.md +159 -102
  2. coconut-develop-3.0.2.post0.dev5/PKG-INFO +140 -0
  3. {coconut-develop-3.0.2.post0.dev3 → coconut-develop-3.0.2.post0.dev5}/__coconut__/__init__.pyi +11 -0
  4. {coconut-develop-3.0.2.post0.dev3 → coconut-develop-3.0.2.post0.dev5}/coconut/command/cli.py +8 -2
  5. {coconut-develop-3.0.2.post0.dev3 → coconut-develop-3.0.2.post0.dev5}/coconut/command/command.py +14 -3
  6. {coconut-develop-3.0.2.post0.dev3 → coconut-develop-3.0.2.post0.dev5}/coconut/compiler/compiler.py +1 -1
  7. {coconut-develop-3.0.2.post0.dev3 → coconut-develop-3.0.2.post0.dev5}/coconut/compiler/header.py +49 -0
  8. {coconut-develop-3.0.2.post0.dev3 → coconut-develop-3.0.2.post0.dev5}/coconut/compiler/templates/header.py_template +51 -12
  9. {coconut-develop-3.0.2.post0.dev3 → coconut-develop-3.0.2.post0.dev5}/coconut/constants.py +4 -2
  10. coconut-develop-3.0.2.post0.dev5/coconut/icoconut/coconut/kernel.json +11 -0
  11. {coconut-develop-3.0.2.post0.dev3 → coconut-develop-3.0.2.post0.dev5}/coconut/root.py +1 -1
  12. {coconut-develop-3.0.2.post0.dev3 → coconut-develop-3.0.2.post0.dev5}/coconut/tests/main_test.py +13 -10
  13. {coconut-develop-3.0.2.post0.dev3 → coconut-develop-3.0.2.post0.dev5}/coconut/tests/src/cocotest/agnostic/primary.coco +1 -0
  14. {coconut-develop-3.0.2.post0.dev3 → coconut-develop-3.0.2.post0.dev5}/coconut/tests/src/cocotest/agnostic/specific.coco +2 -2
  15. {coconut-develop-3.0.2.post0.dev3 → coconut-develop-3.0.2.post0.dev5}/coconut/tests/src/cocotest/target_sys/target_sys_test.coco +72 -1
  16. coconut-develop-3.0.2.post0.dev3/PKG-INFO +0 -137
  17. coconut-develop-3.0.2.post0.dev3/coconut/icoconut/coconut/kernel.json +0 -11
  18. {coconut-develop-3.0.2.post0.dev3 → coconut-develop-3.0.2.post0.dev5}/CONTRIBUTING.md +0 -0
  19. {coconut-develop-3.0.2.post0.dev3 → coconut-develop-3.0.2.post0.dev5}/FAQ.md +0 -0
  20. {coconut-develop-3.0.2.post0.dev3 → coconut-develop-3.0.2.post0.dev5}/HELP.md +0 -0
  21. {coconut-develop-3.0.2.post0.dev3 → coconut-develop-3.0.2.post0.dev5}/LICENSE.txt +0 -0
  22. {coconut-develop-3.0.2.post0.dev3 → coconut-develop-3.0.2.post0.dev5}/MANIFEST.in +0 -0
  23. {coconut-develop-3.0.2.post0.dev3 → coconut-develop-3.0.2.post0.dev5}/README.rst +0 -0
  24. {coconut-develop-3.0.2.post0.dev3 → coconut-develop-3.0.2.post0.dev5}/__coconut__/__init__.py +0 -0
  25. {coconut-develop-3.0.2.post0.dev3 → coconut-develop-3.0.2.post0.dev5}/__coconut__/py.typed +0 -0
  26. {coconut-develop-3.0.2.post0.dev3 → coconut-develop-3.0.2.post0.dev5}/_coconut/__init__.py +0 -0
  27. {coconut-develop-3.0.2.post0.dev3 → coconut-develop-3.0.2.post0.dev5}/_coconut/__init__.pyi +0 -0
  28. {coconut-develop-3.0.2.post0.dev3 → coconut-develop-3.0.2.post0.dev5}/_coconut/py.typed +0 -0
  29. {coconut-develop-3.0.2.post0.dev3 → coconut-develop-3.0.2.post0.dev5}/coconut/__coconut__.py +0 -0
  30. {coconut-develop-3.0.2.post0.dev3 → coconut-develop-3.0.2.post0.dev5}/coconut/__coconut__.pyi +0 -0
  31. {coconut-develop-3.0.2.post0.dev3 → coconut-develop-3.0.2.post0.dev5}/coconut/__init__.py +0 -0
  32. {coconut-develop-3.0.2.post0.dev3 → coconut-develop-3.0.2.post0.dev5}/coconut/__init__.pyi +0 -0
  33. {coconut-develop-3.0.2.post0.dev3 → coconut-develop-3.0.2.post0.dev5}/coconut/__main__.py +0 -0
  34. {coconut-develop-3.0.2.post0.dev3 → coconut-develop-3.0.2.post0.dev5}/coconut/_pyparsing.py +0 -0
  35. {coconut-develop-3.0.2.post0.dev3 → coconut-develop-3.0.2.post0.dev5}/coconut/api.py +0 -0
  36. {coconut-develop-3.0.2.post0.dev3 → coconut-develop-3.0.2.post0.dev5}/coconut/api.pyi +0 -0
  37. {coconut-develop-3.0.2.post0.dev3 → coconut-develop-3.0.2.post0.dev5}/coconut/command/__init__.py +0 -0
  38. {coconut-develop-3.0.2.post0.dev3 → coconut-develop-3.0.2.post0.dev5}/coconut/command/__init__.pyi +0 -0
  39. {coconut-develop-3.0.2.post0.dev3 → coconut-develop-3.0.2.post0.dev5}/coconut/command/command.pyi +0 -0
  40. {coconut-develop-3.0.2.post0.dev3 → coconut-develop-3.0.2.post0.dev5}/coconut/command/mypy.py +0 -0
  41. {coconut-develop-3.0.2.post0.dev3 → coconut-develop-3.0.2.post0.dev5}/coconut/command/resources/zcoconut.pth +0 -0
  42. {coconut-develop-3.0.2.post0.dev3 → coconut-develop-3.0.2.post0.dev5}/coconut/command/util.py +0 -0
  43. {coconut-develop-3.0.2.post0.dev3 → coconut-develop-3.0.2.post0.dev5}/coconut/command/watch.py +0 -0
  44. {coconut-develop-3.0.2.post0.dev3 → coconut-develop-3.0.2.post0.dev5}/coconut/compiler/__init__.py +0 -0
  45. {coconut-develop-3.0.2.post0.dev3 → coconut-develop-3.0.2.post0.dev5}/coconut/compiler/grammar.py +0 -0
  46. {coconut-develop-3.0.2.post0.dev3 → coconut-develop-3.0.2.post0.dev5}/coconut/compiler/matching.py +0 -0
  47. {coconut-develop-3.0.2.post0.dev3 → coconut-develop-3.0.2.post0.dev5}/coconut/compiler/util.py +0 -0
  48. {coconut-develop-3.0.2.post0.dev3 → coconut-develop-3.0.2.post0.dev5}/coconut/convenience.py +0 -0
  49. {coconut-develop-3.0.2.post0.dev3 → coconut-develop-3.0.2.post0.dev5}/coconut/convenience.pyi +0 -0
  50. {coconut-develop-3.0.2.post0.dev3 → coconut-develop-3.0.2.post0.dev5}/coconut/exceptions.py +0 -0
  51. {coconut-develop-3.0.2.post0.dev3 → coconut-develop-3.0.2.post0.dev5}/coconut/highlighter.py +0 -0
  52. {coconut-develop-3.0.2.post0.dev3 → coconut-develop-3.0.2.post0.dev5}/coconut/icoconut/__init__.py +0 -0
  53. {coconut-develop-3.0.2.post0.dev3 → coconut-develop-3.0.2.post0.dev5}/coconut/icoconut/__main__.py +0 -0
  54. {coconut-develop-3.0.2.post0.dev3 → coconut-develop-3.0.2.post0.dev5}/coconut/icoconut/coconut_py/kernel.json +0 -0
  55. {coconut-develop-3.0.2.post0.dev3 → coconut-develop-3.0.2.post0.dev5}/coconut/icoconut/coconut_py2/kernel.json +0 -0
  56. {coconut-develop-3.0.2.post0.dev3 → coconut-develop-3.0.2.post0.dev5}/coconut/icoconut/coconut_py3/kernel.json +0 -0
  57. {coconut-develop-3.0.2.post0.dev3 → coconut-develop-3.0.2.post0.dev5}/coconut/icoconut/embed.py +0 -0
  58. {coconut-develop-3.0.2.post0.dev3 → coconut-develop-3.0.2.post0.dev5}/coconut/icoconut/root.py +0 -0
  59. {coconut-develop-3.0.2.post0.dev3 → coconut-develop-3.0.2.post0.dev5}/coconut/integrations.py +0 -0
  60. {coconut-develop-3.0.2.post0.dev3 → coconut-develop-3.0.2.post0.dev5}/coconut/main.py +0 -0
  61. {coconut-develop-3.0.2.post0.dev3 → coconut-develop-3.0.2.post0.dev5}/coconut/py.typed +0 -0
  62. {coconut-develop-3.0.2.post0.dev3 → coconut-develop-3.0.2.post0.dev5}/coconut/requirements.py +0 -0
  63. {coconut-develop-3.0.2.post0.dev3 → coconut-develop-3.0.2.post0.dev5}/coconut/terminal.py +0 -0
  64. {coconut-develop-3.0.2.post0.dev3 → coconut-develop-3.0.2.post0.dev5}/coconut/tests/__init__.py +0 -0
  65. {coconut-develop-3.0.2.post0.dev3 → coconut-develop-3.0.2.post0.dev5}/coconut/tests/__main__.py +0 -0
  66. {coconut-develop-3.0.2.post0.dev3 → coconut-develop-3.0.2.post0.dev5}/coconut/tests/constants_test.py +0 -0
  67. {coconut-develop-3.0.2.post0.dev3 → coconut-develop-3.0.2.post0.dev5}/coconut/tests/src/cocotest/agnostic/__init__.coco +0 -0
  68. {coconut-develop-3.0.2.post0.dev3 → coconut-develop-3.0.2.post0.dev5}/coconut/tests/src/cocotest/agnostic/main.coco +0 -0
  69. {coconut-develop-3.0.2.post0.dev3 → coconut-develop-3.0.2.post0.dev5}/coconut/tests/src/cocotest/agnostic/suite.coco +0 -0
  70. {coconut-develop-3.0.2.post0.dev3 → coconut-develop-3.0.2.post0.dev5}/coconut/tests/src/cocotest/agnostic/tutorial.coco +0 -0
  71. {coconut-develop-3.0.2.post0.dev3 → coconut-develop-3.0.2.post0.dev5}/coconut/tests/src/cocotest/agnostic/util.coco +0 -0
  72. {coconut-develop-3.0.2.post0.dev3 → coconut-develop-3.0.2.post0.dev5}/coconut/tests/src/cocotest/non_strict/non_strict_test.coco +0 -0
  73. {coconut-develop-3.0.2.post0.dev3 → coconut-develop-3.0.2.post0.dev5}/coconut/tests/src/cocotest/target_2/py2_test.coco +0 -0
  74. {coconut-develop-3.0.2.post0.dev3 → coconut-develop-3.0.2.post0.dev5}/coconut/tests/src/cocotest/target_3/py3_test.coco +0 -0
  75. {coconut-develop-3.0.2.post0.dev3 → coconut-develop-3.0.2.post0.dev5}/coconut/tests/src/cocotest/target_35/py35_test.coco +0 -0
  76. {coconut-develop-3.0.2.post0.dev3 → coconut-develop-3.0.2.post0.dev5}/coconut/tests/src/cocotest/target_36/py36_test.coco +0 -0
  77. {coconut-develop-3.0.2.post0.dev3 → coconut-develop-3.0.2.post0.dev5}/coconut/tests/src/cocotest/target_38/py38_test.coco +0 -0
  78. {coconut-develop-3.0.2.post0.dev3 → coconut-develop-3.0.2.post0.dev5}/coconut/tests/src/extras.coco +0 -0
  79. {coconut-develop-3.0.2.post0.dev3 → coconut-develop-3.0.2.post0.dev5}/coconut/tests/src/runnable.coco +0 -0
  80. {coconut-develop-3.0.2.post0.dev3 → coconut-develop-3.0.2.post0.dev5}/coconut/tests/src/runner.coco +0 -0
  81. {coconut-develop-3.0.2.post0.dev3 → coconut-develop-3.0.2.post0.dev5}/coconut/util.py +0 -0
  82. {coconut-develop-3.0.2.post0.dev3 → coconut-develop-3.0.2.post0.dev5}/coconut_develop.egg-info/SOURCES.txt +0 -0
  83. {coconut-develop-3.0.2.post0.dev3 → coconut-develop-3.0.2.post0.dev5}/conf.py +0 -0
  84. {coconut-develop-3.0.2.post0.dev3 → coconut-develop-3.0.2.post0.dev5}/pyproject.toml +0 -0
  85. {coconut-develop-3.0.2.post0.dev3 → coconut-develop-3.0.2.post0.dev5}/setup.cfg +0 -0
  86. {coconut-develop-3.0.2.post0.dev3 → coconut-develop-3.0.2.post0.dev5}/setup.py +0 -0
  87. {coconut-develop-3.0.2.post0.dev3 → coconut-develop-3.0.2.post0.dev5}/xontrib/coconut.py +0 -0
@@ -143,74 +143,77 @@ dest destination directory for compiled files (defaults to
143
143
  ##### Optional Arguments
144
144
 
145
145
  ```
146
- -h, --help show this help message and exit
147
- --and source [dest ...]
148
- add an additional source/dest pair to compile (dest is optional)
149
- -v, -V, --version print Coconut and Python version information
150
- -t version, --target version
151
- specify target Python version (defaults to universal)
152
- -i, --interact force the interpreter to start (otherwise starts if no other command
153
- is given) (implies --run)
154
- -p, --package compile source as part of a package (defaults to only if source is a
155
- directory)
156
- -a, --standalone, --stand-alone
157
- compile source as standalone files (defaults to only if source is a
158
- single file)
159
- -l, --line-numbers, --linenumbers
160
- add line number comments for ease of debugging
161
- -k, --keep-lines, --keeplines
162
- include source code in comments for ease of debugging
163
- -w, --watch watch a directory and recompile on changes
164
- -r, --run execute compiled Python
165
- -n, --no-write, --nowrite
166
- disable writing compiled Python
167
- -d, --display print compiled Python
168
- -q, --quiet suppress all informational output (combine with --display to write
169
- runnable code to stdout)
170
- -s, --strict enforce code cleanliness standards
171
- --no-tco, --notco disable tail call optimization
172
- --no-wrap-types, --nowraptypes
173
- disable wrapping type annotations in strings and turn off 'from
174
- __future__ import annotations' behavior
175
- -c code, --code code run Coconut passed in as a string (can also be piped into stdin)
176
- -j processes, --jobs processes
177
- number of additional processes to use (defaults to 'sys') (0 is no
178
- additional processes; 'sys' uses machine default)
179
- -f, --force force re-compilation even when source code and compilation parameters
180
- haven't changed
181
- --minify reduce size of compiled Python
182
- --jupyter ..., --ipython ...
183
- run Jupyter/IPython with Coconut as the kernel (remaining args passed
184
- to Jupyter)
185
- --mypy ... run MyPy on compiled Python (remaining args passed to MyPy) (implies
186
- --package)
187
- --argv ..., --args ...
188
- set sys.argv to source plus remaining args for use in the Coconut
189
- script being run
190
- --tutorial open Coconut's tutorial in the default web browser
191
- --docs, --documentation
192
- open Coconut's documentation in the default web browser
193
- --style name set Pygments syntax highlighting style (or 'list' to list styles)
194
- (defaults to COCONUT_STYLE environment variable if it exists,
195
- otherwise 'default')
196
- --history-file path set history file (or '' for no file) (can be modified by setting
197
- COCONUT_HOME environment variable)
198
- --vi-mode, --vimode enable vi mode in the interpreter (currently set to False) (can be
199
- modified by setting COCONUT_VI_MODE environment variable)
200
- --recursion-limit limit, --recursionlimit limit
201
- set maximum recursion depth in compiler (defaults to 1920) (when
202
- increasing --recursion-limit, you may also need to increase --stack-
203
- size)
204
- --stack-size kbs, --stacksize kbs
205
- run the compiler in a separate thread with the given stack size in
206
- kilobytes
207
- --site-install, --siteinstall
208
- set up coconut.api to be imported on Python start
209
- --site-uninstall, --siteuninstall
210
- revert the effects of --site-install
211
- --verbose print verbose debug output
212
- --trace print verbose parsing data (only available in coconut-develop)
213
- --profile collect and print timing info (only available in coconut-develop)
146
+ -h, --help show this help message and exit
147
+ --and source [dest ...]
148
+ add an additional source/dest pair to compile (dest is optional)
149
+ -v, -V, --version print Coconut and Python version information
150
+ -t version, --target version
151
+ specify target Python version (defaults to universal)
152
+ -i, --interact force the interpreter to start (otherwise starts if no other command
153
+ is given) (implies --run)
154
+ -p, --package compile source as part of a package (defaults to only if source is a
155
+ directory)
156
+ -a, --standalone, --stand-alone
157
+ compile source as standalone files (defaults to only if source is a
158
+ single file)
159
+ -l, --line-numbers, --linenumbers
160
+ force enable line number comments (--line-numbers are enabled by
161
+ default unless --minify is passed)
162
+ --no-line-numbers, --nolinenumbers
163
+ disable line number comments (opposite of --line-numbers)
164
+ -k, --keep-lines, --keeplines
165
+ include source code in comments for ease of debugging
166
+ -w, --watch watch a directory and recompile on changes
167
+ -r, --run execute compiled Python
168
+ -n, --no-write, --nowrite
169
+ disable writing compiled Python
170
+ -d, --display print compiled Python
171
+ -q, --quiet suppress all informational output (combine with --display to write
172
+ runnable code to stdout)
173
+ -s, --strict enforce code cleanliness standards
174
+ --no-tco, --notco disable tail call optimization
175
+ --no-wrap-types, --nowraptypes
176
+ disable wrapping type annotations in strings and turn off 'from
177
+ __future__ import annotations' behavior
178
+ -c code, --code code run Coconut passed in as a string (can also be piped into stdin)
179
+ -j processes, --jobs processes
180
+ number of additional processes to use (defaults to 'sys') (0 is no
181
+ additional processes; 'sys' uses machine default)
182
+ -f, --force force re-compilation even when source code and compilation parameters
183
+ haven't changed
184
+ --minify reduce size of compiled Python
185
+ --jupyter ..., --ipython ...
186
+ run Jupyter/IPython with Coconut as the kernel (remaining args passed
187
+ to Jupyter)
188
+ --mypy ... run MyPy on compiled Python (remaining args passed to MyPy) (implies
189
+ --package --line-numbers)
190
+ --argv ..., --args ...
191
+ set sys.argv to source plus remaining args for use in the Coconut
192
+ script being run
193
+ --tutorial open Coconut's tutorial in the default web browser
194
+ --docs, --documentation
195
+ open Coconut's documentation in the default web browser
196
+ --style name set Pygments syntax highlighting style (or 'list' to list styles)
197
+ (defaults to COCONUT_STYLE environment variable if it exists,
198
+ otherwise 'default')
199
+ --history-file path set history file (or '' for no file) (can be modified by setting
200
+ COCONUT_HOME environment variable)
201
+ --vi-mode, --vimode enable vi mode in the interpreter (currently set to False) (can be
202
+ modified by setting COCONUT_VI_MODE environment variable)
203
+ --recursion-limit limit, --recursionlimit limit
204
+ set maximum recursion depth in compiler (defaults to 1920) (when
205
+ increasing --recursion-limit, you may also need to increase --stack-
206
+ size)
207
+ --stack-size kbs, --stacksize kbs
208
+ run the compiler in a separate thread with the given stack size in
209
+ kilobytes
210
+ --site-install, --siteinstall
211
+ set up coconut.api to be imported on Python start
212
+ --site-uninstall, --siteuninstall
213
+ revert the effects of --site-install
214
+ --verbose print verbose debug output
215
+ --trace print verbose parsing data (only available in coconut-develop)
216
+ --profile collect and print timing info (only available in coconut-develop)
214
217
  ```
215
218
 
216
219
  #### Coconut Scripts
@@ -221,7 +224,7 @@ coconut-run <source> <args>
221
224
  ```
222
225
  as an alias for
223
226
  ```
224
- coconut --quiet --target sys --line-numbers --keep-lines --run <source> --argv <args>
227
+ coconut --quiet --target sys --keep-lines --run <source> --argv <args>
225
228
  ```
226
229
  which will quietly compile and run `<source>`, passing any additional arguments to the script, mimicking how the `python` command works.
227
230
 
@@ -732,6 +735,8 @@ All function composition operators also have in-place versions (e.g. `..=`).
732
735
 
733
736
  Since all forms of function composition always call the first function in the composition (`f` in `f ..> g` and `g` in `f <.. g`) with exactly the arguments passed into the composition, all forms of function composition will preserve all metadata attached to the first function in the composition, including the function's [signature](https://docs.python.org/3/library/inspect.html#inspect.signature) and any of that function's attributes.
734
737
 
738
+ _Note: for composing `async` functions, see [`and_then` and `and_then_await`](#and_then-and-and_then_await)._
739
+
735
740
  ##### Example
736
741
 
737
742
  **Coconut:**
@@ -3341,6 +3346,54 @@ res, err = safe_call(-> 1 / 0) |> fmap$(.+1)
3341
3346
  **Python:**
3342
3347
  _Can't be done without a complex `Expected` definition. See the compiled code for the Python syntax._
3343
3348
 
3349
+ #### `ident`
3350
+
3351
+ **ident**(_x_, *, _side\_effect_=`None`)
3352
+
3353
+ Coconut's `ident` is the identity function, generally equivalent to `x -> x`.
3354
+
3355
+ `ident` also accepts one keyword-only argument, `side_effect`, which specifies a function to call on the argument before it is returned. Thus, `ident` is effectively equivalent to:
3356
+ ```coconut
3357
+ def ident(x, *, side_effect=None):
3358
+ if side_effect is not None:
3359
+ side_effect(x)
3360
+ return x
3361
+ ```
3362
+
3363
+ `ident` is primarily useful when writing in a point-free style (e.g. in combination with [`lift`](#lift)) or for debugging [pipes](#pipes) where `ident$(side_effect=print)` can let you see what is being piped.
3364
+
3365
+ #### `const`
3366
+
3367
+ **const**(_value_)
3368
+
3369
+ Coconut's `const` simply constructs a function that, whatever its arguments, just returns the given value. Thus, `const` is equivalent to a pickleable version of
3370
+ ```coconut
3371
+ def const(value) = (*args, **kwargs) -> value
3372
+ ```
3373
+
3374
+ `const` is primarily useful when writing in a point-free style (e.g. in combination with [`lift`](#lift)).
3375
+
3376
+ #### `flip`
3377
+
3378
+ **flip**(_func_, _nargs_=`None`)
3379
+
3380
+ Coconut's `flip(f, nargs=None)` is a higher-order function that, given a function `f`, returns a new function with reversed argument order. If `nargs` is passed, only the first `nargs` arguments are reversed.
3381
+
3382
+ For the binary case, `flip` works as
3383
+ ```coconut
3384
+ flip(f, 2)(x, y) == f(y, x)
3385
+ ```
3386
+ such that `flip$(?, 2)` implements the `C` combinator (`flip` in Haskell).
3387
+
3388
+ In the general case, `flip` is equivalent to a pickleable version of
3389
+ ```coconut
3390
+ def flip(f, nargs=None) =
3391
+ (*args, **kwargs) -> (
3392
+ f(*args[::-1], **kwargs) if nargs is None
3393
+ else f(*(args[nargs-1::-1] + args[nargs:]), **kwargs)
3394
+ )
3395
+ ```
3396
+
3344
3397
  #### `lift`
3345
3398
 
3346
3399
  **lift**(_func_)
@@ -3388,54 +3441,58 @@ def plus_and_times(x, y):
3388
3441
  return x + y, x * y
3389
3442
  ```
3390
3443
 
3391
- #### `flip`
3444
+ #### `and_then` and `and_then_await`
3392
3445
 
3393
- **flip**(_func_, _nargs_=`None`)
3446
+ Coconut provides the `and_then` and `and_then_await` built-ins for composing `async` functions. Specifically:
3447
+ * To forwards compose an async function `async_f` with a normal function `g` (such that `g` is called on the result of `await`ing `async_f`), write ``async_f `and_then` g``.
3448
+ * To forwards compose an async function `async_f` with another async function `async_g` (such that `async_g` is called on the result of `await`ing `async_f`, and then `async_g` is itself awaited), write ``async_f `and_then_await` async_g``.
3449
+ * To forwards compose a normal function `f` with an async function `async_g` (such that `async_g` is called on the result of `f`), just write `f ..> async_g`.
3394
3450
 
3395
- Coconut's `flip(f, nargs=None)` is a higher-order function that, given a function `f`, returns a new function with reversed argument order. If `nargs` is passed, only the first `nargs` arguments are reversed.
3451
+ Note that all of the above will always result in the resulting composition being an `async` function.
3396
3452
 
3397
- For the binary case, `flip` works as
3453
+ The built-ins are effectively equivalent to:
3398
3454
  ```coconut
3399
- flip(f, 2)(x, y) == f(y, x)
3400
- ```
3401
- such that `flip$(?, 2)` implements the `C` combinator (`flip` in Haskell).
3455
+ def and_then[**T, U, V](
3456
+ first_async_func: async (**T) -> U,
3457
+ second_func: U -> V,
3458
+ ) -> async (**T) -> V =
3459
+ async def (*args, **kwargs) -> (
3460
+ first_async_func(*args, **kwargs)
3461
+ |> await
3462
+ |> second_func
3463
+ )
3402
3464
 
3403
- In the general case, `flip` is equivalent to a pickleable version of
3404
- ```coconut
3405
- def flip(f, nargs=None) =
3406
- (*args, **kwargs) -> (
3407
- f(*args[::-1], **kwargs) if nargs is None
3408
- else f(*(args[nargs-1::-1] + args[nargs:]), **kwargs)
3465
+ def and_then_await[**T, U, V](
3466
+ first_async_func: async (**T) -> U,
3467
+ second_async_func: async U -> V,
3468
+ ) -> async (**T) -> V =
3469
+ async def (*args, **kwargs) -> (
3470
+ first_async_func(*args, **kwargs)
3471
+ |> await
3472
+ |> second_async_func
3473
+ |> await
3409
3474
  )
3410
3475
  ```
3411
3476
 
3412
- #### `const`
3477
+ Like normal [function composition](#function-composition), `and_then` and `and_then_await` will preserve all metadata attached to the first function in the composition.
3413
3478
 
3414
- **const**(_value_)
3479
+ ##### Example
3415
3480
 
3416
- Coconut's `const` simply constructs a function that, whatever its arguments, just returns the given value. Thus, `const` is equivalent to a pickleable version of
3481
+ **Coconut:**
3417
3482
  ```coconut
3418
- def const(value) = (*args, **kwargs) -> value
3483
+ load_and_send_data = (
3484
+ load_data_async()
3485
+ `and_then` proc_data
3486
+ `and_then_await` send_data
3487
+ )
3419
3488
  ```
3420
3489
 
3421
- `const` is primarily useful when writing in a point-free style (e.g. in combination with [`lift`](#lift)).
3422
-
3423
- #### `ident`
3424
-
3425
- **ident**(_x_, *, _side\_effect_=`None`)
3426
-
3427
- Coconut's `ident` is the identity function, generally equivalent to `x -> x`.
3428
-
3429
- `ident` also accepts one keyword-only argument, `side_effect`, which specifies a function to call on the argument before it is returned. Thus, `ident` is effectively equivalent to:
3430
- ```coconut
3431
- def ident(x, *, side_effect=None):
3432
- if side_effect is not None:
3433
- side_effect(x)
3434
- return x
3490
+ **Python:**
3491
+ ```coconut_python
3492
+ async def load_and_send_data():
3493
+ return await send_data(proc_data(await load_data_async()))
3435
3494
  ```
3436
3495
 
3437
- `ident` is primarily useful when writing in a point-free style (e.g. in combination with [`lift`](#lift)) or for debugging [pipes](#pipes) where `ident$(side_effect=print)` can let you see what is being piped.
3438
-
3439
3496
  ### Built-Ins for Working with Iterators
3440
3497
 
3441
3498
  ```{contents}
@@ -0,0 +1,140 @@
1
+ Metadata-Version: 2.1
2
+ Name: coconut-develop
3
+ Version: 3.0.2.post0.dev5
4
+ Summary: Simple, elegant, Pythonic functional programming.
5
+ Home-page: http://coconut-lang.org
6
+ Author: Evan Hubinger
7
+ Author-email: evanjhub@gmail.com
8
+ License: Apache 2.0
9
+ Keywords: functional,programming,language,compiler,pattern,pattern-matching,algebraic,data type,data types,lambda,lambdas,lazy,evaluation,lazy list,lazy lists,tail,recursion,call,recursive,infix,function,composition,compose,partial,application,currying,curry,pipeline,pipe,unicode,operator,operators,frozenset,literal,syntax,destructuring,assignment,fold,datamaker,prepattern,iterator,none,coalesce,coalescing,statement,lru_cache,memoization,backport,typing,embed,PEP 622,overrides,islice,itertools,functools,TYPE_CHECKING,Expected,breakpoint,help,reduce,takewhile,dropwhile,tee,count,makedata,consume,parallel_map,addpattern,recursive_iterator,concurrent_map,fmap,starmap,reiterable,scan,groupsof,memoize,zip_longest,override,flatten,ident,call,safe_call,flip,const,lift,all_equal,collectby,multi_enumerate,cartesian_product,multiset,cycle,windowsof,and_then,and_then_await,py_chr,py_dict,py_hex,py_input,py_int,py_map,py_object,py_oct,py_open,py_print,py_range,py_str,py_super,py_zip,py_filter,py_reversed,py_enumerate,py_raw_input,py_xrange,py_repr,py_breakpoint,_namedtuple_of,reveal_type,reveal_locals,MatchError,__fmap__,__iter_getitem__,data,match,case,cases,where,addpattern,then,operator,type,copyclosure,λ
10
+ Platform: UNKNOWN
11
+ Classifier: Development Status :: 5 - Production/Stable
12
+ Classifier: License :: OSI Approved :: Apache Software License
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: Topic :: Software Development
15
+ Classifier: Topic :: Software Development :: Code Generators
16
+ Classifier: Topic :: Software Development :: Compilers
17
+ Classifier: Topic :: Software Development :: Interpreters
18
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
19
+ Classifier: Topic :: Utilities
20
+ Classifier: Environment :: Console
21
+ Classifier: Operating System :: OS Independent
22
+ Classifier: Programming Language :: Python
23
+ Classifier: Programming Language :: Python :: 2
24
+ Classifier: Programming Language :: Python :: 2.6
25
+ Classifier: Programming Language :: Python :: 2.7
26
+ Classifier: Programming Language :: Python :: 3
27
+ Classifier: Programming Language :: Python :: 3.2
28
+ Classifier: Programming Language :: Python :: 3.3
29
+ Classifier: Programming Language :: Python :: 3.4
30
+ Classifier: Programming Language :: Python :: 3.5
31
+ Classifier: Programming Language :: Python :: 3.6
32
+ Classifier: Programming Language :: Python :: 3.7
33
+ Classifier: Programming Language :: Python :: 3.8
34
+ Classifier: Programming Language :: Python :: 3.9
35
+ Classifier: Programming Language :: Python :: 3.10
36
+ Classifier: Programming Language :: Python :: 3.11
37
+ Classifier: Programming Language :: Other
38
+ Classifier: Programming Language :: Other Scripting Engines
39
+ Classifier: Programming Language :: Python :: Implementation :: CPython
40
+ Classifier: Programming Language :: Python :: Implementation :: PyPy
41
+ Classifier: Framework :: IPython
42
+ Classifier: Framework :: Jupyter
43
+ Classifier: Typing :: Typed
44
+ Provides-Extra: kernel
45
+ Provides-Extra: watch
46
+ Provides-Extra: mypy
47
+ Provides-Extra: backports
48
+ Provides-Extra: xonsh
49
+ Provides-Extra: jupyter
50
+ Provides-Extra: all
51
+ Provides-Extra: ipython
52
+ Provides-Extra: docs
53
+ Provides-Extra: tests
54
+ Provides-Extra: dev
55
+ License-File: LICENSE.txt
56
+
57
+ |logo| Coconut
58
+ ==============
59
+
60
+ ..
61
+ <insert toctree here>
62
+
63
+ .. |logo| image:: https://github.com/evhub/coconut/raw/gh-pages/favicon-32x32.png
64
+
65
+ .. image:: https://opencollective.com/coconut/backers/badge.svg
66
+ :alt: Backers on Open Collective
67
+ :target: #backers
68
+ .. image:: https://opencollective.com/coconut/sponsors/badge.svg
69
+ :alt: Sponsors on Open Collective
70
+ :target: #sponsors
71
+ .. image:: https://badges.gitter.im/evhub/coconut.svg
72
+ :alt: Join the chat at https://gitter.im/evhub/coconut
73
+ :target: https://gitter.im/evhub/coconut?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge
74
+
75
+ Coconut (`coconut-lang.org`__) is a variant of Python_ that **adds on top of Python syntax** new features for simple, elegant, Pythonic **functional programming**.
76
+
77
+ __ Coconut_
78
+ .. _Coconut: http://coconut-lang.org/
79
+
80
+ Coconut is developed on GitHub_ and hosted on PyPI_. Installing Coconut is as easy as opening a command prompt and entering::
81
+
82
+ pip install coconut
83
+
84
+ To help you get started, check out these links for more information about Coconut:
85
+
86
+ - Tutorial_: If you're new to Coconut, a good place to start is Coconut's **tutorial**.
87
+ - Documentation_: If you're looking for info about a specific feature, check out Coconut's **documentation**.
88
+ - `Online Interpreter`_: If you want to try Coconut in your browser, check out Coconut's **online interpreter**.
89
+ - FAQ_: If you have general questions about Coconut—like who Coconut is built for and whether or not you should use it—Coconut's frequently asked questions are often the best place to start.
90
+ - `Create a New Issue <https://github.com/evhub/coconut/issues/new>`_: If you're having a problem with Coconut, creating a new issue detailing the problem will allow it to be addressed as soon as possible.
91
+ - Gitter_: For any questions, concerns, or comments about anything Coconut-related, ask around at Coconut's Gitter, a GitHub-integrated chat room for Coconut developers.
92
+ - Releases_: Want to know what's been added in recent Coconut versions? Check out the release log for all the new features and fixes.
93
+
94
+ .. _Python: https://www.python.org/
95
+ .. _PyPI: https://pypi.python.org/pypi/coconut
96
+ .. _Tutorial: http://coconut.readthedocs.io/en/latest/HELP.html
97
+ .. _Documentation: http://coconut.readthedocs.io/en/latest/DOCS.html
98
+ .. _`Online Interpreter`: https://cs121-team-panda.github.io/coconut-interpreter
99
+ .. _FAQ: http://coconut.readthedocs.io/en/latest/FAQ.html
100
+ .. _GitHub: https://github.com/evhub/coconut
101
+ .. _Gitter: https://gitter.im/evhub/coconut
102
+ .. _Releases: https://github.com/evhub/coconut/releases
103
+
104
+ Credits
105
+ +++++++
106
+
107
+ Contributors
108
+ ------------
109
+
110
+ This project exists thanks to all the people who contribute! `Become a contributor`__.
111
+
112
+ .. image:: https://opencollective.com/coconut/contributors.svg?width=890&button=false
113
+ :target: https://github.com/evhub/coconut/graphs/contributors
114
+
115
+ __ Contributor_
116
+ .. _Contributor: http://coconut.readthedocs.io/en/develop/CONTRIBUTING.html
117
+
118
+ Backers
119
+ -------
120
+
121
+ Thank you to all our backers! `Become a backer`__.
122
+
123
+ .. image:: https://opencollective.com/coconut/backers.svg?width=890
124
+ :target: https://opencollective.com/coconut#backers
125
+
126
+ __ Backer_
127
+ .. _Backer: https://opencollective.com/coconut#backer
128
+
129
+ Sponsors
130
+ --------
131
+
132
+ Support Coconut by becoming a sponsor. Your logo will show up here with a link to your website. `Become a sponsor`__.
133
+
134
+ .. image:: https://opencollective.com/XX/sponsor/0/avatar.svg
135
+ :target: https://opencollective.com/coconut/sponsor/0/website
136
+
137
+ __ Sponsor_
138
+ .. _Sponsor: https://opencollective.com/coconut#sponsor
139
+
140
+
@@ -530,6 +530,17 @@ def _coconut_base_compose(
530
530
  ) -> _t.Callable[[_T], _t.Any]: ...
531
531
 
532
532
 
533
+ def and_then(
534
+ first_async_func: _t.Callable[_P, _t.Awaitable[_U]],
535
+ second_func: _t.Callable[[_U], _V],
536
+ ) -> _t.Callable[_P, _t.Awaitable[_V]]: ...
537
+
538
+ def and_then_await(
539
+ first_async_func: _t.Callable[_P, _t.Awaitable[_U]],
540
+ second_async_func: _t.Callable[[_U], _t.Awaitable[_V]],
541
+ ) -> _t.Callable[_P, _t.Awaitable[_V]]: ...
542
+
543
+
533
544
  # all forward/backward/none composition functions MUST be kept in sync:
534
545
 
535
546
  # @_t.overload
@@ -115,7 +115,13 @@ arguments.add_argument(
115
115
  arguments.add_argument(
116
116
  "-l", "--line-numbers", "--linenumbers",
117
117
  action="store_true",
118
- help="add line number comments for ease of debugging",
118
+ help="force enable line number comments (--line-numbers are enabled by default unless --minify is passed)",
119
+ )
120
+
121
+ arguments.add_argument(
122
+ "--no-line-numbers", "--nolinenumbers",
123
+ action="store_true",
124
+ help="disable line number comments (opposite of --line-numbers)",
119
125
  )
120
126
 
121
127
  arguments.add_argument(
@@ -209,7 +215,7 @@ arguments.add_argument(
209
215
  "--mypy",
210
216
  type=str,
211
217
  nargs=argparse.REMAINDER,
212
- help="run MyPy on compiled Python (remaining args passed to MyPy) (implies --package)",
218
+ help="run MyPy on compiled Python (remaining args passed to MyPy) (implies --package --line-numbers)",
213
219
  )
214
220
 
215
221
  arguments.add_argument(
@@ -229,8 +229,10 @@ class Command(object):
229
229
  # validate general command args
230
230
  if args.stack_size and args.stack_size % 4 != 0:
231
231
  logger.warn("--stack-size should generally be a multiple of 4, not {stack_size} (to support 4 KB pages)".format(stack_size=args.stack_size))
232
- if args.mypy is not None and args.line_numbers:
233
- logger.warn("extraneous --line-numbers argument passed; --mypy implies --line-numbers")
232
+ if args.mypy is not None and args.no_line_numbers:
233
+ logger.warn("using --mypy running with --no-line-numbers is not recommended; mypy error messages won't include Coconut line numbers")
234
+ if args.line_numbers and args.no_line_numbers:
235
+ raise CoconutException("cannot compile with both --line-numbers and --no-line-numbers")
234
236
  if args.site_install and args.site_uninstall:
235
237
  raise CoconutException("cannot --site-install and --site-uninstall simultaneously")
236
238
  for and_args in getattr(args, "and") or []:
@@ -266,11 +268,20 @@ class Command(object):
266
268
  self.argv_args = list(args.argv)
267
269
 
268
270
  # process general compiler args
271
+ if args.line_numbers:
272
+ line_numbers = True
273
+ elif args.no_line_numbers:
274
+ line_numbers = False
275
+ else:
276
+ line_numbers = (
277
+ not args.minify
278
+ or args.mypy is not None
279
+ )
269
280
  self.setup(
270
281
  target=args.target,
271
282
  strict=args.strict,
272
283
  minify=args.minify,
273
- line_numbers=args.line_numbers or args.mypy is not None,
284
+ line_numbers=line_numbers,
274
285
  keep_lines=args.keep_lines,
275
286
  no_tco=args.no_tco,
276
287
  no_wrap=args.no_wrap_types,
@@ -3499,7 +3499,7 @@ if not {check_var}:
3499
3499
  return "await " + await_expr
3500
3500
  elif self.target_info >= (3, 3):
3501
3501
  # we have to wrap the yield here so it doesn't cause the function to be detected as an async generator
3502
- return self.wrap_passthrough("(yield from " + await_expr + ")", early=True)
3502
+ return self.wrap_passthrough("(yield from " + await_expr + ")")
3503
3503
  else:
3504
3504
  # this yield is fine because we can detect the _coconut.asyncio.From
3505
3505
  return "(yield _coconut.asyncio.From(" + await_expr + "))"
@@ -488,6 +488,55 @@ items = _coconut.collections.Counter.viewitems
488
488
  indent=1,
489
489
  newline=True,
490
490
  ),
491
+ def_async_compose_call=prepare(
492
+ r'''
493
+ async def __call__(self, *args, **kwargs):
494
+ arg = await self._coconut_func(*args, **kwargs)
495
+ for f, await_f in self._coconut_func_infos:
496
+ arg = f(arg)
497
+ if await_f:
498
+ arg = await arg
499
+ return arg
500
+ ''' if target_info >= (3, 5) else
501
+ pycondition(
502
+ (3, 5),
503
+ if_ge=r'''
504
+ _coconut_call_ns = {}
505
+ _coconut_exec("""async def __call__(self, *args, **kwargs):
506
+ arg = await self._coconut_func(*args, **kwargs)
507
+ for f, await_f in self._coconut_func_infos:
508
+ arg = f(arg)
509
+ if await_f:
510
+ arg = await arg
511
+ return arg""", _coconut_call_ns)
512
+ __call__ = _coconut_call_ns["__call__"]
513
+ ''',
514
+ # we got the below code by compiling the above code with yield from instead of await and --target 2
515
+ if_lt=r'''
516
+ @_coconut.asyncio.coroutine
517
+ def __call__(self, *args, **kwargs):
518
+ to_await = _coconut.iter(self._coconut_func(*args, **kwargs))
519
+ while True:
520
+ try:
521
+ yield _coconut.next(to_await)
522
+ except _coconut.StopIteration as stop_it:
523
+ arg = stop_it.args[0] if _coconut.len(stop_it.args) > 0 else None
524
+ break
525
+ for f, await_f in self._coconut_func_infos:
526
+ arg = f(arg)
527
+ if await_f:
528
+ to_await = _coconut.iter(arg)
529
+ while True:
530
+ try:
531
+ yield _coconut.next(to_await)
532
+ except _coconut.StopIteration as stop_it:
533
+ arg = stop_it.args[0] if _coconut.len(stop_it.args) > 0 else None
534
+ break
535
+ raise _coconut.StopIteration(arg)
536
+ ''',
537
+ ),
538
+ indent=1
539
+ ),
491
540
 
492
541
  # used in the second round
493
542
  tco_comma="_coconut_tail_call, _coconut_tco, " if not no_tco else "",