Skip to content

Commit

Permalink
Improve builtins
Browse files Browse the repository at this point in the history
Resolves   #692, #693.
  • Loading branch information
evhub committed Dec 30, 2022
1 parent c82b426 commit 990bf78
Show file tree
Hide file tree
Showing 8 changed files with 136 additions and 37 deletions.
140 changes: 110 additions & 30 deletions DOCS.md

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions _coconut/__init__.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@ TypeError = TypeError
ValueError = ValueError
StopIteration = StopIteration
RuntimeError = RuntimeError
callable = callable
classmethod = classmethod
all = all
any = any
Expand Down
4 changes: 2 additions & 2 deletions coconut/compiler/compiler.py
Original file line number Diff line number Diff line change
Expand Up @@ -3963,9 +3963,9 @@ def parse_eval(self, inputstring, **kwargs):
"""Parse eval code."""
return self.parse(inputstring, self.eval_parser, {"strip": True}, {"header": "none", "initial": "none", "final_endline": False}, **kwargs)

def parse_lenient(self, inputstring, **kwargs):
def parse_lenient(self, inputstring, newline=False, **kwargs):
"""Parse any code."""
return self.parse(inputstring, self.file_parser, {"strip": True}, {"header": "none", "initial": "none", "final_endline": False}, **kwargs)
return self.parse(inputstring, self.file_parser, {"strip": True}, {"header": "none", "initial": "none", "final_endline": newline}, **kwargs)

def parse_xonsh(self, inputstring, **kwargs):
"""Parse xonsh code."""
Expand Down
15 changes: 12 additions & 3 deletions coconut/compiler/templates/header.py_template
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ def _coconut_super(type=None, object_or_type=None):
numpy_modules = {numpy_modules}
jax_numpy_modules = {jax_numpy_modules}
abc.Sequence.register(collections.deque)
Ellipsis, NotImplemented, NotImplementedError, Exception, AttributeError, ImportError, IndexError, NameError, TypeError, ValueError, StopIteration, RuntimeError, all, any, bytes, classmethod, dict, enumerate, filter, float, frozenset, getattr, hasattr, hash, id, int, isinstance, issubclass, iter, len, list, locals, map, min, max, next, object, property, range, reversed, set, setattr, slice, str, sum, super, tuple, type, vars, zip, repr, print{comma_bytearray} = Ellipsis, NotImplemented, NotImplementedError, Exception, AttributeError, ImportError, IndexError, NameError, TypeError, ValueError, StopIteration, RuntimeError, all, any, bytes, classmethod, dict, enumerate, filter, float, frozenset, getattr, hasattr, hash, id, int, isinstance, issubclass, iter, len, list, locals, map, min, max, next, object, property, range, reversed, set, setattr, slice, str, sum, {lstatic}super{rstatic}, tuple, type, vars, zip, {lstatic}repr{rstatic}, {lstatic}print{rstatic}{comma_bytearray}
Ellipsis, NotImplemented, NotImplementedError, Exception, AttributeError, ImportError, IndexError, NameError, TypeError, ValueError, StopIteration, RuntimeError, all, any, bytes, callable, classmethod, dict, enumerate, filter, float, frozenset, getattr, hasattr, hash, id, int, isinstance, issubclass, iter, len, list, locals, map, min, max, next, object, property, range, reversed, set, setattr, slice, str, sum, super, tuple, type, vars, zip, repr, print{comma_bytearray} = Ellipsis, NotImplemented, NotImplementedError, Exception, AttributeError, ImportError, IndexError, NameError, TypeError, ValueError, StopIteration, RuntimeError, all, any, bytes, callable, classmethod, dict, enumerate, filter, float, frozenset, getattr, hasattr, hash, id, int, isinstance, issubclass, iter, len, list, locals, map, min, max, next, object, property, range, reversed, set, setattr, slice, str, sum, {lstatic}super{rstatic}, tuple, type, vars, zip, {lstatic}repr{rstatic}, {lstatic}print{rstatic}{comma_bytearray}
class _coconut_sentinel{object}:
__slots__ = ()
class _coconut_base_hashable{object}:
Expand Down Expand Up @@ -1230,6 +1230,8 @@ 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 All @@ -1248,10 +1250,17 @@ def fmap(func, obj, **kwargs):
return _coconut_base_makedata(obj.__class__, _coconut_starmap(func, obj.items()) if _coconut.isinstance(obj, _coconut.abc.Mapping) else _coconut_map(func, obj))
else:
return _coconut_base_makedata(obj.__class__, _coconut_map(func, obj.items() if _coconut.isinstance(obj, _coconut.abc.Mapping) else obj))
def memoize(maxsize=None, *args, **kwargs):
def _coconut_memoize_helper(maxsize=None, typed=False):
return maxsize, typed
def memoize(*args, **kwargs):
"""Decorator that memoizes a function, preventing it from being recomputed
if it is called multiple times with the same arguments."""
return _coconut.functools.lru_cache(maxsize, *args, **kwargs)
if not kwargs and _coconut.len(args) == 1 and _coconut.callable(args[0]):
return _coconut.functools.lru_cache(maxsize=None)(args[0])
if _coconut.len(kwargs) == 1 and "user_function" in kwargs and _coconut.callable(kwargs["user_function"]):
return _coconut.functools.lru_cache(maxsize=None)(kwargs["user_function"])
maxsize, typed = _coconut_memoize_helper(*args, **kwargs)
return _coconut.functools.lru_cache(maxsize, typed)
{def_call_set_names}
class override(_coconut_base_hashable):
__slots__ = ("func",)
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 = 15
DEVELOP = 16
ALPHA = False # for pre releases rather than post releases

