Go and namespaces: is it possible to achieve something similar to Python? - module

I wonder if there is a way to use namespaces in the Go language in a similar way as Python does.
In Python if I have the following files containing functions:
/a.py
def foo():
/b.py
def bar():
I can access foo and bar in a third Python file as following:
import a
a1 = a.foo()
import b
b1 = b.bar()
I had some difficulties finding some documentation on namespaces with the Go language.
How are namespaces implemented in go? With package and import? Or is import dedicated to external libraries?
I think I understood that for each package there should be a dedicated directory. I wonder if this is absolutely mandatory, because it can become impractical whenever a high granularity of modules is the best way to engineer a certain idea. In other words, I would like to avoid using one directory per package (for internal use).

Go's equivalent to Python modules are packages. Unlike Python modules that exist as a single file, a Go package is represented by a directory. While a simple package might only include a single source file in the directory, larger packages can be split over multiple files.
So to take your Python example, you could create a file $GOPATH/src/a/a.go with the following contents:
package a
import "fmt"
func Foo() {
fmt.Println("a.Foo")
}
In your main program, you can call the function like so:
package main
import "a"
func main() {
a.Foo()
}
One thing to note is that only exported types and functions in a will be available externally. That is, types and functions whose names begin with a capital letter (which is why I renamed foo to Foo).
If you don't want to set up a Go workspace, you can also use relative paths for your imports. For instance, if you change the import in the main program to import "./a", then the source code for the a package can be located at a/a.go relative to the main program.

Related

How to test the main package in Golang from a "test" package?

I have a simple program written in Golang. It's an API. So inside the project folder, there's a folder named cmd containing my main package (used to initialise the app and defines the endpoints for the API). There's also a folder named after my program, containing multiple files from a package also named after my program. This package serves as the model to do all the necessary queries and contains all the types I have defined.
I also created a folder called test. It contains all my test files under the package named test. The problem is that to run the tests, I have to access my main package ! Is there a way to do that in Golang ? I tried simply using import "cmd/main" but of course it doesn't work.
I also had an idea. Perhaps I could move all my initialising functions (in the cmd folder) to the package named after my program. This way I could do a regular import in test. And I create, inside of cmd, a main.go in the main package that serves as the entry point for the compiler.
I'm new to Go so I'm not really confident. Do you think it's the right way ?
Thanks.
EDIT : Apparently some people think this question is a duplicate, but it's not. Here's the explanation I gave in on of the comments :
I read this post before posting, but it didn't answer my question
because in that post the person has his tests in the main package. The
reason why I asked my question is because I don't want to have my
tests in the main package. I'd rather have them all in a test folder
inside the same package.
What you want to do is not not possible in GO (assuming you want to test private functions).
because I don't want to have my tests in the main package. I'd rather
have them all in a test folder inside the same package.
Your code belongs to different package if you move it into different folder.
This is how GO defines packages https://golang.org/doc/code.html#Organization:
Each package consists of one or more Go source files in a single
directory.
This is how your code structured:
main
| -- main.go (package main)
+ -- test
| -- main_test.go (package test)
It is idiomatic to keep tests in the same folder with code. It is normal if language or framework set some rules that developer has to follow. GO is pretty strict about that.
This is how you can organize your code:
main
| -- main.go (package main)
| -- main_test.go (package main_test)
| -- main_private_test.go (package main)
Often it makes sense to test code against its pubic interfaces. The best way to do that that, is to put tests into different package. GO convention is to keep tests in the same folder what leads to using the same package name. There is a workaround for that issue. You can add _test (package main_test) prefix to package name for your tests.
If, that is not possible to test your code using public interfaces, you can add another file with tests and use package main in that file.

Importing multiple versions of the same Module/Package for Benchmarking

I am working on a Package,
this package using BinDeps to pull in some C source code, and compile some binaries.
My julia module then mostly just exposes ccalls to those functions.
Now there are about 5 different options for how the C source can be compiled, with various different optimisations turned on.
And to go with them various other changes that are triggered by by a constant that is written to the deps.jl that is output by BinDeps.
So I would like to import each of the different builds of my package as different modules, so I can benchmark them using BenchmarkTools.jl.
Currently, my plan is to make a script that generates 5 different versions of my module, by copying it, and changing it's name, and by using a different deps.jl files to link to different compiled shared libraries.
And then (assuming I renamed them numerically):
using BenchmarkTools
import MyMod_1
import MyMod_2
import MyMod_3
import MyMod_4
import MyMod_5
#show #benchmark MyMod_1.foo()
#show #benchmark MyMod_2.foo()
#show #benchmark MyMod_3.foo()
#show #benchmark MyMod_4.foo()
#show #benchmark MyMod_5.foo()
Currently I am scripting the copying and renaming of modules.
It is a little scary, and seems a bit brittle.
But is there a better way?

