Skip to content

Commit

Permalink
Rename of to call
Browse files Browse the repository at this point in the history
Refs   #691.
  • Loading branch information
evhub committed Dec 30, 2022
1 parent 990bf78 commit eddc207
Show file tree
Hide file tree
Showing 9 changed files with 48 additions and 35 deletions.
14 changes: 8 additions & 6 deletions DOCS.md
Original file line number Diff line number Diff line change
Expand Up @@ -1564,7 +1564,7 @@ A very common thing to do in functional programming is to make use of function v
(raise) => def (exc=None, from_exc=None) -> raise exc from from_exc # or just raise if exc is None
```

_For an operator function for function application, see [`of`](#of)._
_For an operator function for function application, see [`call`](#call)._

##### Example

Expand Down Expand Up @@ -3521,16 +3521,18 @@ def flip(f, nargs=None) =
)
```

### `of`
### `call`

**of**(_func_, /, *_args_, \*\*_kwargs_)
**call**(_func_, /, *_args_, \*\*_kwargs_)

Coconut's `of` simply implements function application. Thus, `of` is equivalent to
Coconut's `call` simply implements function application. Thus, `call` is equivalent to
```coconut
def of(f, /, *args, **kwargs) = f(*args, **kwargs)
def call(f, /, *args, **kwargs) = f(*args, **kwargs)
```

