Method prefixes in Go - go

In go, there's a "prefix" that you can put on a function. How is this useful? What are the use cases for this?
Example:
type a struct {
Thing string
}
func (something a) b() {
fmt.Println(something.Thing)
}

Programming is communication: you are communicating to the machine what it should do, and communicating to other programmers (including your future self). Many higher-level programming constructs serve the purpose of making code more expressive--that is, more clearly stating the programmer's intent.
Go's function receivers are like the "self" object in more traditional object-oriented languages. It's a way of grouping a set of functions together and saying "these methods exist primarily to operate on objects of this type", rather than just being general utility methods that happen to take an argument of that type. In other words, they exist to describe the behavior of the abstract object whose state is described by the structure.

It means that the function is attached to the struct, in this case, so that you can do a.b() somewhere else.

Related

Is there a meaningful difference between pass_by_reference vs pass_by_object_sharing in ruby?

Context: i argue that saying pass_by_reference when it's really pass_by_sharing is misleading
Here is the excerpt from the book "Effective Ruby" I'm arguing against
"Most objects are passed around as references and not as actual values. When these types of objects are inserted into a container the collection class is actually storing a reference to the object and not the object itself. (The notable exception to the rule is the Fixnum class whose objects are always passed by value and not by reference.)
The same is true when objects are passed as method arguments. The method will receive a reference to the object and not a new copy. This is great for efficiency but has a startling implication.
"
The 'call by value' and 'call by object sharing' terminology matches Ruby's behavior, and
the terminology is consistent with other object orientated languages that have the same
semantics.
'Call by value' and 'call by object sharing' basically mean the same thing in object orientated languages, so which one is used doesn't really matter. Someone just thought it would clarify the confusion in the terminology to add more terminology.
If 'call by reference' was implemented in Ruby though, it would be something like:
def f(byref x)
x = "CHANGED"
end
x = ""
f(x)
# X is "CHANGED"
Here, the value of x is changed. The value being which object x refers to.
Using terms 'call by reference' just creates confusion though because they mean
different things to different people. It's unnecessary in
languages like Ruby because you don't have a choice. In languages with different
calling mechanisms like C++ and C# it makes more sense to teach these terms because
they have a real effect on programs and we can come up with non hypothetical examples
of them.
When explaining parameters in Ruby, you don't need to use any of these terms though.
They're meaningless to people that don't already know the language. Just
describe the behavior itself without that terminology and avoid the baggage.
I would say if you insist on using these terms, then use 'call by value' because it's usually considered more correct. The 'Programming Ruby' book calls it 'call by value', as well as plenty of Ruby programmers. Using the term with a different meaning than its technical one isn't helpful.
You are right. Ruby is pass-by-value only. The semantics of passing and assigning in Ruby are exactly identical to those in Java. And Java is universally described (on Stack Overflow and the rest of the Internet) as pass-by-value only. Terms about languages such as pass-by-value and pass-by-reference must be consistently used across languages to be meaningful.
The thing that is often misunderstood by people who say Java, Ruby, etc. "pass objects by reference" is that "objects" are not values in these languages, and thus cannot be "passed". The value of every variable and result of every expression is a "reference", which is a pointer to an object. The expression for creating an object returns an object pointer; when you access an attribute through the dot notation, the left side takes an object pointer; when you assign one variable to another, you copy the pointer resulting in two pointers to the same object. You always deal with pointers to objects, never objects themselves.
This is made explicit in Java as the only types in Java are primitive types and reference types -- there are no "object types". So every value in Java that is not a primitive is a reference (a pointer to an object). Ruby is dynamically-typed, so variables don't have explicit types. But you can imagine a dynamically-typed language as just a statically-typed language having exactly one type; and for languages like Python and Ruby, if this type were described, it be a pointer-to-object type.
The issue ultimately boils down to a problem of definitions. People argue over things because there is no precise definition, or they each have slightly different definitions. Rather then argue over vaguely-defined things like what is the "value" of a variable, or whether named values are "variables" or "names", etc., we need to use a definition for pass-by-value and pass-by-reference that is based purely on semantics of a language structure. #fgb's answer provides a clear semantic test for pass-by-reference. In "true pass-by-reference", e.g. with & in C++ and PHP, or with ref or out in C#, simple assignment (i.e. =) to a parameter variable has the same effect as simple assignment to the passed variable in the original scope. In pass-by-value, simple assignment (i.e. =) to a parameter variable has no effect in the original scope. This is what we see in Java, Python, Ruby, and many other languages.
I dislike people coming up with new names like "pass by object sharing", when they don't understand that the semantics are covered by an existing term, pass-by-value. Adding a new term only adds more to the confusion rather than reduce it, because it does not resolve the definitions of existing terms, only adding a new term that also needs to be defined.