Organizing modules in a D project

I come from Java backgrounds and the problem of packaging is as follows then:
I can have many files under the same package, say com.parobay.io. I can then distribute this as a library, and the users will use it like this:
import com.parobay.io.Input;
import com.parobay.io.Output;
or
import com.parobay.io.*; // to import everything
So I can have a single "module (com.parobay.io) and classes defined in multiple files.
So how to I achieve the same in D? Do I have to create a directory com\parobay\io and there place two files called Input.d and Output.d or is there a smarter way?
In Java the rules are very strict, so it's hard to get it wrong. In D there are many possibilities. So are there any conventions, like one class per file, or file name equal to the name of class?
You can choose to do it basically the same as Java, though remember these items:
import foo.* doesn't work in D, but you CAN make a file called package.d in the directory which manually lists public import foo.Input; public import foo.Output; etc. which allows you to import the whole package.
ALWAYS put a module com.parobay.io.Input; or whatever line at the top of any file that is imported. Don't expect it to just work based on directory structure and filename. The directory structure actually isn't strictly necessary, it is just a convention to easily find the file. The module line at the top with the name is the authoritative thing the compiler checks.
D modules often have all lowercase names, but you can use uppercase ones if you like. I think it is nice to use a lowercase name like the class name, so you might call the module io.input and the class Input. The reason for this convention is sometimes filename case gets lost when transferring from system to system. But developers are pretty aware of case so in practice either way should work.
One class per file will work fine or you can put two tightly coupled classes together in the same file (they'll have access to each other's private members if they are in the same file).
See this page for more info: http://dlang.org/module especially search for the heading "Package Module"
Don't use two separate files for your Input and Output classes. Instead, put both classes in a single file, parobay/io.d (corresponding to the module parobay.io).
It's definitely not the convention to limit yourself to just one class per file. D modules are for grouping together code of related functionality. When someone does import parobay.io;, they expect to get all of parobay.io - classes, utility functions and whatever else is relevant. It's similar to Java's import com.parobay.io.*;.
If someone really wants to import specific parts of your module, they can use selective imports:
import parobay.io: Input; // Just the Input class of the parobay.io module.
import parobay.io: Output; // Just the Output class.
import parobay.io: Input, Output; // Just the Input and Output classes.
There are a few additional things to note about this.
Package and module names are conventionally all-lowercase.
It makes everyone's lives easier if the path to the file matches up exactly with its full module name. For example, module foo.bar.baz should be in the file foo/bar/baz.d.
In my experience, it's rare for a D module to be named after a domain name. You can prefix your module names with com or org or net if you really want to, but it's not expected like it is in Java.
Adam D. Ruppe's answer has some great points about explicit module declarations and class member visibility. It's also well worth reading the module and style pages on the official D website.
D community has three widely accepted alternatives.
Write a module named all.d which includes all modules from your package. (Literally '*' --> 'all'). After that you simply do import com.paroboy.io.all;
I see more and more that D developers use _ for this. So they write a module called _.d for this purpose. Similarly to #1, you do import com.paroboy.io._;
Relatively new addition to the D programming language is the package.d module, which can be used to import the package. More about this at the following DIP: http://wiki.dlang.org/DIP37 . If I remember well, DMD supports it since v2.064 . (Documentation: http://dlang.org/module#PackageModule)
I myself use the #1 approach because it is obvious what is going on. While #2 and #3 may be confusing to people reading D source file, especially the third one. A valid question someone may ask: "What the heck am I importing, package?? But import is only for modules!??"
Allthough nothing stops you from having separate module per-class, I would not recommend it. D is truly modular language, so take advantage of that. Group all your types in a single D module. That is my advice, and that is the "D way".
NOTE:
There is a (big) semantic difference between Java "module" and a D module, as you have probably already noticed. I am primarily a Java programmer, so I know how confusing this may be to Java programmers who are playing with D. Java classes in the same package quite often take advantage of the package-level access. However, classes within the same module behave like "friends" in C++.
Speaking about Java modules, they were supposed to come with Java 8 (true modules!), but were posponed and will hopefully be included in Java 9.
UPDATE: We reached conclusion, after a chat on FreeNode (IRC) with some members of the D-Programming-Language, that it is indeed safe now to use the package attribute. It behaves as the specification says.

