This article is Lisp-like, but for the time being Python Part 2 Advent Calendar 2015 is the third day article.
Continuing from Last time, we will explore the possibility of Hy.
The stable version of Hy at the time of this writing is 0.11.0.
In 0.11.0, when defining a class, use def class
and write as follows.
(defclass FooBar [object]
[[--init--
(fn [self x]
(setv self.x x)
None)]
[get-x
(fn [self]
"Return our copy of x"
self.x)]])
In the latest development version of Hy, as documented, how to define classes It's a little strange.
(defclass FooBar [object]
(defn --init-- [self x]
(setv self.x x))
(defn get-x [self]
"Return our copy of x"
self.x))
Compared to 0.11.0 or earlier, the writing style is cleaner.
I don't know when the version that can be written will be stable, but if it changes anyway, I will get used to the new writing, so after that I will assume that I will use the development version Hy installed from github. write.
pip install git+https://github.com/hylang/hy.git
It has nothing to do with the class definition, but when I write a script to check the operation,
if __name__ == '__main__':
#Do something here
func()
I want to write an idiom equivalent to in Hy.
Apparently, Python's __X__
becomes --X--
in Hy, so you can write it as follows.
; hello.hy
(defn hello []
(print "Hello, World"))
(if (= --name-- "__main__")
(hello))
Run with the hy
interpreter.
$ hy ~/tmp/hello.hy
Hello, World
When I thought about the example of object-oriented programming using class inheritance, I couldn't think of a useful example, so [the timeless masterpiece "Rudolf and the Black Cat"](http://www.amazon.co.jp/ I made a trivial sample based on dp / 4061335057 /).
Define the Cat
class that represents a domestic cat and the StrayCat
that represents a stray cat by inheriting from the abstract class ʻAbstractCat`.
; cat.hy
(defclass AbstractCat [object]
(defn --init-- [self name]
(setv self.name name))
(defn greet [self]
(raise NotImplementedError)))
(defclass StrayCat [AbstractCat]
(defn greet [self]
(.format "My name is{}" self.name)))
(defclass Cat [AbstractCat]
(defn --init-- [self name home]
(.--init-- (super Cat self) name)
(setv self.home home))
(defn greet [self]
(.format "my name is{}。{}I live in." self.name self.home)))
(defn main []
(let [cat1 (Cat "Rudolph" "Rie-chan's house")
cat2 (StrayCat "Ippai Attena")]
(print (.greet cat1))
(print (.greet cat2))))
(if (= --name-- "__main__")
(main))
Just because __X__
becomes --X--
gives the impression that you've almost moved the Python syntax to Lisp syntax.
The constructor __init __
becomes --init --
, and use (setv self.key value)
to set properties.
(defclass AbstractCat [object]
(defn --init-- [self name]
(setv self.name name))
The Python super (X, self) .method ()
idiom that calls the method of the parent class is almost the same, just replaced with the Lisp syntax. In the above example, it is used when calling the constructor of the parent class.
(defclass Cat [AbstractCat]
(defn --init-- [self name home]
(.--init-- (super Cat self) name)
(setv self.home home))
The pattern that throws a NotImplementedError
exception to represent an abstract method can be ported almost exactly as(raise NotImplementedError)
.
(defclass AbstractCat [object]
;;Abbreviation
(defn greet [self]
(raise NotImplementedError)))
Hy comes with a Hy → Python conversion tool called hy2py
. Let's use this tool to convert the above example into Python code.
hy2py cat.hy
The result is as follows.
from hy.core.language import name
class AbstractCat(object):
def __init__(self, name):
self.name = name
self.name
return None
def greet(self):
raise NotImplementedError
class StrayCat(AbstractCat):
def greet(self):
return u'\u4ffa\u306e\u540d\u524d\u306f{}'.format(self.name)
class Cat(AbstractCat):
def __init__(self, name, home):
super(Cat, self).__init__(name)
self.home = home
self.home
return None
def greet(self):
return u'\u50d5\u306e\u540d\u524d\u306f{}\u3002{}\u306b\u4f4f\u3093\u3067\u3044\u307e\u3059\u3002'.format(self.name, self.home)
def main():
def _hy_anon_fn_6():
cat1 = Cat(u'\u30eb\u30c9\u30eb\u30d5', u'\u308a\u3048\u3061\u3083\u3093\u306e\u5bb6')
cat2 = StrayCat(u'\u30a4\u30c3\u30d1\u30a4\u30a2\u30c3\u30c6\u30ca')
(cat1, cat2)
print(cat1.greet())
return print(cat2.greet())
return _hy_anon_fn_6()
(main() if (__name__ == u'__main__') else None)
It was converted to Python code almost as intended, except that it contained the meaningless return None
.
With the latest development version of Hy, you can define classes very intuitively with def class
, so it doesn't feel too difficult.
Perhaps because of the simple grammar of Python, Python code and Hy code look very similar, and you realize that "all programming languages lead to Lisp."
Next time, I would like to write a larger program to explore the possibilities of Hy.
Recommended Posts