[PYTHON] I tried to get started with Hy ・ Define a class

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.

Old class definition method

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)]])

How to define a new class

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

ʻIf name == How to write'main'` in Hy

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

Inherit class

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)))

Convert Hy code to Python code using hy2py

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.

Finally

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

I tried to get started with Hy ・ Define a class
I tried to get started with Hy
[Python] A memo that I tried to get started with asyncio
I tried to get started with blender python script_Part 01
A memorandum when I tried to get it automatically with selenium
I wrote a script to get you started with AtCoder fast!
I tried to get started with Bitcoin Systre on the weekend
I tried to get CloudWatch data with Python
A layman wants to get started with Python
I tried to create a table only with Django
I tried to draw a route map with Python
I tried to automatically generate a password with Python3
What I did to get started with Linux commands
I tried to implement a volume moving average with Quantx
Link to get started with python
I tried to automatically create a report with Markov chain
How to get started with Scrapy
How to get started with Python
I tried to solve a combination optimization problem with Qiskit
I tried "How to get a method decorated in Python"
How to get started with Django
I tried to sort a random FizzBuzz column with bubble sort.
I tried to create a class to search files with Python's Glob method in VBA
I tried to divide with a deep learning language model
I made a class to get the analysis result by MeCab in ndarray with python
I tried to make a generator that generates a C # container class from CSV with Python
I tried to get a database of horse racing using Pandas
[3rd] I tried to make a certain authenticator-like tool with python
Here's a brief summary of how to get started with Django
I tried to make a periodical process with Selenium and Python
I tried to get a list of AMI Names using Boto3
I tried to make a 2channel post notification application with Python
I tried to create Bulls and Cows with a shell program
I tried to make a todo application using bottle with python
[4th] I tried to make a certain authenticator-like tool with python
[1st] I tried to make a certain authenticator-like tool with python
I tried to make a strange quote for Jojo with LSTM
I tried to make a mechanism of exclusive control with Go
Step notes to get started with django
I tried to implement Autoencoder with TensorFlow
I tried to create a linebot (preparation)
I tried to visualize AutoEncoder with TensorFlow
I tried a functional language with Python
I tried to implement CVAE with PyTorch
I tried to make a Web API
I tried to solve TSP with QAOA
How to get started with laravel (Linux)
I tried to introduce a serverless chatbot linked with Rakuten API to Teams
Python: I tried to make a flat / flat_map just right with a generator
I tried to communicate with a remote server by Socket communication with Python.
I tried to implement a blockchain that actually works with about 170 lines
I tried to create a program to convert hexadecimal numbers to decimal numbers with python
A story I was addicted to trying to get a video url with tweepy
I tried to create a plug-in with HULFT IoT Edge Streaming [Development] (2/3)
I tried to make a calculator with Tkinter so I will write it
I tried to make "Sakurai-san" a LINE BOT with API Gateway + Lambda
I tried to draw a system configuration diagram with Diagrams on Docker
I tried to get the authentication code of Qiita API with Python.
I tried to make a traffic light-like with Raspberry Pi 4 (Python edition)
I get a UnicodeDecodeError when trying to connect to oracle with python sqlalchemy
I tried to create a plug-in with HULFT IoT Edge Streaming [Execution] (3/3)