Programming Go, using Unified Modelling Language Diagrams

I have just started using Go (GoLang) and I am finding it a great language. However, after many years of UML and the Object Oriented methods, I find that modelling Go programs (Reverse engineering) is a bit problematic, in that Go Structs contain properties/state, but no methods, and methods/functions that use Structs as parameters (even the ones that do magic so that it makes a Struct look like an object), don't contain methods, or state.
Does this mean I should be using another Methodology to model a Go Program or does UML sufficiently model the language constructs?
Yes I know that if you use methods on the Structs that the behavior of an object in UML can be mapped into Go via a combination of a Struct and a Struct Method, but I am finding this to be wrong, an impedance mismatch in paradigms of sorts.
Is it time for a new (perish the thought!) diagramming technique, for the brave new world where behavior is no longer controlled by an object? can behavior be modeled without reference to the state that it is affecting?
Update:
I am trying Data Flow Diagrams out, to see if they fit better to the paradigm. So far so good, but I think I am going to come unstuck when I model the Methods of a Struct, the compromise in the DFD being that they are treated as Functions. :(
Go supports inheritance!!! arghhh!!! (head is blown clean off.) you can compose a Struct which is made of another Struct, which has methods, that the Sub Struct now inherits...you getting this? my mind is blown. Means that UML IS valid...fully but it feels dirty.
Go Does not support inheritance, it just appears so. :) DFD's it is then!
The fact that methods are declared outside the definition of the struct itself should not be significant; it is just a minor syntax difference. The methods belong to the struct type just as surely as if they were inside the braces. (They are declared outside the braces because methods aren't limited to structs.)
The real potential problem with using UML with Go is that UML is normally used with traditional object-oriented design (i.e. class hierarchies), and Go takes a different approach to inheritance and polymorphism. Maybe UML can be adapted to Go's type system—I'm not familiar enough with UML to say—but your design approach will probably need to change somewhat whether you continue using UML or not.
Go is not intended to be used in the everything-is-an-object style of Smalltalk and Java. Idiomatic Go programs generally contain a large percentage of procedural code. If your design process focuses on object modeling, it will not work well for Go.
UML still gives you tools useful for analysis and design of components, interfaces, and data. Go is not an OO language, so you cannot use inheritance, polymorphism, methods, etc. You don't need a new paradigm, you may need an old one: Structured Analysis and Structured Design.
Go Structs contain properties/state, but no methods, and
methods/functions that use Structs as parameters (even the ones that
do magic so that it makes a Struct look like an object), don't contain
methods, or state.
As you may know, in C++ you can also declare methods on structs - just as in classes with the only difference that you won't be able to use access modifiers.
In OOP languages you declare methods of a class inside the class definition, giving the feeling that these methods are somehow part of the class. This is not true for most languages and Go makes this obvious.
When you declare something like the following pseudo-code in a traditional OOP language:
class Foo {
public function bar(x int) {
// ...
}
}
the linker will export a function that will look something like:
Foo__bar(this Foo, x int)
When you then do (assume f is an instance of Foo):
f.bar(3)
you are in fact (and indirectly, more on that later) doing:
Foo__bar(f, 3)
The class instance itself will only contain a so called vtable with function pointers to the methods it implements and/or inherits.
Additionally, methods do not contain state, at least not in the contemporary programming world.
Does this mean I should be using another Methodology to model a Go
Program or does UML sufficiently model the language constructs?
UML should suffice.
Is it time for a new (perish the thought!) diagramming technique, for
the brave new world where behavior is no longer controlled by an
object?
Naa.
Can behavior be modeled without reference to the state that it is
affecting?
Yes, that's what interfaces are for.
I am trying Data Flow Diagrams out, to see if they fit better to the
paradigm. So far so good, but I think I am going to come unstuck when
I model the Methods of a struct, the compromise in the DFD being that
they are treated as Functions. :(
Do not get lost in abstractions, break them. There is no perfect paradigm and there will never be.
If you like planning and modeling more than programming you should just stick with Java.
If you like building and maintaining the actual code and working systems you should try just planning your Go program on a piece of paper or a whiteboard and get programming.

Do you use nouns for classnames that represent callable objects?

There is a more generic question asked here. Consider this as an extension to that.
I understand that classes represent type of objects and we should use nouns as their names. But there are function objects supported in many language that acts more like functions than objects. Should I name those classes also as nouns, or verbs are ok in that case. doSomething(), semantically, makes more sense than Something().
Update / Conclusion
The two top voted answers I got on this shares a mixed opinion:
Attila
In the case of functors, however, they represent "action", so naming them with a verb (or some sort of noun-verb combination) is more appropriate -- just like you would name a function based on what it is doing.
Rook
The instance of a functor on the other hand is effectively a function, and would perhaps be better named accordingly. Following Jim's suggestion above, SomethingDoer doSomething; doSomething();
Both of them, after going through some code, seems to be the common practice. In GNU implementation of stl I found classes like negate, plus, minus (bits/stl_function.h) etc. And variate_generator, mersenne_twister (tr1/random.h). Similarly in boost I found classes like base_visitor, predecessor_recorder (graph/visitors.hpp) as well as inverse, inplace_erase (icl/functors.hpp)
Objects (and thus classes) usually represent "things", therefore you want to name them with nouns. In the case of functors, however, they represent "action", so naming them with a verb (or some sort of noun-verb combination) is more appropriate -- just like you would name a function based on what it is doing.
In general, you would want to name things (objects, functions, etc.) after their purpose, that is, what they represent in the program/the world.
You can think of functors as functions (thus "action") with state. Since the clean way of achieving this (having a state associated with your "action") is to create an object that stores the state, you get an object, which is really an "action" (a fancy function).
Note that the above applies to languages where you can make a pure functor, that is, an object where the invocation is the same as for a regular function (e.g. C++). In languages where this is not supported (that is, you have to have a method other than operator() called, like command.do()), you would want to name the command-like class/object a noun and name the method called a verb.
The type of the functor is a class, which you may as well name in your usual style (for instance, a noun) because it doesn't really do anything on its own. The instance of a functor on the other hand is effectively a function, and would perhaps be better named accordingly. Following Jim's suggestion above, SomethingDoer doSomething; doSomething();
A quick peek at my own code shows I've managed to avoid this issue entirely by using words which are both nouns and verbs... Filter and Show for example. Might be tricky to apply that naming scheme in all circumstances, however!
I suggest you give them a suffix like Function, Callback, Action, Command, etc. so that you will have classes called SortFunction, SearchAction, ExecuteCommand instead of Sort, Search, Execute which sound more like names of actual functions.
I think there are two ways to see this:
1) The class which could be named sensibly so that it can be invoked as a functor directly upon construction:
Doer()(); // constructed and invoked in one shot, compiler could optimize
2) The instance in cases where we want the functor to be invoked multiple times on a stateless functor object, or perhaps for stylistic reasons when #1's syntax is not preferable.
Doer _do;
_do(); // operator () invocation after construction
I like #Rook's suggestion above of naming the class with words that have the same verb and noun forms such as Search or Filter.

