Skip to content

Latest commit

 

History

History

hy

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 

Hy Language

Hy (github) is a Lisp variant embedded in CPython. The syntax is is mostly homoiconic, using a Clojure-like reader. Hy is converted to Python's AST and then compiled to Python bytecode. It is tested with Python 2.7 and 3.{4-7}.

Hy is changing rapidly. hy/NEWS.rst has information about the latest changes; this often has not yet filtered into the documentation in the docs dir of the repo.

Other Python Lisp projects:

Installation

pip install hy
pip install git+https://github.com/hylang/hy.git

Summary

Also see the Documentation Index.

Substitutions When Converting to Python Names

  • Hyphens are replaced with underbars: foo-barfoo_bar
  • Earmuffed names are converted to upper case: *foo*FOO
  • UTF-8 names are encoded with punycode and prefixed with hy_: i♥uhy_iu_t0x

Syntax

Syntax:

  • '#!': Ignored when first line of script.
  • ;: Comment.
  • "...": Strings must always use double quotes.

Representations

Hy expressions when printed by the standard Python repr make '(7, "abc") appear as HyExpression([HyInteger(7), HyString('abc')]). The hy.contrib.hy-repr module has a hy-repr function to print in standard Hy format instead, and this can be used in the REPL:

$ hy --repl-output-fn=hy.contrib.hy-repr.hy-repr
=> '(7 "abc")
'(7 "abc")

hy-repr will call an object's __hy-repr__() method if available, and will fall back to standard Python repr when it doesn't know how to handle a format.

Like Python repr, where possible hy-repr output should be invertable with (eval (read-str (hy-repr x))) returning x or an object equal to it.

Literals

For more detailed information, see Hy (the language).

  • None, True, False: Equivalant of nil, true, false in other Lisps.
  • Numbers may be preceeded by 0x/0o/0b for base 16/8/2. Underscores and commas may appear anywhere in a numeric literal except at the start: (+ 10,000 20_000)) => 30000. NaN, Inf and -Inf are available.
  • n/m: Python Fraction(n, m)
  • "...": String with \ escapes and literal newlines allowed. (Single quotes, triple quotes not available.) Prefix with r for raw (no escapes), b for bytes. Strings are always Unicode; under Python 2 "foo"u"foo" and b"foo""foo".
  • #[delim[...]delim]: Raw bracket string; delim may be any string not containing [/], including empty: #[[Say "hi."]]. An initial newline is removed; all others are literal.
  • ': Prefixed to a form, prevents evaluation. E.g.: 'name is literal name, '() is literal empty list.
  • (): HyExpression.
  • []: HyList.
  • {}: Python dict. E.g., {"a" 1 2 2.0 :foo None}{2: 2.0, '\ufdd0:foo': None, 'a': 1}
  • #{}: Python set, E.g., #{"one" 2 :three}
  • :name: Keyword. Evaluates to '\ufdd0:foo' except when used as literal in a function call indicating keyword argument. Can be quoted: (f ':foo)f('\ufdd0:foo').
  • #_: Discard prefix; following form is discarded instead of compiled. Useful for commenting out forms.
  • (list-comp expr selector filter): List comprehension: evaluate expr form for every value generated by selector form where optional filter form is true. See list-comp.

Forms

See Built-Ins for more details.

  • (setv x form [y form2 ...]): Bind result of form to x.
  • (defn f [arg ...] (form)): Define a function.
  • (defclass C [parent ...] [...]): Class definition
  • (do form ...): A "block" of multiple forms (used with if, cond, etc.), as with progn in other Lisps.
  • (if pform tform fform): pform is a predicate; tform and fform default to True and False.
  • (cond [pform tform] ...) : Conditional: first matching pform evaluates its tform and then evaulation stops. Use [True tform] at end for default match.
  • (with [name cform]] form): Context manager binding cform to name: (with [f (open "/foo")] (print (.read f))).
  • (import ...): Import. Uses unquoted names, (import os).

Functions

Functions (and macros) are called by putting them as the first element of a form, followed by the arguments: (+ 1 2). Prefixing a function name with a . calls the method on the succeeding object: (.startswith "abc" "a")True. You can also call in standard obj.method format with names (but not literals):

(setv s "abc")
(s.startswith "a")      ; ⇒ True, just like (s.startswith s "a")
("abc".startswith "a")  ; HyTypeError: cannot access attribute
                        ; on anything other than a name

Generally, Python functions are directly available in Hy under the same name. Dyadic functions are extended to more than two arguments where appropriate, e.g., (+ "a" "b" "c").

See Built-Ins and Hy Core for more details on built-in functions.