This repository collects some of the useful functions and macros that I wrote or borrowed for hylang. I am more accustomed to the common lisp syntax, so I borrowed from the nice work of riktor on hycl to make hylang more friendly to people coming from common lisp.
hy==0.17.0
To install
pip install git+https://github.com/guanyilun/hylab/
To start with, import the core library
(import [hylab.core [*]])
(require [hylab.core [*]])
(setf x 10)
(defun plus-one (x)
(inc x)
)
(print (plus-one x))
11
One can also use defparameter
which is the same as setv
or setf
,
however I find it more readable to use this exclusively for global
variables.
(defparameter *global-var* 10)
(print *global-var*)
10
numpy
and plt
are also loaded automatically
(print (np.arange 0 10))
[0 1 2 3 4 5 6 7 8 9]
numpy
array indexing can be done by
(setf x (np.random.randn 100 100 100))
(nget x 0 1 :10)
array([ 0.87120279, -1.66700778, 0.26169724, -0.60144387, 0.55433208, -0.43233873, -1.11727772, 0.41093365, 0.36703862, -1.88770578])
With Ellipsis
(. (nget x ... 0:10) shape)
(100, 100, 10)
Add new columns
(. (nget x ... None) shape)
(100, 100, 100, 1)
Some more examples of nget
(setf a (.reshape (np.arange 36) (, 6 6)))
(nget a (, 0 1 2 3 4) (, 1 2 3 4 5))
array([ 1, 8, 15, 22, 29])
(nget a 3: (, 0 2 5))
array([[18, 20, 23], [24, 26, 29], [30, 32, 35]])
(setf mask (np.array (, 1 0 1 0 0 1) :dtype bool))
(nget a mask 2)
array([ True, False, True, False, False, True]) array([ 2, 14, 32])
(nget a ::2 3)
(nget a ::2 3 None)
(nget a ... 0)
array([ 3, 15, 27]) array([[ 3], [15], [27]]) array([ 0, 6, 12, 18, 24, 30])
Quick python->hy equation translation,
(let ((x (np.linspace 0 10 10)))
(+ (** (np.sin x) 2) (** (np.cos x) 2)))
array([1., 1., 1., 1., 1., 1., 1., 1., 1., 1.])
It can be written as
(let ((x (np.linspace 0 10 10)))
($ "np.sin(x)**2+np.cos(x)**2"))
array([1., 1., 1., 1., 1., 1., 1., 1., 1., 1.])
This is different to the py-eval
function as this is a macro that
gets converted into the previous (lisp) notation at compile time so
there is no performance issue.
The same symbol represents curry when used as tag macro
(tuple (map #$(+ 10) '(1 2 3 4 5)))
(11, 12, 13, 14, 15)
This is equivalent to using the tag macro for tuple
#t(map #$(+ 10) '(1 2 3 4 5))
(11, 12, 13, 14, 15)
Similarly
#t(map #$(+ 10) '(1 2 3 4 5))
#l(map #$(+ 10) '(1 2 3 4 5))
#a(map #$(+ 10) '(1 2 3 4 5))
#h(map #$(+ 10) '(1 2 3 4 5))
(11, 12, 13, 14, 15) [11, 12, 13, 14, 15] array([11, 12, 13, 14, 15]) HyExpression([11, 12, 13, 14, 15])
Some convenient conversions (to HySymbol) for macros
#sym"my-var1"
#sym 'my-var2
#."my-var3"
#. 'my-var4
HySymbol('my-var1') HySymbol('my-var2') HySymbol('.my-var3') HySymbol('.my-var4')
Lambda expression, the following three expressions are equivalent, the first is the built-in notation from hylang, the second is a common lisp like alias and the last is a unicode alias.
#l(map (fn [x] (1+ x)) [1 2 3])
#l(map (lambda (x) (1+ x)) [1 2 3])
#l(map (λ (x) (1+ x)) [1 2 3])
[2, 3, 4] [2, 3, 4] [2, 3, 4]
Get elements of lists or tuples
(let ((x '((1 2) (3 4) (5 6))))
(lget x 0 :))
array([1, 2])
(let ((x '((1 2) (3 4) (5 6))))
(lget x None ...))
array([[[1, 2], [3, 4], [5, 6]]])
Threading
(let ((x (np.arange 1 10)))
(as-> x it
(/ 100 it)
(+ it 3)
(np.sin it)
(** it 2 )))
array([0.38811483, 0.15675672, 0.95855331, 0.07338995, 0.71608897, 0.53169132, 0.99995163, 0.04262882, 0.99932125])
This can also be written as (borrowed from riktor)
(let ((x (np.arange 1 10)))
(=> x
(/ 100 _)
(+ 3)
(np.sin)
(** 2)))
array([0.38811483, 0.15675672, 0.95855331, 0.07338995, 0.71608897, 0.53169132, 0.99995163, 0.04262882, 0.99932125])
Quick plotting tools
(setf x (np.linspace 1 10 100))
(setf y (np.sin x))
(plot
x y "r-"
y x "g-"
:xlabel "x"
:ylabel "y"
:title "Test Plot"
:legend ["Line1" "Line2"]
:savefig "plots/test.png"
:show)
For printing
(setf
age 99
height 2.2)
(print (+ "I am " (str age) " years old, and I am " (str height) " m tall"))
I am 99 years old, and I am 2.2 m tall
A simpler way of printing is
(print (.format "I am {} years old, and I am {} m tall" age height))
I am 99 years old, and I am 2.2 m tall
An even simpler way of printing from hylab
(print #f"I am {age} years old, and I am {height} m tall")
I am 99 years old, and I am 2.2 m tall
Clearly this is inspired by f-string in python. It allows arbitrary s-expression too
(print #f"I am {(inc age)} years old, and I am {(round (* np.pi height) 2)} m tall")
I am 100 years old, and I am 6.91 m tall
It should work with format options too (though there may be cases that I haven’t considered, PR is welcomed).
(print #f"Pi = {np.pi:8.2f}")
Pi = 3.14
(setf n "cat")
(print #f"Animal: {n:5}")
(print #f"Animal: {n:>5}")
(print #f"Animal: {n:^5}")
(print #f"Animal: {n:*^5}")
Animal: cat Animal: cat Animal: cat Animal: *cat*
I also included codes from hyiter written by riktor, which I find amazing. Here are some examples that I borrowed directly from hyiter to showcase this function
NEEDS FIXING for hy==0.17.0
;; loop on iterable
(itr
(for i in '(1 2 3))
(print i))
1 2 3
(print (itr
(for i in (range 10))
(when (= (% i 2) 0)
(collect (* 10 i)))))
[0, 20, 40, 60, 80]
(itr
(initially
(print "LOOP Start!"))
(for i in '(1 2 3))
(print i))
LOOP Start! 1 2 3
(itr
(for i in '(1 2 3))
(print i)
(finally
(print "LOOP Finish!")))
1 2 3 LOOP Finish!
(print (itr
(for i in (range 10))
(maximize i)))
9
(print (itr
(for i in (range 10))
(count (= (% i 2) 0))))
5
This is only a subset of what’s possible, for more details please refer to this link.
More to come …
- Credits to riktor from whom I borrowed lots of codes.
- I also borrowed some codes from Eric Kaschalk.
- The template is based on cookiecutter-pypackage.
MIT