How to name factory like methods?

I guess that most factory-like methods start with create. But why are they called "create"? Why not "make", "produce", "build", "generate" or something else? Is it only a matter of taste? A convention? Or is there a special meaning in "create"?
createURI(...)
makeURI(...)
produceURI(...)
buildURI(...)
generateURI(...)
Which one would you choose in general and why?
Some random thoughts:
'Create' fits the feature better than most other words. The next best word I can think of off the top of my head is 'Construct'. In the past, 'Alloc' (allocate) might have been used in similar situations, reflecting the greater emphasis on blocks of data than objects in languages like C.
'Create' is a short, simple word that has a clear intuitive meaning. In most cases people probably just pick it as the first, most obvious word that comes to mind when they wish to create something. It's a common naming convention, and "object creation" is a common way of describing the process of... creating objects.
'Construct' is close, but it is usually used to describe a specific stage in the process of creating an object (allocate/new, construct, initialise...)
'Build' and 'Make' are common terms for processes relating to compiling code, so have different connotations to programmers, implying a process that comprises many steps and possibly a lot of disk activity. However, the idea of a Factory "building" something is a sensible idea - especially in cases where a complex data-structure is built, or many separate pieces of information are combined in some way.
'Generate' to me implies a calculation which is used to produce a value from an input, such as generating a hash code or a random number.
'Produce', 'Generate', 'Construct' are longer to type/read than 'Create'. Historically programmers have favoured short names to reduce typing/reading.
Joshua Bloch in "Effective Java" suggests the following naming conventions
valueOf — Returns an instance that has, loosely speaking, the same value
as its parameters. Such static factories are effectively
type-conversion methods.
of — A concise alternative to valueOf, popularized by EnumSet (Item 32).
getInstance — Returns an instance that is described by the parameters
but cannot be said to have the same value. In the case of a singleton,
getInstance takes no parameters and returns the sole instance.
newInstance — Like getInstance, except that newInstance guarantees that
each instance returned is distinct from all others.
getType — Like getInstance, but used when the factory method is in a
different class. Type indicates the type of object returned by the
factory method.
newType — Like newInstance, but used when the factory method is in a
different class. Type indicates the type of object returned by the
factory method.
Wanted to add a couple of points I don't see in other answers.
Although traditionally 'Factory' means 'creates objects', I like to think of it more broadly as 'returns me an object that behaves as I expect'. I shouldn't always have to know whether it's a brand new object, in fact I might not care. So in suitable cases you might avoid a 'Create...' name, even if that's how you're implementing it right now.
Guava is a good repository of factory naming ideas. It is popularising a nice DSL style. examples:
Lists.newArrayListWithCapacity(100);
ImmutableList.of("Hello", "World");
"Create" and "make" are short, reasonably evocative, and not tied to other patterns in naming that I can think of. I've also seen both quite frequently and suspect they may be "de facto standards". I'd choose one and use it consistently at least within a project. (Looking at my own current project, I seem to use "make". I hope I'm consistent...)
Avoid "build" because it fits better with the Builder pattern and avoid "produce" because it evokes Producer/Consumer.
To really continue the metaphor of the "Factory" name for the pattern, I'd be tempted by "manufacture", but that's too long a word.
I think it stems from “to create an object”. However, in English, the word “create” is associated with the notion “to cause to come into being, as something unique that would not naturally evolve or that is not made by ordinary processes,” and “to evolve from one's own thought or imagination, as a work of art or an invention.” So it seems as “create” is not the proper word to use. “Make,” on the other hand, means “to bring into existence by shaping or changing material, combining parts, etc.” For example, you don’t create a dress, you make a dress (object). So, in my opinion, “make” by meaning “to produce; cause to exist or happen; bring about” is a far better word for factory methods.
Partly convention, partly semantics.
Factory methods (signalled by the traditional create) should invoke appropriate constructors. If I saw buildURI, I would assume that it involved some computation, or assembly from parts (and I would not think there was a factory involved). The first thing that I thought when I saw generateURI is making something random, like a new personalized download link. They are not all the same, different words evoke different meanings; but most of them are not conventionalised.
I'd call it UriFactory.Create()
Where,
UriFactory is the name of the class type which is provides method(s) that create Uri instances.
and Create() method is overloaded for as many as variations you have in your specs.
public static class UriFactory
{
//Default Creator
public static UriType Create()
{
}
//An overload for Create()
public static UriType Create(someArgs)
{
}
}
I like new. To me
var foo = newFoo();
reads better than
var foo = createFoo();
Translated to english we have foo is a new foo or foo is create foo. While I'm not a grammer expert I'm pretty sure the latter is grammatically incorrect.
I'd point out that I've seen all of the verbs but produce in use in some library or other, so I wouldn't call create being an universal convention.
Now, create does sound better to me, evokes the precise meaning of the action.
So yes, it is a matter of (literary) taste.
Personally I like instantiate and instantiateWith, but that's just because of my Unity and Objective C experiences. Naming conventions inside the Unity engine seem to revolve around the word instantiate to create an instance via a factory method, and Objective C seems to like with to indicate what the parameter/s are. This only really works well if the method is in the class that is going to be instantiated though (and in languages that allow constructor overloading, this isn't so much of a 'thing').
Just plain old Objective C's initWith is also a good'un!

