VISITS Advent Calendar has finally run out of a week.
Looking back, articles in a very wide range of fields were written, and even people in the company were often surprised by the fact that "this person had this kind of technology."
For me, this is the closing article for the 2019 Advent Calendar!
TL; DR
Some of our products implement API servers in ** Go language **.
I've been touching Python for a long time, but I've been writing Go language for about a month and a half, but I'll write an article about ** the difference between Go language and Python ** that I found out by writing it in my work.
Titled
** Pythonista tells us "This is strange Go language" **
For the time being, I made the title of a certain program ~~ Park t (ry ~~ respected and made it a catchy title (what)
The target audience is set as follows.
-** People who use Python a lot but have never written Go language ** -** People who touch Go language as a hobby but do not have the opportunity to write or read in business **
I'm writing it so that you can read it if you know the grammar of Python even if you are not familiar with the Go language.
I would like to cover everything from differences in grammar level to language characteristics that are effective at the business level.
The whole article feels like ** Go favor **, but it's because of my love for Python!
You're right, it's a different language.
First, Python is a ** dynamically typed language and a language that runs on the interpreter **, while Go is a ** statically typed language compilation language **.
It seems wrong to compare this alone.
** I think it would be interesting to compare it with such a difference **, and I thought it might be worth trying as an article, which was a big motivation for writing an article.
Although they are completely different languages, the big thing Python and Go have in common is that ** both languages are designed to be highly readable **.
There are various programming languages, but I have a mysterious miscellaneous feeling that the languages that are highly readable and maintainable (as a result of natural selection) will remain.
After all, everyone loves easy-to-read code!
The birth of Python is surprisingly old, with the first release (** Python 0.90 **) by Guido Van Rossum in ** 1991 **. It's well known that the name "Python" comes from the BBC TV show ** Monty Python's Flying Circus ** (I haven't seen it yet).
According to History of Python, Van Rossum seems to be a big fan of the show, short and mysterious to the invented language that had no name at the time. It seems that it became this name because I wanted to give it a different name.
It seems that at first it was ** a hobby development that I went to kill time for Christmas **. It's so dreamy and interesting that a language created by killing time will be used all over the world.
** Python 2.0 ** was released in 2000 and became known as a major language (Python --Wikipedia. % B4% E5% 8F% B2).
The big transition from Python 2.x to Python 3.x, which breaks backwards compatibility, now feels a bit past, but now ** Python 3.8 ** has been released ([Python 3.8]. New features (summary)](https://qiita.com/ksato9700/items/3846e8db573a07c71c33)).
(Quoted from History of Python)
Type ʻimport this` on the Python interpreter and you'll see ** Zen of Python ** in English! )
$ python
Python 3.8.0 (default, Oct 31 2019, 16:56:00)
[Clang 11.0.0 (clang-1100.0.33.8)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import this
The Zen of Python, by Tim Peters
Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
Readability counts.
Special cases aren't special enough to break the rules.
Although practicality beats purity.
Errors should never pass silently.
Unless explicitly silenced.
In the face of ambiguity, refuse the temptation to guess.
There should be one-- and preferably only one --obvious way to do it.
Although that way may not be obvious at first unless you're Dutch.
Now is better than never.
Although never is often better than *right* now.
If the implementation is hard to explain, it's a bad idea.
If the implementation is easy to explain, it may be a good idea.
Namespaces are one honking great idea -- let's do more of those!
For those who are not good at English, The Zen of Python is helpful.
Unlike Python, which started with personal hobby development, Go was born from the world's largest company, ** Google **. Designed by Google engineers Robert Griesemer, Rob Pike, and Ken Thompson in an experimental project to develop new programming (Go --en.wikipedia.org .wikipedia.org/wiki/Go_(programming_language))).
** Design started in 2007, and Go1.0 was just released in 2012 **, which is a short history in the programming language world as ** newcomer **.
Go is open source, so anyone can read the code.
$ git clone https://github.com/golang/go.git #(Note!) There is about 200MB
$ git log --reverse
If you do the above, you'll see commits around 2008. (By the way, the first commit was a specification.)
One of the three, Rob Pike, can read the unreleased slides presented at the Stanford EE Computer Systems Colloquium in 2010 in PDF (Another Go at Language Design. //web.stanford.edu/class/ee380/Abstracts/100428-pike-stanford.pdf)).
If you look at this PDF, it has quite interesting content, but roughly speaking, it solves the problems that Java and C ++ have (redundant code, long compilation time, large binaries, etc.) It seems that Go was devised to do **.
The Target: Go aims to combine the safety and performance of a statically typed compiled language with the expressiveness and convenience of a dynamically typed interpreted language.
Especially when translating this part,
** Go's goal is to connect the following two. ** **
-** Safety and performance of statically typed compilation language ** -** Expressive power and convenience of dynamically typed interpreted language **
It's a nice story, but Go is the language that is really trying to make it happen.
The PDF also mentions Go's ** features that solve problems in other languages **.
--Fast compilation --Expressive type system --Concurrency (strong in concurrent programming) --Garbage collection --System programming language (with direct access to hardware) —— Be clear --Orthogonality (package is sufficiently independent of other packages)
The interpretation of the orthogonality part is based on Orthogonality in Go. Is that why the standard packages are extensive and divided in an easy-to-understand manner?
The manners of Go are summarized, and they are collectively called Go Way
.
"What is the method ..."
Many people may be worried about it, but it is often messed up by following the behavior that seems strange at first.
[What is "Go language-ness"? The goodness of understanding Simplicity's philosophy and proceeding with development along the Go Way](https://employment.en-japan.com/engineerhub/entry/2018/06/19/110000#Go%E8%A8% 80% E8% AA% 9E% E3% 82% 89% E3% 81% 97% E3% 81% 95% E3% 81% A8% E3% 81% AF)
It is recommended because the explanation of ** Go Way ** is written in great detail.
Both Python and Go are programming languages, so it's easy to see them in code.
hello.py
print('Hello, World')
$ python hello.py
Hello, World
Or
$ python
Python 3.8.0 (default, Oct 31 2019, 16:56:00)
[Clang 11.0.0 (clang-1100.0.33.8)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>>print('Hello, World')
Hello, World
main.go
package main
import "fmt"
func main() {
fmt.Println("Hello, World")
}
$ go run main.go
Hello, World
.. .. .. Hmm.
As expected, I don't really understand the difference, so let's implement it a little more practically.
Let's implement annoying programmers in Python and Go, respectively, to spread their favorite programming language to other programmers.
As a specification,
-** Programmers can have names and favorite languages as attributes ** -** It has a function that changes the programmer's favorite language to your favorite language when you give another programmer as an argument ** -** The name in the class variable cannot be changed globally **
Python
First, let's create a Programmer
Class in Python.
First, the minimal implementation.
main.py
class Programmer:
def __init__(self, name, favorite_language):
self.name = name
self.favorite_language = favorite_language
def teach_favorite_language(self, prog):
prog.favorite_language = self.favorite_language
pythonista = Programmer("zawawahoge", "Python")
go_lover = Programmer("foobar", "Go")
pythonista.teach_favorite_language(go_lover)
You can set getters and setters using the @property
decorator.
Now you can implement private variables (like).
Regarding name
, I didn't implement setter, so it will not be accessible from the outside (although it can be done).
main.py
class Programmer:
def __init__(self, name, favorite_language):
self.__name = name
self.__favorite_language = favorite_language
@property
def name(self):
return self.__name
@property
def favorite_language(self):
return self.__favorite_language
@favorite_language.setter
def favorite_language(self, favorite_language):
self.__favorite_language = favorite_language
def teach_favorite_language(self, prog):
prog.favorite_language = self.favorite_language
pythonista = Programmer("zawawahoge", "Python")
go_lover = Programmer("go_lover", "Go")
pythonista.teach_favorite_language(go_lover)
In Python, what you want to be a private variable is prefixed with __
.
I tried to implement the same function in Go that was implemented in Python. I try to make it as close as possible to the code I write in business.
main.go
package main
type Language string
//Programmer is the programmer's interface (global variable)
type Programmer interface {
TeachFavoriteLanguage(target Programmer) error
SetFavoriteLanguage(lang Language) error
FavoriteLanguage() Language
}
//programmer implements the Programmer interface(Can only be referenced from within the package)
type programmer struct {
Programmer
name string
favoriteLanguage Language
}
//NewProgrammer returns a new Programmer
func NewProgrammer(name string, lang Language) Programmer {
return &programmer{
name: name,
favoriteLanguage: lang,
}
}
// getter
func (p *programmer) FavoriteLanguage() Language {
return p.favoriteLanguage
}
// setter
func (p *programmer) SetFavoriteLanguage(lang Language) error {
p.favoriteLanguage = lang
return nil
}
//Implementation of TeachFavoriteLanguage
func (p *programmer) TeachFavoriteLanguage(target Programmer) error {
err := target.SetFavoriteLanguage(p.FavoriteLanguage())
if err != nil {
return err
}
return nil
}
//Within the main function, you can communicate only with the Programmer interface
func main() {
pythonista := NewProgrammer("zawawahoge", Language("Python"))
go_lover := NewProgrammer("go_lover", Language("Go"))
err := pythonista.TeachFavoriteLanguage(go_lover)
if err != nil {
panic("An error occurred during missionary work")
}
}
At first glance, you can see that the amount of code is overwhelmingly larger than that of Python.
** Why is it increasing so much! ?? !! ?? !! ?? ** **
If you raise the features that are different from Python,
--Explicitly define the Language
type (string
)
--Define the Programmer
interface
--Define programmer
struct
--Define a global NewProgrammer ()
instead of a constructor and generate a Programmer
--Implement the interface (if the function is created, it will be satisfied)
--Perform error handling
In Go, if the first letter of a variable is ** uppercase, it will be a global variable **, and if it is lowercase, it will be a package variable (only visible within the same package) **.
The amount of code itself is larger than that of Python, but ** each one has a clear meaning and there is no waste **.
Due to the forced indentation, the language specification is such that it cannot be unreadable code such as a compressed .js
file.
People who are new to Python often say that the indentation is unpleasant, but in fact this makes it easier to understand the scope at a glance **.
In addition, the amount of code is overwhelmingly smaller than that of a normal compilation language. The reason why Python has spread so far in scientific computing is probably because it has the feature of being able to wrap various libraries with an easy-to-understand interface.
However, since it is a dynamically typed language, it has the drawback that it is difficult to utilize the complement of the IDE, and it is difficult to prevent the contents of the object from being destroyed in advance due to the language specifications, so it strongly depended on the skill of the implementer. It can be called a language (especially when creating a library).
Python is actually extremely flexible, so it often happens that the implementation differs greatly from person to person. With Go, due to the characteristics of the language, the implementation method is determined to some extent for the purpose, so ** the code will be similar regardless of the person who wrote it **.
Thanks to this, even if you are developing with multiple developers, it is unlikely that you will not understand the implementation at all.
** Although it is a difficult language to enjoy, I think that the code will be implementer-independent because the necessary and sufficient implementation is naturally required **.
try ~ except
In Python, you use the try ~ except
syntax.
try:
do_something()
res = get_something()
except Exception as e:
print(f"e={e}, type(e)={type(e)}")
Error handling of the try ~ catch
system has a large overhead for error detection, and performance may deteriorate even when no error occurs.
Since the overhead is heavy if you enclose everything in try
, write the error handling by enclosing only the part where an error is likely to occur in try
.
Then, what do you do when an error occurs without try
? It will be a story.
Unlike other languages, Go does not handle errors with try ~ catch
or try ~ except
, and determines success or error based on the return value of type ʻerror`.
The following error handling frequently appears in Go code.
If you're not familiar with it, it's probably ** unpleasant ** (early author).
err := DoSomething()
if err != nil {
return errors.Errorf("failed to do something; err=%#v", err)
}
res, err := GetSomething()
if err != nil {
return errors.Errorf("failed to get something; err %#v", err)
}
Just like Go, if you just check if ʻerris
nil (
None` in Python), you can detect the error, so the overhead is very small and the performance degradation for error detection is reduced. Almost no need.
The downside is that you'll have to write error handling in almost every piece of code, so it's ** somehow annoying ** until you're used to it. However, by the time you get used to it, you will be more reassured that you can handle all the code with errors! ** **
** Pythonista tells us "This is strange Go language" ** How was it?
Unlike the title, I'm sorry for ** Go favor **.
In terms of articles, I also wanted to write test items, but I was exhausted.
In writing this article, I decided to investigate both Python and Go, but thanks to that, I learned ** a lot **, so I thought it was good to choose it as a subject.
People who have something to convey will be encouraged if they like it.
Thank you very much.
-[What is "Go language-ness"? The goodness of understanding Simplicity's philosophy and proceeding with development along the Go Way](https://employment.en-japan.com/engineerhub/entry/2018/06/19/110000#Go%E8%A8% 80% E8% AA% 9E% E3% 82% 89% E3% 81% 97% E3% 81% 95% E3% 81% A8% E3% 81% AF) -The Zen of Python