Merge branch 'contrib-cleanup'
This commit is contained in:
commit
9449584c7f
@ -1,60 +0,0 @@
|
||||
============
|
||||
Alias macros
|
||||
============
|
||||
|
||||
.. versionadded:: 0.12
|
||||
|
||||
The alias macro module provides the ``(defn-alias)`` and
|
||||
``(defmacro-alias)``, that were in Hy core previously.
|
||||
|
||||
|
||||
Macros
|
||||
======
|
||||
|
||||
|
||||
.. _defn-alias:
|
||||
|
||||
defn-alias
|
||||
------------------------
|
||||
|
||||
The ``defn-alias`` macro is much like ``defn``,
|
||||
with the distinction that instead of defining a function with a single
|
||||
name, these can also define aliases. Other than taking a list of
|
||||
symbols for function names as the first parameter, ``defn-alias``
|
||||
is no different from ``defn``.
|
||||
|
||||
.. code-block:: clj
|
||||
|
||||
=> (defn-alias [main-name alias] []
|
||||
... (print "Hello!"))
|
||||
=> (main-name)
|
||||
"Hello!"
|
||||
=> (alias)
|
||||
"Hello!"
|
||||
|
||||
|
||||
.. _defmacro-alias:
|
||||
|
||||
defmacro-alias
|
||||
--------------
|
||||
|
||||
``defmacro-alias`` is used to define macros with multiple names
|
||||
(aliases). The general format is ``(defmacro-alias [names] [parameters]
|
||||
expr)``. It creates multiple macros with the same parameter list and
|
||||
body, under the specified list of names.
|
||||
|
||||
The following example defines two macros, both of which allow the user
|
||||
to write code in infix notation.
|
||||
|
||||
.. code-block:: clj
|
||||
|
||||
=> (defmacro-alias [infix infi] [code]
|
||||
... (quasiquote (
|
||||
... (unquote (get code 1))
|
||||
... (unquote (get code 0))
|
||||
... (unquote (get code 2)))))
|
||||
|
||||
=> (infix (1 + 1))
|
||||
2
|
||||
=> (infi (1 + 1))
|
||||
2
|
@ -1,58 +0,0 @@
|
||||
==========
|
||||
Flow
|
||||
==========
|
||||
|
||||
.. versionadded:: 0.10.1
|
||||
|
||||
The ``flow`` macros allow directing the flow of a program with greater ease.
|
||||
|
||||
|
||||
Macros
|
||||
======
|
||||
|
||||
.. _case:
|
||||
.. _switch:
|
||||
|
||||
case
|
||||
-----
|
||||
|
||||
``case`` allows you to decide based on the value of a variable.
|
||||
|
||||
|
||||
Usage: `(case variable val1 (body1) val2 (body2) ...)`
|
||||
|
||||
Example:
|
||||
|
||||
.. code-block:: hy
|
||||
|
||||
(require [hy.contrib.flow [case]])
|
||||
|
||||
(defn temp-commenter [temp]
|
||||
(case temp
|
||||
-10 (print "It's freezing. Turn up the thermostat!")
|
||||
15 (print "Sounds about average.")
|
||||
45 (print "Holy smokes. It's hot in here!")
|
||||
(print "I don't even know.")))
|
||||
|
||||
|
||||
switch
|
||||
-----
|
||||
|
||||
``switch`` allows you to run code based on the value of a variable.
|
||||
A final extra body allows for a default case.
|
||||
|
||||
|
||||
Usage: `(switch var (cond1) (body1) (cond2) (body2) ... )`
|
||||
|
||||
Example:
|
||||
|
||||
.. code-block:: hy
|
||||
|
||||
(require [hy.contrib.flow [switch]])
|
||||
|
||||
(defn temp-commenter [temp]
|
||||
(switch temp
|
||||
(<= 10.0) (print "Better wear a jacket!")
|
||||
(<= 25.0) (print "Brace yourselves. Summer is coming!")
|
||||
(<= 30.0) (print "Time to get some ice cream.")
|
||||
(print "Sounds like a heat wave")))
|
@ -2,14 +2,15 @@
|
||||
Contributor Modules Index
|
||||
=========================
|
||||
|
||||
These modules are experimental additions to Hy. Once deemed mature,
|
||||
they will be moved to the ``hy.extra`` namespace or loaded by
|
||||
default.
|
||||
|
||||
Contents:
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 3
|
||||
|
||||
alias
|
||||
anaphoric
|
||||
flow
|
||||
loop
|
||||
multi
|
||||
profile
|
||||
|
@ -13,9 +13,9 @@ concise and easy to read.
|
||||
|
||||
-- Wikipedia (https://en.wikipedia.org/wiki/Anaphoric_macro)
|
||||
|
||||
To use these macros you need to require the hy.contrib.anaphoric module like so:
|
||||
To use these macros you need to require the ``hy.extra.anaphoric`` module like so:
|
||||
|
||||
``(require [hy.contrib.anaphoric [*]])``
|
||||
``(require [hy.extra.anaphoric [*]])``
|
||||
|
||||
.. _ap-if:
|
||||
|
14
docs/extra/index.rst
Normal file
14
docs/extra/index.rst
Normal file
@ -0,0 +1,14 @@
|
||||
===================
|
||||
Extra Modules Index
|
||||
===================
|
||||
|
||||
These modules are considered no less stable than Hy's built-in
|
||||
functions and macros, but they need to be loaded with ``(import
|
||||
...)`` or ``(require ...)``.
|
||||
|
||||
Contents:
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 3
|
||||
|
||||
anaphoric
|
@ -34,5 +34,6 @@ Contents:
|
||||
tutorial
|
||||
style-guide
|
||||
language/index
|
||||
extra/index
|
||||
contrib/index
|
||||
hacking
|
||||
|
@ -1,39 +0,0 @@
|
||||
;; Copyright (c) 2014, 2015 Gergely Nagy
|
||||
;; Copyright (c) 2014, 2015 Paul Tagliamonte <paultag@debian.org>
|
||||
|
||||
;; Permission is hereby granted, free of charge, to any person obtaining a
|
||||
;; copy of this software and associated documentation files (the "Software"),
|
||||
;; to deal in the Software without restriction, including without limitation
|
||||
;; the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
;; and/or sell copies of the Software, and to permit persons to whom the
|
||||
;; Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
;; The above copyright notice and this permission notice shall be included in
|
||||
;; all copies or substantial portions of the Software.
|
||||
|
||||
;; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
;; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
;; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
;; THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
;; LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
;; FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
;; DEALINGS IN THE SOFTWARE.
|
||||
|
||||
(defmacro defmacro-alias [names lambda-list &rest body]
|
||||
"define one macro with several names"
|
||||
(setv ret `(do))
|
||||
(for* [name names]
|
||||
(.append ret
|
||||
`(defmacro ~name ~lambda-list ~@body)))
|
||||
ret)
|
||||
|
||||
|
||||
(defmacro defn-alias [names lambda-list &rest body]
|
||||
"define one function with several names"
|
||||
(let [main (first names)
|
||||
aliases (rest names)]
|
||||
(setv ret `(do (defn ~main ~lambda-list ~@body)))
|
||||
(for* [name aliases]
|
||||
(.append ret
|
||||
`(setv ~name ~main)))
|
||||
ret))
|
@ -1,21 +0,0 @@
|
||||
(import inspect functools sys)
|
||||
|
||||
|
||||
(defn curry [func]
|
||||
(let [sig (.getargspec inspect func)
|
||||
count (len sig.args)]
|
||||
|
||||
(fn [&rest args]
|
||||
(if (< (len args) count)
|
||||
(apply functools.partial (+ [(curry func)] (list args)))
|
||||
(apply func args)))))
|
||||
|
||||
|
||||
(defmacro fnc [args &rest body]
|
||||
`(do (import hy.contrib.curry)
|
||||
(with-decorator hy.contrib.curry.curry (fn [~@args] ~@body))))
|
||||
|
||||
|
||||
(defmacro defnc [name args &rest body]
|
||||
`(do (require hy.contrib.curry)
|
||||
(def ~name (hy.contrib.curry.fnc [~@args] ~@body))))
|
@ -1,50 +0,0 @@
|
||||
# -*- encoding: utf-8 -*-
|
||||
#
|
||||
# Decorator for defmulti
|
||||
#
|
||||
# Copyright (c) 2014 Morten Linderud <mcfoxax@gmail.com>
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a
|
||||
# copy of this software and associated documentation files (the "Software"),
|
||||
# to deal in the Software without restriction, including without limitation
|
||||
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
# and/or sell copies of the Software, and to permit persons to whom the
|
||||
# Software is furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
# DEALINGS IN THE SOFTWARE.
|
||||
|
||||
from collections import defaultdict
|
||||
|
||||
|
||||
class MultiDispatch(object):
|
||||
_fns = defaultdict(dict)
|
||||
|
||||
def __init__(self, fn):
|
||||
self.fn = fn
|
||||
self.__doc__ = fn.__doc__
|
||||
if fn.__name__ not in self._fns[fn.__module__].keys():
|
||||
self._fns[fn.__module__][fn.__name__] = {}
|
||||
values = fn.__code__.co_varnames
|
||||
self._fns[fn.__module__][fn.__name__][values] = fn
|
||||
|
||||
def is_fn(self, v, args, kwargs):
|
||||
"""Compare the given (checked fn) too the called fn"""
|
||||
com = list(args) + list(kwargs.keys())
|
||||
if len(com) == len(v):
|
||||
return all([kw in com for kw in kwargs.keys()])
|
||||
return False
|
||||
|
||||
def __call__(self, *args, **kwargs):
|
||||
for i, fn in self._fns[self.fn.__module__][self.fn.__name__].items():
|
||||
if self.is_fn(i, args, kwargs):
|
||||
return fn(*args, **kwargs)
|
||||
raise TypeError("No matching functions with this signature!")
|
@ -1,24 +0,0 @@
|
||||
;; Additional flow macros
|
||||
|
||||
|
||||
(defmacro/g! switch [variable &rest args]
|
||||
(setv g!comp (car args))
|
||||
(setv g!body (car (cdr args)))
|
||||
(setv g!rest (cdr (cdr args)))
|
||||
(setv g!cond `(~(car g!comp) ~variable ~@(cdr g!comp)))
|
||||
(if g!rest
|
||||
(if (cdr g!rest)
|
||||
`(if ~g!cond ~g!body (switch ~variable ~@g!rest))
|
||||
`(if ~g!cond ~g!body ~@g!rest))
|
||||
`(if ~g!cond ~g!body)))
|
||||
|
||||
(defmacro/g! case [variable &rest args]
|
||||
(setv g!value (car args))
|
||||
(setv g!body (car (cdr args)))
|
||||
(setv g!rest (cdr (cdr args)))
|
||||
(setv g!cond `(= ~variable ~g!value))
|
||||
(if g!rest
|
||||
(if (cdr g!rest)
|
||||
`(if ~g!cond ~g!body (case ~variable ~@g!rest))
|
||||
`(if ~g!cond ~g!body ~@g!rest))
|
||||
`(if ~g!cond ~g!body)))
|
@ -1,31 +0,0 @@
|
||||
;;; Hy on Meth
|
||||
;;; based on paultag's meth library to access a Flask based application
|
||||
|
||||
(defmacro route-with-methods [name path methods params &rest code]
|
||||
"Same as route but with an extra methods array to specify HTTP methods"
|
||||
`(let [deco (apply app.route [~path]
|
||||
{"methods" ~methods})]
|
||||
(with-decorator deco
|
||||
(defn ~name ~params
|
||||
(do ~@code)))))
|
||||
|
||||
(defn rwm [name path method params code]
|
||||
`(do (require hy.contrib.meth)
|
||||
(hy.contrib.meth.route-with-methods ~name ~path ~method ~params ~@code)))
|
||||
|
||||
;; Some macro examples
|
||||
(defmacro route [name path params &rest code]
|
||||
"Get request"
|
||||
(rwm name path ["GET"] params code))
|
||||
|
||||
(defmacro post-route [name path params &rest code]
|
||||
"Post request"
|
||||
(rwm name path ["POST"] params code))
|
||||
|
||||
(defmacro put-route [name path params &rest code]
|
||||
"Put request"
|
||||
(rwm name path ["PUT"] params code))
|
||||
|
||||
(defmacro delete-route [name path params &rest code]
|
||||
"Delete request"
|
||||
(rwm name path ["DELETE"] params code))
|
@ -25,6 +25,35 @@
|
||||
[hy.models.list [HyList]]
|
||||
[hy.models.string [HyString]])
|
||||
|
||||
(defclass MultiDispatch [object] [
|
||||
|
||||
_fns (defaultdict dict)
|
||||
|
||||
__init__ (fn [self f]
|
||||
(setv self.f f)
|
||||
(setv self.__doc__ f.__doc__)
|
||||
(unless (in f.__name__ (.keys (get self._fns f.__module__)))
|
||||
(setv (get self._fns f.__module__ f.__name__) {}))
|
||||
(setv values f.__code__.co_varnames)
|
||||
(setv (get self._fns f.__module__ f.__name__ values) f))
|
||||
|
||||
fn? (fn [self v args kwargs]
|
||||
"Compare the given (checked fn) to the called fn"
|
||||
(setv com (+ (list args) (list (.keys kwargs))))
|
||||
(and
|
||||
(= (len com) (len v))
|
||||
(.issubset (frozenset (.keys kwargs)) com)))
|
||||
|
||||
__call__ (fn [self &rest args &kwargs kwargs]
|
||||
(setv output None)
|
||||
(for [[i f] (.items (get self._fns self.f.__module__ self.f.__name__))]
|
||||
(when (.fn? self i args kwargs)
|
||||
(setv output (apply f args kwargs))
|
||||
(break)))
|
||||
(if output
|
||||
output
|
||||
(raise (TypeError "No matching functions with this signature"))))])
|
||||
|
||||
(defn multi-decorator [dispatch-fn]
|
||||
(setv inner (fn [&rest args &kwargs kwargs]
|
||||
(setv dispatch-key (apply dispatch-fn args kwargs))
|
||||
@ -73,7 +102,7 @@
|
||||
(do (def comment (car bodies))
|
||||
(def bodies (cdr bodies))))
|
||||
(def ret `(do))
|
||||
(.append ret '(import [hy.contrib.dispatch [MultiDispatch]]))
|
||||
(.append ret '(import [hy.contrib.multi [MultiDispatch]]))
|
||||
(for [body bodies]
|
||||
(def let-binds (car body))
|
||||
(def body (cdr body))
|
||||
|
0
hy/extra/__init__.py
Normal file
0
hy/extra/__init__.py
Normal file
@ -1,5 +1,3 @@
|
||||
# for Botsbuildbots
|
||||
requests
|
||||
# code quality
|
||||
flake8
|
||||
coverage
|
||||
|
@ -14,13 +14,10 @@ from .native_tests.core import * # noqa
|
||||
from .native_tests.reader_macros import * # noqa
|
||||
from .native_tests.shadow import * # noqa
|
||||
from .native_tests.with_test import * # noqa
|
||||
from .native_tests.contrib.anaphoric import * # noqa
|
||||
from .native_tests.extra.anaphoric import * # noqa
|
||||
from .native_tests.contrib.loop import * # noqa
|
||||
from .native_tests.contrib.meth import * # noqa
|
||||
from .native_tests.contrib.walk import * # noqa
|
||||
from .native_tests.contrib.multi import * # noqa
|
||||
from .native_tests.contrib.curry import * # noqa
|
||||
from .native_tests.contrib.botsbuildbots import * # noqa
|
||||
from .native_tests.contrib.sequences import * # noqa
|
||||
|
||||
if PY3:
|
||||
|
@ -1,8 +0,0 @@
|
||||
(require [hy.contrib.alias [defn-alias]])
|
||||
|
||||
(defn test-defn-alias []
|
||||
(defn-alias [tda-main tda-a1 tda-a2] [] :bazinga)
|
||||
(assert (= (tda-main) :bazinga))
|
||||
(assert (= (tda-a1) :bazinga))
|
||||
(assert (= (tda-a2) :bazinga))
|
||||
(assert (= tda-main tda-a1 tda-a2)))
|
@ -1,4 +0,0 @@
|
||||
(require [hy.contrib.botsbuildbots [Botsbuildbots]])
|
||||
|
||||
(defn test-botsbuildbots []
|
||||
(assert (> (len (first (Botsbuildbots))) 50)))
|
@ -1,13 +0,0 @@
|
||||
(require [hy.contrib.curry [defnc]])
|
||||
|
||||
|
||||
(defnc s [x y z] ((x z) (y z))) ; λxyz.xz(yz)
|
||||
(defnc k [x] (fn [y] x)) ; λx.λy.x
|
||||
(defnc i [x] x) ;; λx.x
|
||||
|
||||
(defnc succ [n] (+ n 1))
|
||||
|
||||
|
||||
(defn test-curry []
|
||||
(assert (= 16 (((((s ((((k s) k) i) i)) (i i)) ((i (i i))
|
||||
((((k s) i) ((s (k s)) k)) i))) succ) 0))))
|
@ -1,53 +0,0 @@
|
||||
(require [hy.contrib.meth [route post-route put-route delete-route]])
|
||||
|
||||
(defclass FakeMeth []
|
||||
"Mocking decorator class"
|
||||
[rules {}]
|
||||
(defn route [self rule &kwargs options]
|
||||
(fn [f]
|
||||
(assoc self.rules rule (, f options))
|
||||
f)))
|
||||
|
||||
(defn test_route []
|
||||
(let [app (FakeMeth)]
|
||||
(route get-index "/" [] (str "Hy world!"))
|
||||
(setv app-rules (getattr app "rules"))
|
||||
(assert (in "/" app-rules))
|
||||
(let [(, rule-fun rule-opt) (get app-rules "/")]
|
||||
(assert (not (empty? rule-opt)))
|
||||
(assert (in "GET" (get rule-opt "methods")))
|
||||
(assert (= (getattr rule-fun "__name__") "get_index"))
|
||||
(assert (= "Hy world!" (rule-fun))))))
|
||||
|
||||
(defn test_post_route []
|
||||
(let [app (FakeMeth)]
|
||||
(post-route get-index "/" [] (str "Hy world!"))
|
||||
(setv app-rules (getattr app "rules"))
|
||||
(assert (in "/" app-rules))
|
||||
(let [(, rule-fun rule-opt) (get app-rules "/")]
|
||||
(assert (not (empty? rule-opt)))
|
||||
(assert (in "POST" (get rule-opt "methods")))
|
||||
(assert (= (getattr rule-fun "__name__") "get_index"))
|
||||
(assert (= "Hy world!" (rule-fun))))))
|
||||
|
||||
(defn test_put_route []
|
||||
(let [app (FakeMeth)]
|
||||
(put-route get-index "/" [] (str "Hy world!"))
|
||||
(setv app-rules (getattr app "rules"))
|
||||
(assert (in "/" app-rules))
|
||||
(let [(, rule-fun rule-opt) (get app-rules "/")]
|
||||
(assert (not (empty? rule-opt)))
|
||||
(assert (in "PUT" (get rule-opt "methods")))
|
||||
(assert (= (getattr rule-fun "__name__") "get_index"))
|
||||
(assert (= "Hy world!" (rule-fun))))))
|
||||
|
||||
(defn test_delete_route []
|
||||
(let [app (FakeMeth)]
|
||||
(delete-route get-index "/" [] (str "Hy world!"))
|
||||
(setv app-rules (getattr app "rules"))
|
||||
(assert (in "/" app-rules))
|
||||
(let [(, rule-fun rule-opt) (get app-rules "/")]
|
||||
(assert (not (empty? rule-opt)))
|
||||
(assert (in "DELETE" (get rule-opt "methods")))
|
||||
(assert (= (getattr rule-fun "__name__") "get_index"))
|
||||
(assert (= "Hy world!" (rule-fun))))))
|
0
tests/native_tests/extra/__init__.hy
Normal file
0
tests/native_tests/extra/__init__.hy
Normal file
@ -19,7 +19,7 @@
|
||||
;; DEALINGS IN THE SOFTWARE.
|
||||
|
||||
(import [hy.errors [HyMacroExpansionError]])
|
||||
(require [hy.contrib.anaphoric [*]])
|
||||
(require [hy.extra.anaphoric [*]])
|
||||
|
||||
;;;; some simple helpers
|
||||
|
Loading…
Reference in New Issue
Block a user