Why isn't DRY considered a good thing for type declarations?

It seems like people who would never dare cut and paste code have no problem specifying the type of something over and over and over. Why isn't it emphasized as a good practice that type information should be declared once and only once so as to cause as little ripple effect as possible throughout the source code if the type of something is modified? For example, using pseudocode that borrows from C# and D:
MyClass<MyGenericArg> foo = new MyClass<MyGenericArg>(ctorArg);
void fun(MyClass<MyGenericArg> arg) {
gun(arg);
}
void gun(MyClass<MyGenericArg> arg) {
// do stuff.
}
Vs.
var foo = new MyClass<MyGenericArg>(ctorArg);
void fun(T)(T arg) {
gun(arg);
}
void gun(T)(T arg) {
// do stuff.
}
It seems like the second one is a lot less brittle if you change the name of MyClass, or change the type of MyGenericArg, or otherwise decide to change the type of foo.
I don't think you're going to find a lot of disagreement with your argument that the latter example is "better" for the programmer. A lot of language design features are there because they're better for the compiler implementer!
See Scala for one reification of your idea.
Other languages (such as the ML family) take type inference much further, and create a whole style of programming where the type is enormously important, much more so than in the C-like languages. (See The Little MLer for a gentle introduction.)
It isn't considered a bad thing at all. In fact, C# maintainers are already moving a bit towards reducing the tiring boilerplate with the var keyword, where
MyContainer<MyType> cont = new MyContainer<MyType>();
is exactly equivalent to
var cont = new MyContainer<MyType>();
Although you will see many people who will argue against var usage, which kind of shows that many people is not familiar with strong typed languages with type inference; type inference is mistaken for dynamic/soft typing.
Repetition may lead to more readable code, and sometimes may be required in the general case. I've always seen the focus of DRY being more about duplicating logic than repeating literal text. Technically, you can eliminate 'var' and 'void' from your bottom code as well. Not to mention you indicate scope with indentation, why repeat yourself with braces?
Repetition can also have practical benefits: parsing by a program is easier by keeping the 'void', for example.
(However, I still strongly agree with you on prefering "var name = new Type()" over "Type name = new Type()".)
It's a bad thing. This very topic was mentioned in Google's Go language Techtalk.
Albert Einstein said, "Everything should be made as simple as possible, but not one bit simpler."
Your complaint makes no sense in the case of a dynamically typed language, so you must intend this to refer to statically typed languages. In that case, your replacement example implicitly uses Generics (aka Template Classes), which means that any time that fun or gun is used, a new definition based upon the type of the argument. That could result in dozens of extra methods, regardless of the intent of the programmer. In particular, you're throwing away the benefit of compiler-checked type-safety for a runtime error.
If your goal was to simply pass through the argument without checking its type, then the correct type would be Object not T.
Type declarations are intended to make the programmer's life simpler, by catching errors at compile-time, instead of failing at runtime. If you have an overly complex type definition, then you probably don't understand your data. In your example, I would have suggested adding fun and gun to MyClass, instead of defining them separately. If fun and gun don't apply to all possible template types, then they should be defined in an explicit subclass, not as separate functions that take a templated class argument.
Generics exist as a way to wrap behavior around more specific objects. List, Queue, Stack, these are fine reasons for Generics, but at the end of the day, the only thing you should be doing with a bare Generic is creating an instance of it, and calling methods on it. If you really feel the need to do more than that with a Generic, then you probably need to embed your Generic class as an instance object in a wrapper class, one that defines the behaviors you need. You do this for the same reason that you embed primitives into a class: because by themselves, numbers and strings do not convey semantic information about their contents.
Example:
What semantic information does List convey? Just that you're working with multiple triples of integers. On the other hand, List, where a color has 3 integers (red, blue, green) with bounded values (0-255) conveys the intent that you're working with multiple Colors, but provides no hint as to whether the List is ordered, allows duplicates, or any other information about the Colors. Finally a Palette can add those semantics for you: a Palette has a name, contains multiple Colors, but no duplicates, and order isn't important.
This has gotten a bit far afield from the original question, but what it means to me is that DRY (Don't Repeat Yourself) means specifying information once, but that specification should be as precise as is necessary.

Resources