`of` is primarily useful as an [operator function](#operator-functions) for function application when writing in a point-free style.
`call` is primarily useful as an [operator function](#operator-functions) for function application when writing in a point-free style.

**DEPRECATED:** `of` is available as a deprecated alias for `call`. Note that deprecated features are disabled in `--strict` mode.

### `const`

Expand Down
16 changes: 8 additions & 8 deletions __coconut__/__init__.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -180,40 +180,40 @@ def _coconut_tco(func: _Tfunc) -> _Tfunc:


@_t.overload
def _coconut_tail_call(
def call(
_func: _t.Callable[[_T], _Uco],
_x: _T,
) -> _Uco: ...
@_t.overload
def _coconut_tail_call(
def call(
_func: _t.Callable[[_T, _U], _Vco],
_x: _T,
_y: _U,
) -> _Vco: ...
@_t.overload
def _coconut_tail_call(
def call(
_func: _t.Callable[[_T, _U, _V], _Wco],
_x: _T,
_y: _U,
_z: _V,
) -> _Wco: ...
@_t.overload
def _coconut_tail_call(
def call(
_func: _t.Callable[_t.Concatenate[_T, _P], _Uco],
_x: _T,
*args: _t.Any,
**kwargs: _t.Any,
) -> _Uco: ...
@_t.overload
def _coconut_tail_call(
def call(
_func: _t.Callable[_t.Concatenate[_T, _U, _P], _Vco],
_x: _T,
_y: _U,
*args: _t.Any,
**kwargs: _t.Any,
) -> _Vco: ...
@_t.overload
def _coconut_tail_call(
def call(
_func: _t.Callable[_t.Concatenate[_T, _U, _V, _P], _Wco],
_x: _T,
_y: _U,
Expand All @@ -222,14 +222,14 @@ def _coconut_tail_call(
**kwargs: _t.Any,
) -> _Wco: ...
@_t.overload
def _coconut_tail_call(
def call(
_func: _t.Callable[..., _Tco],
*args: _t.Any,
**kwargs: _t.Any,
) -> _Tco: ...


of = _coconut_tail_call
_coconut_tail_call = of = call


def recursive_iterator(func: _T_iter_func) -> _T_iter_func:
Expand Down
18 changes: 13 additions & 5 deletions coconut/compiler/header.py
Original file line number Diff line number Diff line change
Expand Up @@ -272,21 +272,27 @@ def process_header_args(which, target, use_hash, no_tco, strict, no_wrap):
r'''def prepattern(base_func, **kwargs):
"""DEPRECATED: use addpattern instead."""
def pattern_prepender(func):
return addpattern(func, **kwargs)(base_func)
return addpattern(func, base_func, **kwargs)
return pattern_prepender'''
if not strict else
r'''def prepattern(*args, **kwargs):
"""Deprecated feature 'prepattern' disabled by --strict compilation; use 'addpattern' instead."""
raise _coconut.NameError("deprecated feature 'prepattern' disabled by --strict compilation; use 'addpattern' instead")'''
"""Deprecated built-in 'prepattern' disabled by --strict compilation; use 'addpattern' instead."""
raise _coconut.NameError("deprecated built-in 'prepattern' disabled by --strict compilation; use 'addpattern' instead")'''
),
def_datamaker=(
r'''def datamaker(data_type):
"""DEPRECATED: use makedata instead."""
return _coconut.functools.partial(makedata, data_type)'''
if not strict else
r'''def datamaker(*args, **kwargs):
"""Deprecated feature 'datamaker' disabled by --strict compilation; use 'makedata' instead."""
raise _coconut.NameError("deprecated feature 'datamaker' disabled by --strict compilation; use 'makedata' instead")'''
"""Deprecated built-in 'datamaker' disabled by --strict compilation; use 'makedata' instead."""
raise _coconut.NameError("deprecated built-in 'datamaker' disabled by --strict compilation; use 'makedata' instead")'''
),
of_is_call=(
"of = call" if not strict else
r'''def of(*args, **kwargs):
"""Deprecated built-in 'of' disabled by --strict compilation; use 'call' instead."""
raise _coconut.NameError("deprecated built-in 'of' disabled by --strict compilation; use 'call' instead")'''
),
return_method_of_self=pycondition(
(3,),
Expand Down Expand Up @@ -515,6 +521,8 @@ def __init__(self, func, aiter):
self.aiter = aiter
def __reduce__(self):
return (self.__class__, (self.func, self.aiter))
def __repr__(self):
return "fmap(" + _coconut.repr(self.func) + ", " + _coconut.repr(self.aiter) + ")"
def __aiter__(self):
return self
{async_def_anext}
Expand Down
9 changes: 5 additions & 4 deletions coconut/compiler/templates/header.py_template
Original file line number Diff line number Diff line change
Expand Up @@ -1221,6 +1221,8 @@ def fmap(func, obj, **kwargs):
starmap_over_mappings = kwargs.pop("starmap_over_mappings", False)
if kwargs:
raise _coconut.TypeError("fmap() got unexpected keyword arguments " + _coconut.repr(kwargs))
if obj is None:
return None
obj_fmap = _coconut.getattr(obj, "__fmap__", None)
if obj_fmap is not None:
try:
Expand All @@ -1230,8 +1232,6 @@ def fmap(func, obj, **kwargs):
else:
if result is not _coconut.NotImplemented:
return result
if obj.__class__ is None.__class__:
return None
if obj.__class__.__module__ in _coconut.jax_numpy_modules:
import jax.numpy as jnp
return jnp.vectorize(func)(obj)
Expand Down Expand Up @@ -1330,13 +1330,14 @@ def ident(x, **kwargs):
if side_effect is not None:
side_effect(x)
return x
def of(_coconut_f, *args, **kwargs):
def call(_coconut_f, *args, **kwargs):
"""Function application operator function.

Equivalent to:
def of(f, *args, **kwargs) = f(*args, **kwargs).
def call(f, /, *args, **kwargs) = f(*args, **kwargs).
"""
return _coconut_f(*args, **kwargs)
{of_is_call}
class flip(_coconut_base_hashable):
"""Given a function, return a new function with inverse argument order.
If nargs is passed, only the first nargs arguments are reversed."""
Expand Down
2 changes: 1 addition & 1 deletion coconut/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -614,7 +614,7 @@ def get_bool_env_var(env_var, default=False):
"override",
"flatten",
"ident",
"of",
"call",
"flip",
"const",
"lift",
Expand Down
2 changes: 1 addition & 1 deletion coconut/root.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
VERSION = "2.1.1"
VERSION_NAME = "The Spanish Inquisition"
# False for release, int >= 1 for develop
DEVELOP = 16
DEVELOP = 17
ALPHA = False # for pre releases rather than post releases

# -----------------------------------------------------------------------------------------------------------------------
Expand Down
4 changes: 2 additions & 2 deletions coconut/tests/src/cocotest/agnostic/main.coco
Original file line number Diff line number Diff line change
Expand Up @@ -953,7 +953,7 @@ def main_test() -> bool:
assert (a=1, b=2) == (1, 2) == (a:int=1, b=2)
assert (a=1, b: int = 2) == (1, 2) == (a: int=1, b: int=2)
assert "_namedtuple_of" in repr((a=1,))
assert "b=2" in repr <| of$(?, a=1, b=2)
assert "b=2" in repr <| call$(?, a=1, b=2)
assert lift((,), (.*2), (.**2))(3) == (6, 9)
assert_raises(-> (⁻)(1, 2), TypeError)
assert -1 == ⁻1
Expand Down Expand Up @@ -1230,7 +1230,7 @@ def main_test() -> bool:
x = 2
x |>= (3/.)
assert x == 3/2
assert (./2) |> (.`of`3) == 3/2
assert (./2) |> (.`call`3) == 3/2
assert 5 |> (.*2) |> (2/.) == 1/5 == 5 |> (2*.) |> (./2) |> (1/.)
def test_list():
\list = [1, 2, 3]
Expand Down
8 changes: 4 additions & 4 deletions coconut/tests/src/cocotest/agnostic/suite.coco
Original file line number Diff line number Diff line change
Expand Up @@ -746,12 +746,12 @@ def suite_test() -> bool:
class inh_A() `isinstance` A `isinstance` object = inh_A()
for maxdiff in (maxdiff1, maxdiff2, maxdiff3, maxdiff_):
assert maxdiff([7,1,4,5]) == 4, "failed for " + repr(maxdiff)
assert all(r == 4 for r in parallel_map(of$(?, [7,1,4,5]), [maxdiff1, maxdiff2, maxdiff3]))
assert all(r == 4 for r in parallel_map(call$(?, [7,1,4,5]), [maxdiff1, maxdiff2, maxdiff3]))
assert ret_ret_func(1) == ((), {"func": 1}) == ret_args_kwargs$(func=1)() # type: ignore
assert ret_args_kwargs$(?, func=2)(1) == ((1,), {"func": 2})
assert lift(ret_args_kwargs)(ident, plus1, times2, sq=square)(3) == ((3, 4, 6), {"sq": 9})
assert plus1 `of` 2 == 3
assert of(ret_args_kwargs, 1, 2, a=1, b=3) == ((1, 2), {"a": 1, "b": 3})
assert plus1 `call` 2 == 3
assert call(ret_args_kwargs, 1, 2, a=1, b=3) == ((1, 2), {"a": 1, "b": 3})
x = y = 2
starsum$ x y .. starproduct$ 2 2 <| 2 == 12
assert x_and_y(x=1) == (1, 1) == x_and_y(y=1)
Expand All @@ -771,7 +771,7 @@ def suite_test() -> bool:
match tree() in leaf(1):
assert False
x = y = -1
x `flip(of)` is_even or y = 2
x `flip(call)` is_even or y = 2
assert x == 2
assert y == -1
x `(x, f) -> f(x)` is_even or y = 3
Expand Down
10 changes: 6 additions & 4 deletions coconut/tests/src/extras.coco
Original file line number Diff line number Diff line change
Expand Up @@ -213,12 +213,14 @@ def test_convenience() -> bool:
assert parse("abc", "lenient") == "abc #1: abc"

setup()
assert "Deprecated feature 'prepattern' disabled by --strict compilation" not in parse("\n", mode="file")
assert "Deprecated feature 'datamaker' disabled by --strict compilation" not in parse("\n", mode="file")
assert "Deprecated built-in 'prepattern' disabled by --strict compilation" not in parse("\n", mode="file")
assert "Deprecated built-in 'datamaker' disabled by --strict compilation" not in parse("\n", mode="file")
assert "Deprecated built-in 'of' disabled by --strict compilation" not in parse("\n", mode="file")

setup(strict=True)
assert "Deprecated feature 'prepattern' disabled by --strict compilation" in parse("\n", mode="file")
assert "Deprecated feature 'datamaker' disabled by --strict compilation" in parse("\n", mode="file")
assert "Deprecated built-in 'prepattern' disabled by --strict compilation" in parse("\n", mode="file")
assert "Deprecated built-in 'datamaker' disabled by --strict compilation" in parse("\n", mode="file")
assert "Deprecated built-in 'of' disabled by --strict compilation" in parse("\n", mode="file")

assert_raises(-> parse("def f(x):\n \t pass"), CoconutStyleError)
assert_raises(-> parse("lambda x: x"), CoconutStyleError)
Expand Down

0 comments on commit eddc207

Please sign in to comment.