Hi, I could be wrong (please correct me ;-), but here you are what I think
about Go:
INTRODUCTION
Computers and software were initially developed for scientific computing;
e.g., ALGOL and FORTRAN from the 1950s! Therefore, several computer
languages and libraries have been invented and are used in scientific
computing to date. Nonetheless, when programming a new scientific
simulation, the question about computational efficiency versus ease-of-use
remains open. Here, we aim to shed light on a suitable answer to this
question---TL;DR use Go and Gosl!
One would say that scripting (interpreted) languages might provide the
convenient platform for computations as long as care is taken to send
intensive tasks to functions pre-compiled with high-performance languages.
This strategy fails to create an easy-to-use environment because the
programmer needs to think when and where those tasks should go. Considering
that this kind of decision is essential for performance, we argue that
scripting language is not the best solution. Furthermore, we argue that
scripting is the worst tool for teaching new programmers in scientific
computing.
We argue that only experts should use scripting languages (scripts) for
computer programming because beginners cannot understand how dangerous the
flexibility of scripts can be. For example, the assignment of variables
with the same name to different types is often a cause of misunderstandings
and failures. To make this problem even worse, failures due to wrong types
are not captured at runtime---certainly not at compilation time (there is
no compilation time in scripts). In other words, the interpreter is too
permissive. The scientist, if aware (rarely the case with students), will
investigate the numerical output and, after much work, will find the source
of the error. Therefore, this situation is not ideal. To exemplify, the
following is allowed in Python (or Julia---similar syntax):
```
a = 1.0
a = "a" # OK in Python or Julia
```
In the following code, Go will detect the error with a message such as
`./test.go:5: cannot use "a" (type string) as type float64 in assignment`:
```
package main
func main() {
a := 1.0
a = "a" // not accepted in Go
}
```
The problem propagates in scripting languages when developing
objected-oriented code. For example, a member data of a class can be
entirely modified by `anyone`, `anywhere` in Python! This issue completely
defeats the purpose of encapsulation in OOP.
In summary, scripting (e.g., Python) and alike (e.g., Julia, Matlab)
languages are excellent for the expert programmer only who can understand
what is going on. However, they are very misleading to the beginner. In
other words, the strictness of compiled languages DOES help to learn
computer programming. Furthermore, the tools for working with compiled
language often take advantage of well-defined types. The shift towards type
declaration is so apparent that new languages and strategies are being
invented to overcome these issues. For example, TypeScript and Javascript
(ES6) combined with FlowType have been recently developed and have a fast
adoption among web developers. It seems that no new large project will use
non-typed Javascript code.
GO LANGUAGE
Go is a modern programming language created by Google engineers in 2007,
including Robert Griesemer, Rob Pike, and Ken Thompson. The language was
later made public as open source in 2009. Go has since grown exponentially
attracting a large number of co-developers and users. The primary goal
leading to the introduction of yet a new language was the combination of
efficiency (like C/C++) with ease of development (like Python). There are
other several innovations and advantages in Go when compared with
mainstream languages such as C/C++/C#/Java/Python/Ruby/Lua.
Also, Go automatically detects Fortran and C files which helps taking
advantage of good existing code.
The vocabulary in Go is quite small compared to other languages, making
easy to have an overview of the syntax and available commands. Go avoids
complexities such as generics (aka templates) usually available in other
languages (e.g., C++). Go also tries to avoid unnecessary complexity by not
taking `in the language` advanced OOP concepts such as polymorphism,
multiple inheritances, and others. Moreover, Go is somewhat pragmatic in
the sense that, if an operation can be made much more straightforward,
although slightly orthogonal to the central paradigm, this operation will
be carefully defined and adopted in the language specification. These
features, thanks to the unquestionable expertise of the core developers,
made Go an enjoyable language to work with.
One limitation of some other languages is code organization and package
development. For example, C/C++ require the use of `#ifndef`, `#define`,
`#endif`, or `#pragma once` everywhere to prevent code being included more
than once. In fact, it is frustrating at times to find how to deal with
this situation in C/C++, noting that the developer has to worry about what
code goes in the header (.h, .hpp) or in the (.c, .cpp) files. Moreover,
the cyclic nature of `imports` using C/C++ can be a nightmare.
In Python, the organization of packages sometimes lead to situations where
the naming becomes very confusing. For example, we cite the case with
matplotlib.pyplot or pylab or other packages called mypackage.mypackage
that we find around. As another example, in Julia, module definition is
messy, because the user (programmer) has to decide among the files to be
included versus module definition. In summary, package definition is not
simple in Python or Julia.
On the other hand, Go was designed from the beginning to be multi-modular,
prevent cyclic dependency, and made package definition simple. In Go, the
solution is based on how the directories are organized. For example, each
directory is a package, and all files in the same directory belong to that
package. When importing code from other packages, the full path (like URL)
of that package is used. There is no need for `header` files in Go!
Moreover, the coding of one feature can span multiple files in the same
directory. Go comes with a set of tools to build applications and even
download third-party code.
Go also has a strict convention for code formatting. In other words, there
is only one way to format your code in Go---using braces starting at the
end of the line with the `standard` indentation. In this way, a true
`standard` exists for Go codes which makes sharing straightforward and
quite pleasant; e.g., no one argues about the positioning of braces
anymore! Moreover, the strict code convention and specification in Go
largely facilitates the development of auxiliary programming tools to
process code. For instance, the import field in source code can be
automatized as is done with the excellent goimports tool. Many other tools
(e.g., vet, lint) take advantage of Go conciseness.
Because files and directories in Go follow a well-defined specification, it
is very easy (and fast) to find definitions, code lines, files, and
packages (libraries) in Go projects. The compiler in Go benefits from this
organization and indeed helps with Go being very fast to compile code---you
can run Go code as if it was a scripting language! Furthermore, the
excellent specification and organization in Go helped with the creation of
many other tools to assist in Go code development. For instance, we
mention the `goimports` and `gorename` that automatically import all
dependencies as you type and rename a variable in all code derived from a
particular library.
Furthermore, also thanks in part to how well the Go specification and
conciseness were invented, there are several other useful and fast commands
for handling Go code. For instance, we mention the commands `go run,` `go
build`, `go install` and `go get` that perform the operations of running
the code, building the code, installing the code and downloading (and
compiling) external dependencies automatically.
One particular innovation in Go is the concept of concurrency that can lead
to easy-to-write parallel algorithms. Also, Go is a garbage-collected
language that makes easier the code development with fewer worries about
dangling pointers. Go is in part compiled in Go language and has a
reasonably comprehensive standard library, including tools for sorting,
templating, encodings, cryptography, compression algorithms, mathematical
functions (e.g., for complex numbers), image tools, and even web servers.
Furthermore, Go uses the concept of unit tests very well and even includes
tools to assist in benchmarking. Also, Go comes with tools to prepare
examples and to automate the documentation---there is no need for Doxygen!
The Go language syntax resembles that of C/C++/Java (C-class) but has
significant differences. One fundamental difference is the way variables
are declared. The type definition comes after the variable name. This
difference seems strange at first to C-class programmers, but it makes
sense. In fact, it makes reading easy, where one would read `variable and
anotherVariable` are `float64` in `variable, anotherVariable
float64`---there is no need to type float64 twice (or ten times...). The
syntax is particularly convenient when declaring multiple function
arguments.
Go uses curly braces to define scope but has a strict rule regarding where
the braces can be put and how to deal with indentation. This approach makes
the code consistent and easy for collaborations. Also, with the help of
the tools called `goimports` and `gofmt`, the workflow is straightforward.
Go allows some constructions similar to the `range` command in Python and
does not require the use of parentheses in repetition commands as in
C-class.
There is only one repetition command in Go: the `for` keyword. Compared to
C-class languages, the syntax of the `switch` command is simpler and more
powerful. Because of that, the programmer is induced (positively) to use
`switch` over `if` when there is more than one decision branch.
Go code can be directly executed as in: `go run hello.go`. The code could
be built first with `go build hello.go' and executed (Linux) with
`./hello`. But this last approach is only necessary when deploying the
final application. In fact, Go can be used as scripting (using `go run`
like `python`).
Variables are defined in two ways: the first one requires the command `var`
and the second one uses the assignment operator `:=` which automatically
understands the data type. Another great advantage of Go when compared to
many other languages is the standardized auto-initialization of all
variables to their `zero` default value. For instance, numeric variables
declared with `var` are always zero and strings are always empty. This
feature can be exploited with advantage by the programmer who may consider
variable names such that everything starts zeroed already. For instance,
instead of creating a `silent` variable that needs to be set to `true` all
the time, it's more convenient to use a `verbose` variable that is always
`false` already.
One type that is extensively used in Go is the `slice` of integers or real
numbers represented by float point numbers (64-bit version; aka `double` in
C-class). Slices in Go are a view to an internal sequence of values; i.e.,
slices record the start and end positions in memory. Therefore, slices can
be passed into functions with minimal overhead. There is hence no need for
constantly worrying about `by reference` or `by value`. Pointers can also
be used in Go. We use pointers whenever a user-defined structure is to be
modified by the called function. In Go, the slice notation `S[s:E]` means a
view to array `S` starting at `s` and ending at `E-1`, inclusive.
In conclusion, code written in Go is beautiful, concise and with a very
clear logic.
--
You received this message because you are subscribed to the Google Groups
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.