Merge pull request #1438 from ekaschalk/docstrings

Standardize hy.core docstrings
This commit is contained in:
Kodi Arfer 2017-10-17 13:22:58 -07:00 committed by GitHub
commit e0e850645d
5 changed files with 158 additions and 124 deletions

View File

@ -84,3 +84,4 @@
* Andrew Silva <asilva@law.harvard.edu>
* Zaheer Soebhan <z.soebhan@gmail.com>
* Rob Day <rkd@rkd.me.uk>
* Eric Kaschalk <ekaschalk@gmail.com>

View File

@ -7,7 +7,7 @@
;;; They are automatically required everywhere, even inside hy.core modules.
(defmacro if [&rest args]
"if with elif"
"Conditionally evaluate alternating test and then expressions."
(setv n (len args))
(if* n
(if* (= n 1)
@ -17,11 +17,11 @@
(if ~@(cut args 2))))))
(defmacro macro-error [location reason]
"error out properly within a macro"
"Error out properly within a macro at `location` giving `reason`."
`(raise (hy.errors.HyMacroExpansionError ~location ~reason)))
(defmacro defn [name lambda-list &rest body]
"define a function `name` with signature `lambda-list` and body `body`"
"Define `name` as a function with `lambda-list` signature and body `body`."
(import hy)
(if (not (= (type name) hy.HySymbol))
(macro-error name "defn takes a name as first argument"))

View File

@ -22,15 +22,15 @@
(import [hy.importer [hy-eval :as eval]])
(defn butlast [coll]
"Returns coll except of last element."
"Return an iterator of all but the last item in `coll`."
(drop-last 1 coll))
(defn coll? [coll]
"Checks whether item is a collection"
"Check if `coll` is iterable and not a string."
(and (iterable? coll) (not (string? coll))))
(defn comp [&rest fs]
"Function composition"
"Return the function from composing the given functions `fs`."
(if (not fs) identity
(= 1 (len fs)) (first fs)
(do (setv rfs (reversed fs)
@ -43,35 +43,36 @@
res))))
(defn complement [f]
"Create a function that reverses truth value of another function"
"Returns a new function that returns the logically inverted result of `f`."
(fn [&rest args &kwargs kwargs]
(not (f #* args #** kwargs))))
(defn cons [a b]
"Return a fresh cons cell with car = a and cdr = b"
"Return a fresh cons cell with car = `a` and cdr = `b`."
(HyCons a b))
(defn cons? [c]
"Check whether c can be used as a cons object"
"Check whether `c` is a cons cell."
(instance? HyCons c))
(defn constantly [value]
"Create a function that always returns the same value"
"Create a new function that always returns `value` regardless of its input."
(fn [&rest args &kwargs kwargs]
value))
(defn keyword? [k]
"Check whether k is a keyword"
"Check whether `k` is a keyword."
(and (instance? (type :foo) k)
(.startswith k (get :foo 0))))
(defn dec [n]
"Decrement n by 1"
"Decrement `n` by 1."
(- n 1))
(defn disassemble [tree &optional [codegen False]]
"Return the python AST for a quoted Hy tree as a string.
If the second argument is true, generate python code instead."
"Return the python AST for a quoted Hy `tree` as a string.
If the second argument `codegen` is true, generate python code instead."
(import astor)
(import hy.compiler)
@ -83,8 +84,7 @@
compiled))
(defn distinct [coll]
"Return a generator from the original collection with duplicates
removed"
"Return a generator from the original collection `coll` with no duplicates."
(setv seen (set) citer (iter coll))
(for* [val citer]
(if (not_in val seen)
@ -121,9 +121,8 @@
(defn exec [$code &optional $globals $locals]
"Execute Python code.
The parameter names contain weird characters to discourage calling this
function with keyword arguments, which isn't supported by Python 3's
`exec`."
The parameter names contain weird characters to discourage calling this
function with keyword arguments, which isn't supported by Python 3's `exec`."
(if
(none? $globals) (do
(setv frame (._getframe sys (int 1)))
@ -161,9 +160,9 @@
;; also from itertools, but not in Python2, and without func option until 3.3
(defn accumulate [iterable &optional [func operator.add]]
"accumulate(iterable[, func]) --> accumulate object
"Accumulate `func` on `iterable`.
Return series of accumulated sums (or other binary function results)."
Return series of accumulated sums (or other binary function results)."
(setv it (iter iterable)
total (next it))
(yield total)
@ -172,29 +171,29 @@
(yield total)))
(defn drop [count coll]
"Drop `count` elements from `coll` and yield back the rest"
"Drop `count` elements from `coll` and yield back the rest."
(islice coll count None))
(defn drop-last [n coll]
"Return a sequence of all but the last n elements in coll."
"Return a sequence of all but the last `n` elements in `coll`."
(setv iters (tee coll))
(map first (zip #* [(get iters 0)
(drop n (get iters 1))])))
(defn empty? [coll]
"Return True if `coll` is empty"
"Check if `coll` is empty."
(= 0 (len coll)))
(defn even? [n]
"Return true if n is an even number"
"Check if `n` is an even number."
(= (% n 2) 0))
(defn every? [pred coll]
"Return true if (pred x) is logical true for every x in coll, else false"
"Check if `pred` is true applied to every x in `coll`."
(all (map pred coll)))
(defn flatten [coll]
"Return a single flat list expanding all members of coll"
"Return a single flat list expanding all members of `coll`."
(if (coll? coll)
(_flatten coll [])
(raise (TypeError (.format "{0!r} is not a collection" coll)))))
@ -207,11 +206,11 @@
result)
(defn float? [x]
"Return True if x is float"
"Check if x is float."
(isinstance x float))
(defn symbol? [s]
"Check whether s is a symbol"
"Check if `s` is a symbol."
(instance? HySymbol s))
(import [threading [Lock]])
@ -219,6 +218,7 @@
(setv _gensym_lock (Lock))
(defn gensym [&optional [g "G"]]
"Generate a unique symbol for use in macros without accidental name clashes."
(setv new_symbol None)
(global _gensym_counter)
(global _gensym_lock)
@ -237,93 +237,95 @@
(get f.f_globals "__name__"))
(defn first [coll]
"Return first item from `coll`"
"Return first item from `coll`."
(next (iter coll) None))
(defn identity [x]
"Returns the argument unchanged"
"Return `x`."
x)
(defn inc [n]
"Increment n by 1"
"Increment `n` by 1."
(+ n 1))
(defn instance? [klass x]
"Perform `isinstance` with reversed arguments."
(isinstance x klass))
(defn integer [x]
"Return Hy kind of integer"
"Return Hy kind of integer for `x`."
(long-type x))
(defn integer? [x]
"Return True if x is an integer"
"Check if `x` is an integer."
(isinstance x (, int long-type)))
(defn integer-char? [x]
"Return True if char `x` parses as an integer"
"Check if char `x` parses as an integer."
(try
(integer? (int x))
(except [ValueError] False)
(except [TypeError] False)))
(defn interleave [&rest seqs]
"Return an iterable of the first item in each of seqs, then the second etc."
"Return an iterable of the first item in each of `seqs`, then the second etc."
(chain.from-iterable (zip #* seqs)))
(defn interpose [item seq]
"Return an iterable of the elements of seq separated by item"
"Return an iterable of the elements of `seq` separated by `item`."
(drop 1 (interleave (repeat item) seq)))
(defn iterable? [x]
"Return true if x is iterable"
"Check if `x` is an iterable."
(isinstance x collections.Iterable))
(defn iterate [f x]
"Returns an iterator repeatedly applying `f` to seed `x`.. x, f(x), f(f(x))..."
(setv val x)
(while True
(yield val)
(setv val (f val))))
(defn iterator? [x]
"Return true if x is an iterator"
"Check if `x` is an iterator."
(isinstance x collections.Iterator))
(defn juxt [f &rest fs]
"Return a function that applies each of the supplied functions to a single
set of arguments and collects the results into a list."
"Return a function applying each `fs` to args, collecting results in a list."
(setv fs (cons f fs))
(fn [&rest args &kwargs kwargs]
(list-comp (f #* args #** kwargs) [f fs])))
(defn last [coll]
"Return last item from `coll`"
"Return last item from `coll`."
(get (tuple coll) -1))
(defn list* [hd &rest tl]
"Return a dotted list construed from the elements of the argument"
"Return a chain of nested cons cells (dotted list) containing `hd` and `tl`."
(if (not tl)
hd
(cons hd (list* #* tl))))
(defn macroexpand [form]
"Return the full macro expansion of form"
"Return the full macro expansion of `form`."
(import hy.macros)
(setv name (calling-module-name))
(hy.macros.macroexpand form (HyASTCompiler name)))
(defn macroexpand-1 [form]
"Return the single step macro expansion of form"
"Return the single step macro expansion of `form`."
(import hy.macros)
(setv name (calling-module-name))
(hy.macros.macroexpand-1 form (HyASTCompiler name)))
(defn merge-with [f &rest maps]
"Returns a map that consists of the rest of the maps joined onto
the first. If a key occurs in more than one map, the mapping(s)
from the latter (left-to-right) will be combined with the mapping in
the result by calling (f val-in-result val-in-latter)."
"Return the map of `maps` joined onto the first via the function `f`.
If a key occurs in more than one map, the mapping(s) from the latter
(left-to-right) will be combined with the mapping in the result by calling
(f val-in-result val-in-latter)."
(if (any maps)
(do
(defn merge-entry [m e]
@ -337,31 +339,33 @@
(reduce merge2 maps))))
(defn neg? [n]
"Return true if n is < 0"
"Check if `n` is < 0."
(< n 0))
(defn none? [x]
"Return true if x is None"
"Check if `x` is None"
(is x None))
(defn numeric? [x]
"Check if `x` is an instance of numbers.Number."
(import numbers)
(instance? numbers.Number x))
(defn nth [coll n &optional [default None]]
"Return nth item in collection or sequence, counting from 0.
Return None if out of bounds unless specified otherwise."
"Return `n`th item in `coll` or None (specify `default`) if out of bounds."
(next (drop n coll) default))
(defn odd? [n]
"Return true if n is an odd number"
"Check if `n` is an odd number."
(= (% n 2) 1))
(def -sentinel (object))
(defn partition [coll &optional [n 2] step [fillvalue -sentinel]]
"Chunks coll into n-tuples (pairs by default). The remainder, if any, is not
included unless a fillvalue is specified. The step defaults to n, but can be
more to skip elements, or less for a sliding window with overlap."
"Chunk `coll` into `n`-tuples (pairs by default).
The remainder, if any, is not included unless `fillvalue` is specified. The step
defaults to `n`, but can be more to skip elements, or less for a sliding window
with overlap."
(setv
step (or step n)
coll-clones (tee coll n)
@ -372,46 +376,46 @@
(zip-longest #* slices :fillvalue fillvalue)))
(defn pos? [n]
"Return true if n is > 0"
"Check if `n` is > 0."
(> n 0))
(defn rest [coll]
"Get all the elements of a coll, except the first."
"Get all the elements of `coll`, except the first."
(drop 1 coll))
(defn repeatedly [func]
"Yield result of running func repeatedly"
"Yield result of running `func` repeatedly."
(while True
(yield (func))))
(defn second [coll]
"Return second item from `coll`"
"Return second item from `coll`."
(nth coll 1))
(defn some [pred coll]
"Return the first logical true value of (pred x) for any x in coll, else None"
"Return the first logical true value of applying `pred` in `coll`, else None."
(first (filter None (map pred coll))))
(defn string [x]
"Cast x as current string implementation"
"Cast `x` as the current python verion's string implementation."
(if-python2
(unicode x)
(str x)))
(defn string? [x]
"Return True if x is a string"
"Check if `x` is a string."
(if-python2
(isinstance x (, str unicode))
(isinstance x str)))
(defn take [count coll]
"Take `count` elements from `coll`, or the whole set if the total
number of entries in `coll` is less than `count`."
"Take `count` elements from `coll`."
(islice coll None count))
(defn take-nth [n coll]
"Return every nth member of coll
raises ValueError for (not (pos? n))"
"Return every `n`th member of `coll`.
Raises ValueError for (not (pos? n))."
(if (not (pos? n))
(raise (ValueError "n must be positive")))
(setv citer (iter coll) skip (dec n))
@ -421,13 +425,15 @@
(next citer))))
(defn zero? [n]
"Return true if n is 0"
"Check if `n` equals 0."
(= n 0))
(defn read [&optional [from-file sys.stdin]
[eof ""]]
"Read from input and returns a tokenized string. Can take a given input buffer
to read from, and a single byte as EOF (defaults to an empty string)"
"Read from input and returns a tokenized string.
Can take a given input buffer to read from, and a single byte
as EOF (defaults to an empty string)."
(setv buff "")
(while True
(setv inn (string (.readline from-file)))
@ -441,16 +447,17 @@
parsed)
(defn read-str [input]
"Reads and tokenizes first line of input"
"Reads and tokenizes first line of `input`."
(read :from-file (StringIO input)))
(defn hyify [text]
"Convert text to match hy identifier"
"Convert `text` to match hy identifier."
(.replace (string text) "_" "-"))
(defn keyword [value]
"Create a keyword from the given value. Strings numbers and even objects
with the __name__ magic will work"
"Create a keyword from `value`.
Strings numbers and even objects with the __name__ magic will work."
(if (and (string? value) (value.startswith HyKeyword.PREFIX))
(hyify value)
(if (string? value)
@ -460,8 +467,10 @@
(except [] (HyKeyword (+ ":" (string value))))))))
(defn name [value]
"Convert the given value to a string. Keyword special character will be stripped.
String will be used as is. Even objects with the __name__ magic will work"
"Convert `value` to a string.
Keyword special character will be stripped. String will be used as is.
Even objects with the __name__ magic will work."
(if (and (string? value) (value.startswith HyKeyword.PREFIX))
(hyify (cut value 2))
(if (string? value)
@ -471,7 +480,7 @@
(except [] (string value))))))
(defn xor [a b]
"Perform exclusive or between two parameters"
"Perform exclusive or between `a` and `b`."
(if (and a b)
False
(or a b)))

View File

@ -10,11 +10,14 @@
(import [hy.models [HyList HySymbol]])
(defmacro as-> [head name &rest rest]
"Expands to sequence of assignments to the provided name, starting with head.
The previous result is thus available in the subsequent form. Returns the
final result, and leaves the name bound to it in the local scope. This behaves
much like the other threading macros, but requires you to specify the threading
point per form via the name instead of always the first or last argument."
"Beginning with `head`, expand a sequence of assignments `rest` to `name`.
Each assignment is passed to the subsequent form. Returns the final assignment,
leaving the name bound to it in the local scope.
This behaves similarly to other threading macros, but requires specifying
the threading point per-form via the name, rather than fixing to the first
or last argument."
`(do (setv
~name ~head
~@(interleave (repeat name) rest))
@ -22,6 +25,10 @@
(defmacro assoc [coll k1 v1 &rest other-kvs]
"Associate key/index value pair(s) to a collection `coll` like a dict or list.
If more than three parameters are given, the remaining args are k/v pairs to
be associated in pairs."
(if (odd? (len other-kvs))
(macro-error (last other-kvs)
"`assoc` takes an odd number of arguments"))
@ -37,12 +44,13 @@
(defmacro with [args &rest body]
"shorthand for nested with* loops:
"Wrap execution of `body` within a context manager given as bracket `args`.
Shorthand for nested with* loops:
(with [x foo y bar] baz) ->
(with* [x foo]
(with* [y bar]
baz))"
baz))."
(if (not (empty? args))
(do
(if (>= (len args) 2)
@ -56,12 +64,10 @@
(defmacro cond [&rest branches]
"shorthand for nested ifs:
(cond [foo bar] [baz quux]) ->
(if foo
bar
(if baz
quux))"
"Build a nested if clause with each `branch` a [cond result] bracket pair.
The result in the bracket may be omitted, in which case the condition is also
used as the result."
(if (empty? branches)
None
(do
@ -88,13 +94,10 @@
(defmacro for [args &rest body]
"shorthand for nested for loops:
(for [x foo
y bar]
baz) ->
(for* [x foo]
(for* [y bar]
baz))"
"Build a for-loop with `args` as a [element coll] bracket pair and run `body`.
Args may contain multiple pairs, in which case it executes a nested for-loop
in order of the given pairs."
(setv body (list body))
(if (empty? body)
(macro-error None "`for' requires a body to evaluate"))
@ -113,10 +116,10 @@
(defmacro -> [head &rest rest]
"Threads the head through the rest of the forms. Inserts
head as the second item in the first form of rest. If
there are more forms, inserts the first form as the
second item in the second form of rest, etc."
"Thread `head` first through the `rest` of the forms.
The result of the first threaded form is inserted into the first position of
the second form, the second result is inserted into the third form, and so on."
(setv ret head)
(for* [node rest]
(if (not (isinstance node HyExpression))
@ -127,8 +130,7 @@
(defmacro doto [form &rest expressions]
"Performs a sequence of potentially mutating actions
on an initial object, returning the resulting object"
"Perform possibly mutating `expressions` on `form`, returning resulting obj."
(setv f (gensym))
(defn build-form [expression]
(if (isinstance expression HyExpression)
@ -140,10 +142,10 @@
~f))
(defmacro ->> [head &rest rest]
"Threads the head through the rest of the forms. Inserts
head as the last item in the first form of rest. If there
are more forms, inserts the first form as the last item
in the second form of rest, etc."
"Thread `head` last through the `rest` of the forms.
The result of the first threaded form is inserted into the last position of
the second form, the second result is inserted into the third form, and so on."
(setv ret head)
(for* [node rest]
(if (not (isinstance node HyExpression))
@ -185,6 +187,7 @@
(defmacro with-gensyms [args &rest body]
"Execute `body` with `args` as bracket of names to gensym for use in macros."
(setv syms [])
(for* [arg args]
(.extend syms [arg `(gensym '~arg)]))
@ -193,6 +196,7 @@
~@body))
(defmacro defmacro/g! [name args &rest body]
"Like `defmacro`, but symbols prefixed with 'g!' are gensymed."
(setv syms (list
(distinct
(filter (fn [x]
@ -207,8 +211,9 @@
~@body))
(defmacro defmacro! [name args &rest body]
"Like defmacro/g! plus automatic once-only evaluation for o!
parameters, which are available as the equivalent g! symbol."
"Like `defmacro/g!`, with automatic once-only evaluation for 'o!' params.
Such 'o!' params are availible within `body` as the equivalent 'g!' symbol."
(setv os (list-comp s [s args] (.startswith s "o!"))
gs (list-comp (HySymbol (+ "g!" (cut s 2))) [s os]))
`(defmacro/g! ~name ~args
@ -217,7 +222,7 @@
(defmacro defmain [args &rest body]
"Write a function named \"main\" and do the if __main__ dance"
"Write a function named \"main\" and do the 'if __main__' dance"
(setv retval (gensym))
`(when (= --name-- "__main__")
(import sys)

View File

@ -9,7 +9,7 @@
(defn + [&rest args]
"Shadow + operator for when we need to import / map it against something"
"Shadowed `+` operator adds `args`."
(if
(= (len args) 0)
0
@ -19,13 +19,13 @@
(reduce operator.add args)))
(defn - [a1 &rest a-rest]
"Shadow - operator for when we need to import / map it against something"
"Shadowed `-` operator subtracts each `a-rest` from `a1`."
(if a-rest
(reduce operator.sub a-rest a1)
(- a1)))
(defn * [&rest args]
"Shadow * operator for when we need to import / map it against something"
"Shadowed `*` operator multiplies `args`."
(if
(= (len args) 0)
1
@ -35,6 +35,7 @@
(reduce operator.mul args)))
(defn ** [a1 a2 &rest a-rest]
"Shadowed `**` operator takes `a1` to the power of `a2`, ..., `a-rest`."
; We use `-foldr` instead of `reduce` because exponentiation
; is right-associative.
(-foldr operator.pow (+ (, a1 a2) a-rest)))
@ -42,32 +43,40 @@
(reduce (fn [x y] (f y x)) (cut xs None None -1)))
(defn / [a1 &rest a-rest]
"Shadow / operator for when we need to import / map it against something"
"Shadowed `/` operator divides `a1` by each `a-rest`."
(if a-rest
(reduce operator.truediv a-rest a1)
(/ 1 a1)))
(defn // [a1 a2 &rest a-rest]
"Shadowed `//` operator floor divides `a1` by `a2`, ..., `a-rest`."
(reduce operator.floordiv (+ (, a2) a-rest) a1))
(defn % [x y]
"Shadowed `%` operator takes `x` modulo `y`."
(% x y))
(if PY35 (defn @ [a1 &rest a-rest]
(reduce operator.matmul a-rest a1)))
(if PY35
(defn @ [a1 &rest a-rest]
"Shadowed `@` operator matrix multiples `a1` by each `a-rest`."
(reduce operator.matmul a-rest a1)))
(defn << [a1 a2 &rest a-rest]
"Shadowed `<<` operator performs left-shift on `a1` by `a2`, ..., `a-rest`."
(reduce operator.lshift (+ (, a2) a-rest) a1))
(defn >> [a1 a2 &rest a-rest]
"Shadowed `>>` operator performs right-shift on `a1` by `a2`, ..., `a-rest`."
(reduce operator.rshift (+ (, a2) a-rest) a1))
(defn & [a1 &rest a-rest]
"Shadowed `&` operator performs bitwise-and on `a1` by each `a-rest`."
(if a-rest
(reduce operator.and_ a-rest a1)
a1))
(defn | [&rest args]
"Shadowed `|` operator performs bitwise-or on `a1` by each `a-rest`."
(if
(= (len args) 0)
0
@ -77,9 +86,11 @@
(reduce operator.or_ args)))
(defn ^ [x y]
"Shadowed `^` operator performs bitwise-xor on `x` and `y`."
(^ x y))
(defn ~ [x]
"Shadowed `~` operator performs bitwise-negation on `x`."
(~ x))
(defn comp-op [op a1 a-rest]
@ -89,29 +100,32 @@
(list-comp (op x y) [(, x y) (zip (+ (, a1) a-rest) a-rest)]))
True))
(defn < [a1 &rest a-rest]
"Shadow < operator for when we need to import / map it against something"
"Shadowed `<` operator perform lt comparison on `a1` by each `a-rest`."
(comp-op operator.lt a1 a-rest))
(defn <= [a1 &rest a-rest]
"Shadow <= operator for when we need to import / map it against something"
"Shadowed `<=` operator perform le comparison on `a1` by each `a-rest`."
(comp-op operator.le a1 a-rest))
(defn = [a1 &rest a-rest]
"Shadow = operator for when we need to import / map it against something"
"Shadowed `=` operator perform eq comparison on `a1` by each `a-rest`."
(comp-op operator.eq a1 a-rest))
(defn is [a1 &rest a-rest]
"Shadowed `is` keyword perform is on `a1` by each `a-rest`."
(comp-op operator.is_ a1 a-rest))
(defn != [a1 a2 &rest a-rest]
"Shadow != operator for when we need to import / map it against something"
"Shadowed `!=` operator perform neq comparison on `a1` by `a2`, ..., `a-rest`."
(comp-op operator.ne a1 (+ (, a2) a-rest)))
(defn is-not [a1 a2 &rest a-rest]
"Shadowed `is-not` keyword perform is-not on `a1` by `a2`, ..., `a-rest`."
(comp-op operator.is-not a1 (+ (, a2) a-rest)))
(defn >= [a1 &rest a-rest]
"Shadow >= operator for when we need to import / map it against something"
"Shadowed `>=` operator perform ge comparison on `a1` by each `a-rest`."
(comp-op operator.ge a1 a-rest))
(defn > [a1 &rest a-rest]
"Shadow > operator for when we need to import / map it against something"
"Shadowed `>` operator perform gt comparison on `a1` by each `a-rest`."
(comp-op operator.gt a1 a-rest))
(defn and [&rest args]
"Shadowed `and` keyword perform and on `args`."
(if
(= (len args) 0)
True
@ -121,6 +135,7 @@
(reduce (fn [x y] (and x y)) args)))
(defn or [&rest args]
"Shadowed `or` keyword perform or on `args`."
(if
(= (len args) 0)
None
@ -130,15 +145,19 @@
(reduce (fn [x y] (or x y)) args)))
(defn not [x]
"Shadowed `not` keyword perform not on `x`."
(not x))
(defn in [x y]
"Shadowed `in` keyword perform `x` in `y`."
(in x y))
(defn not-in [x y]
"Shadowed `not in` keyword perform `x` not in `y`."
(not-in x y))
(defn get [coll key1 &rest keys]
"Access item in `coll` indexed by `key1`, with optional `keys` nested-access."
(setv coll (get coll key1))
(for* [k keys]
(setv coll (get coll k)))