# -----------------------------------------------------------------------------------------------------------------------
Expand Down
1 change: 1 addition & 0 deletions coconut/tests/src/cocotest/agnostic/main.coco
Original file line number Diff line number Diff line change
Expand Up @@ -1259,6 +1259,7 @@ def main_test() -> bool:
assert cartesian_product(v, v).count((2, 1)) == 1 == cartesian_product(v, repeat=2).count((2, 1))
assert cartesian_product(v, v).count((2, 0)) == 0 == cartesian_product(v, repeat=2).count((2, 0))
assert not range(0, 0)
assert None |> fmap$(.+1) is None
return True

def test_asyncio() -> bool:
Expand Down
1 change: 1 addition & 0 deletions coconut/tests/src/cocotest/agnostic/suite.coco
Original file line number Diff line number Diff line change
Expand Up @@ -558,6 +558,7 @@ def suite_test() -> bool:
assert sum2([3, 4]) == 7
assert ridiculously_recursive(300) == 201666561657114122540576123152528437944095370972927688812965354745141489205495516550423117825 == ridiculously_recursive_(300)
assert [fib(n) for n in range(16)] == [0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610] == [fib_(n) for n in range(16)]
assert [fib_alt1(n) for n in range(16)] == [0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610] == [fib_alt2(n) for n in range(16)]
assert fib.cache_info().hits == 28
fib_N = 100
assert range(fib_N) |> map$(fib) |> .$[-1] == fibs()$[fib_N-2] == fib_(fib_N-1) == fibs_()$[fib_N-2]
Expand Down
9 changes: 8 additions & 1 deletion coconut/tests/src/cocotest/agnostic/util.coco
Original file line number Diff line number Diff line change
Expand Up @@ -1146,7 +1146,6 @@ def ridiculously_recursive_(n):
return result

def fib(n if n < 2) = n

@memoize() # type: ignore
addpattern def fib(n) = fib(n-1) + fib(n-2) # type: ignore

Expand All @@ -1155,6 +1154,14 @@ def Fibs() = (0, 1) :: map((+), Fibs(), Fibs()$[1:])

fib_ = reiterable(Fibs())$[]

def fib_alt1(n if n < 2) = n
@memoize # type: ignore
addpattern def fib_alt1(n) = fib_alt1(n-1) + fib_alt1(n-2) # type: ignore

def fib_alt2(n if n < 2) = n
@memoize$(user_function=?) # type: ignore
addpattern def fib_alt2(n) = fib_alt2(n-1) + fib_alt2(n-2) # type: ignore

# MapReduce
from collections import defaultdict

Expand Down

0 comments on commit 990bf78

Please sign in to comment.