Opening a module in Erlang

Is there a way to open a module in Erlang and then call its functions without using module name prefix?
Like opening an ML structure!
You can use
-import(my_module, [foo/1,bar/2]).
to import individual functions (in my example foo/1 and bar/2) from another module (my_module), see the modules documentation . There is no way of importing all functions from a module, they have to be explicitly listed.
Also see In Erlang how can I import all functions from a module? for an explanation why you shouldn't import functions!
No, you can't! The methods given by #johlo and #stemm are just work-arounds which allow you to not explicitly write the module name but that is all. The -import(...) declaration is a misnomer and doesn't do what you would expect.
Given Erlang's very dynamic handling of code it would be practically meaningless as well. There is no guarantee that at run-time you have the same "other" module as you had at compile-time, or if it is there at all. All code handling, compiling/loading/purging/reloading/etc. , is done on a module basis and there are no inter-module dependencies or optimisations.
Instead of import you can use defining:
-define(SIN(X), math:sin(X)).
my_func(X) -> ?SIN(X).

How does modular code work in Go?

Not having come from a C/compiled languages background, I'm finding it hard to get to grips with using Go's packages mechanism to create modular code.
In Python, to import a module and get access to it's functions and whatnot, it's a simple case of
import foo
where foo.py is the name of the module you want to import in the same directory. Otherwise you can add an empty __init__.py into a subfolder and access the modules via
from subfolder import foo
You can then access functions by simply referencing them through the module name, e.g. y = foo.bar(y). This makes it easy to separate logical pieces of code from one another.
In Go however, you specify the package name in the source file itself, e.g.
package foo
at the top of the 'foo' module, which you can then supposedly import through
import (
"foo"
)
and then refer to it through that, i.e. y := foo.Bar(x) . But what I can't wrap my head around is how this works in practice. The relevant docs on golang.org seem terse, and directed to people with more (any) experience using makefiles and compilers.
Can someone please clearly explain how you are meant to modularise your code in Go, the right project structure to do so, and how the compilation process works?
Wiki answer, please feel free to add/edit.
Modularization
Multiple files in the same package
This is just what it sounds like. A bunch of files in the same directory that all start with the same package <name> directive means that they are treated as one big set of code by Go. You can transparently call functions in a.go from b.go. This is mostly for the benefit of code organization.
A fictional example would be a "blog" package might be laid out with blog.go (the main file), entry.go, and server.go. It's up to you. While you could write a blog package in one big file, that tends to affect readability.
Multiple packages
The standard library is done this way. Basically you create modules and optionally install them into $GOROOT. Any program you write can import "<name>" and then call <name>.someFunction()
In practice any standalone or shared components should be compiled into packages. Back to the blog package above, If you wanted to add a news feed, you could refactor server.go into a package. Then both blog.go and news.go would both import "server".
Compilation
I currently use gomake with Makefiles. The Go installation comes with some great include files for make that simplify the creation of a package or a command. It's not hard and the best way to get up to speed with these is to just look at sample makefiles from open source projects and read "How to Write Go Code".
In addition to the package organisation, Like pip in python, use dep https://github.com/golang/dep for go package management. if you use it on existing go package it will automatically build the dependency tree with versions for all the packages being used. when shifting to production server, dep ensure will use Gopkg.toml to install all the required packages.
Just use dep ensure -add , other commands for dep are:
Commands:
init Set up a new Go project, or migrate an existing one
status Report the status of the project's dependencies
ensure Ensure a dependency is safely vendored in the project
version Show the dep version information
check Check if imports, Gopkg.toml, and Gopkg.lock are in sync
Examples:
dep init set up a new project
dep ensure install the project's dependencies
dep ensure -update update the locked versions of all dependencies
dep ensure -add github.com/pkg/errors add a dependency to the project