
Writing Web Applications in Go - gits1225
http://golang.org/doc/articles/wiki/
======
michaelfairley
I've run Go in production for a web application, and I'll say that Go is not a
great choice for this task. The built in HTTP server doesn't have a way to
shut down gracefully, there's not a good zero-downtime restart story, and the
standard library SQL package (and abstractions on top of it) has some nasty
warts that only show up under concurrent load.

If you build a webapp in Go, be prepared to spend a lot of time monkeying
around with problems that are solved issues on most other platforms.

~~~
icey
Could you share some information about the SQL warts you found under
concurrent load?

~~~
michaelfairley
My favorite – the method that determines the size of the connection pool:
<http://golang.org/src/pkg/database/sql/sql.go#L227>

~~~
icey
That does look pretty gross, thanks for sharing. Any other ones stick out in
your mind? I've been happy using Go against postgres, but haven't had a
significant enough load to run into real problems yet.

------
kinofcain
One of the first things you're likely to desire after going through this
tutorial is more sophisticated routing, the gorilla toolkit has an excellent
reversible routing system that works with the std lib http packages:

<http://www.gorillatoolkit.org/pkg/mux>

------
NateDad
You can actually read the go language spec in a couple hours. You can pick up
and be productive in the language in a weekend. And yet you can optimize code
down to the byte level where needed. This is the uniqueness of Go. It is
familiar enough that most anyone can look at some code and figure out what
it's doing, but it's not hard to make complex and performant code. Simple and
powerful is better than complex and powerful.

~~~
eropple
_> And yet you can optimize code down to the byte level where needed._

I can't see how this can be true in any real form if I can't completely turn
off garbage collection. There's a lower bound to your ability to eke out
additional perf when you have to take into account a stop-the-world garbage
collector that you don't directly control.

I'm certainly not the best programmer around, but I tend to subscribe to the
notion that perhaps _complex and powerful_ exists because that complexity
grants additional flexibility to those who know how to use it. (Hell, Rob Pike
has admitted as much on his blog regarding why Go doesn't appeal to many
people who are competent C++ programmers. Though he decided to frame it as if
it's a negative, which I really appreciated.)

~~~
lucian1900
Go makes it easy (and common) enough to avoid spurious allocations and to
reuse memory. The GC is often relied on about as much as explicit deallocation
in C++, not as much as in functional or dynamic languages.

------
trungonnews
Question for Gophers. How do you guys debug your code? What IDE do you use?

Scala works beautifully with IDEA IDE, one of the best IDE out there! GUI
debugger just works out of the box.

I tried using Go for a little bit but I find IDE and tooling support for Go is
a bit lacking. Do people consider these aspects anymore when they evaluate a
new language? A proper IDE support can greatly boost your productivity!

~~~
jff
I debug it using Printfs as needed--it just doesn't need a ton of debugging,
and Go makes it easy with the %#v format in Printf giving an appropriate,
annotated representation of pretty much any data type. Stack traces are also
very informative if something goes badly wrong.

I'm pretty sure GDB works now too, but again I have never really felt the need
for it. But then, I've never really felt the need for syntax highlighting,
code folding, or auto-completed function names. I feel like if my Go code has
reached a level of complexity where it needs those things, I've done something
wrong. My IDE is Acme, it lets me edit files, run my build scripts, and
execute test programs.

~~~
trungonnews
This sounds like me when I was still in college trying to hack out a 100 line
of code for a small programming assignment... But this approach does not scale
with a million line of code project. Anyone with real programming experience
can tell you this. Corporates don't just shell out thousand of dollars for an
IDE license for no reason. :)

~~~
jff
Crap, there I was thinking developing Go for my employers was "real
programming"! I guess I should go add a lot more boilerplate and un-needed
complexity, maybe rewrite it in a true enterprise language like Java. Then it
would be a big enough project to need an IDE, making it a "real" project.

Maybe I should just delete all these repos I've worked on for my job, the
cluster management tool, the pedestrian simulator, the GSM radio emulator, the
VM monitoring infrastructure, the distributed key-value store. They were
written in Go, so I guess they weren't real programs.

~~~
trungonnews
Hey. If you can do all of that without requiring any assistance from a good
IDE, then you have my respect. :)

However, I'm still sticking to my point. Debugging your code using Printf
feels like 1990s.

~~~
NateDad
You can always use gdb to debug. However, with type safety and proper unit
tests (which are easy to write with Go's interfaces) you often don't need it.

------
photon137
I've often wondered about using Go as an architectural choice - it's near-
native fast, the syntax and semantics are good, it's GC'ed and runs on Linux
(edit: my language of choice is C# - and Go is the only one that comes close
to it _and_ runs on Linux, IMO - any others out there?- performance is
critical).

However, if I decide to go with Go as a framework choice, is there an active
market of Go developers out there from which one can hire?

~~~
icey
I've spent the past couple of months working with Go, coming from a mostly C#
and Python background. One of the attractions to the language for me is that
it's straightforward to pick up. Because there aren't a lot of "fancy"
features in the language like Linq or list comprehensions, it's easy to dive
into a block of code and figure out what's going on without requiring a lot of
background knowledge.

The language eschews some brevity in exchange for clarity, which gives me a
lot of confidence that I can take a good developer from any background, give
them a week and feel like they've got a decent chance of acquiring the
knowledge they need to work with the language.

The newness of the language means that there isn't a huge ecosystem of
libraries available, BUT the standard lib is pretty damn great, and there are
more and more people coming to the language every day.

My favorite thing about go is it's overall sense of boringness - Go code seems
very predictable. There's a culture of digging into the source throughout the
community, and tools like go fmt & go vet ensure that most code looks similar.

It'd be worth spending a week with it to write something useful to get a sense
of whether or not you truly like it, but my experience has been very positive
so far.

~~~
StavrosK
My problem with it is how frustrating it is to write when you're not very
familiar with it, but I suspect that's more of a generic complaint about
learning a new language rather than soecifically about Go. Every line I write,
I go "argh, I wonder if this is the idiomatic way to do this" and I get
frustrated a lot.

I love the features, though, especially the concurrency ones. It was
conceptually trivial to write a multicasting TCP proxy in it.

~~~
icey
I had the same problems when I first started learning the language, and while
I'm certain I've got a lot more to learn I found that making a habit of
reading lots of source code made a huge difference.

After a little while you start thinking about "can this code be clearer? Are
the intentions obvious?" and that makes the code much easier to write.

Go is incredibly easy to refactor, so instead of worrying about being exactly
right, you can focus on "is this easy to reason about?". My experience has
been that this process will get you very close to idiomatic code on its own.

~~~
StavrosK
I'm not so much frustrated about being exactly right at a high level, since I
am experienced enough with other languages to get the general architecture
down correctly. It's more like "How do you declare a slice of channels of
channels of ints? Do you make() it or not? If you want to pass a channel, do
you pass a pointer or not? How do you pass and reference a pointer? Do you use
make in the outermost scope? How do you iterate over a channel but still
handle a close?"

It's stuff like that, things I already know how to do in other languages but
whose syntax eludes me in Go. I think all I can do is power through it until I
gain some familiarity, though. Good thing the people in the IRC channel are
amazingly helpful.

------
StavrosK
Most of the comments here generally rave about Go, but what would be more
useful to us is things that people found not to be so great in it, like
michaelfairley's comment. I'd like to know what Go isn't good for, to avoid
spending ages writing something in it because I like its features only to
discover it can't easily do something I want.

------
rartichoke
I still don't see the use case for web app or web game development in Go.

Go ahead and make a mini Go app, re-implement half the features that Express
in Node has, then benchmark the 2 with real data using the same data and
templates.

Come back when you see that once you start pulling records in from mongodb or
somewhere else and start rendering either server side templates with this
mongo data or serving json back then the performance differences of the 2
frameworks begin to disappear.

Node will perform better under high concurrency too for most sized responses.

So where's the motivation to switch? If I switch to Go then I have to learn Go
+ I'm still using Javascript on the front end.

If I stick with Node then I can use my JS knowledge on both ends. This is a
really big deal for day to day web app programming and is a deal breaker for
html5 games.

Go cannot be taken seriously to be used for web apps until it offers actual
performance gains over JS and gets something that lets you write Go but it
spits out JS for the client, sort of like Java has GWT (ps. that bombermine
mmo uses GWT).

There's also a serious lack of good light weight web frameworks for Go. None
of them come close to what Express does for Node, and I'm not the only one who
thinks Express is really close to an excellent mix of features without getting
in your face.

~~~
BarkMore
_Node will perform better under high concurrency too for most sized
responses._

Can you share evidence supporting this claim?

~~~
rartichoke
I tested it with Go v1.0.3 vs Node v0.8.21 + Express v3.1.0

I used mgo with Go to connect to mongodb.

Then I filled it with 1,024 documents that was composed of 2 fields. One field
with a few bytes of text and the other with a paragraph of text.

Then I created a few handlers to return:

1) 1x document as json

2) 7x documents as json

3) 15x documents as json

At 15x I decided this was likely going to generate a response large enough
that there's no point going higher. It was about 25kb worth of json.

Then I used a lib called "routes": <https://github.com/drone/routes>

It's not really close to what express does but it's better than nothing. Then
I added in my own etag generator using the same method that express does (it
gens it off the body length) for responses > 1kb.

Then I benchmarked each route 3 times with ab using: -n 7500 -c {50, 250, 750,
1500}

I ignored the first and averaged the last 2 results.

I did this on a local VM locked down to 1 CPU with 512mb of ram with a c2d
2.13ghz CPU and a 7200 rpm sata HD.

Then I did the same with express using just bodyParser since neither setup had
session support. Go didn't have a Redis store that was capable of working with
the Gorilla session lib so I didn't use sessions on both setups.

I used the native mongodb driver for node.

Express was for the most part 10-15% faster where faster is more requests per
second served. The latency was back and forth. I feel like the latency @ 99%
was tighter with Go once the concurrency got really high but the amount was
not enough to matter.

For example once I got to the higher concurrencies both were taking a
ridiculous amount of time (over 7 seconds) on my old crappy desktop. Loading
in 5.5 seconds instead of 7 seconds is not really "better" since it's abysmal
on both.

Go is much better at responding with large amounts of data when the database
call is eliminated. I can only assume its ability to deal with large strings
is leaps and bounds superior to v8 which makes sense to me.

The thing is though, that's pretty much irrelevant. If I was going to serve
static content I would be using S3 or nginx. If I'm serving dynamic content
then I'm likely pulling this in from a database.

~~~
tuxychandru
_Go is much better at responding with large amounts of data when the database
call is eliminated. I can only assume its ability to deal with large strings
is leaps and bounds superior to v8 which makes sense to me._

In my own micro-benchmark, I've seen that BSON decoding takes big chunk of
time when using mgo. That should explain why the go version got faster when DB
access was removed.

This shouldn't come as a surprise as the node.js driver uses a BSON parser
written in C++ by default.

~~~
rartichoke
It wasn't just a small difference though. The difference between returning
10kb of json from a function vs 10kb of json from mgo was insanely different.

I don't think it's because the bson C++ implementation is so much faster than
Go.

I think it's because Go is clearly faster than JS but it doesn't matter once
you introduce db calls.

It's sort of like using "for in" vs "for" in JS in the browser. It doesn't
really matter which one of them might be faster than the other, as soon as you
touch the DOM the difference becomes meaningless and if you jsperf it with DOM
touching the results will be the same.

------
sshillo
If you need performance why not go with scala. The play framework is super
easy to use. Anyone who is familiar with mvc will pick it up very fast. There
is also Martin Odersky's course which is a great intro.

~~~
lucian1900
Scala is extremely complex, rivaling C++. Its syntax in particular is just
crazy.

Which is a shame, since it's otherwise somewhat interesting.

Haskell is a much better choice than Scala, as long as JVM isn't required.

~~~
GhotiFish
I'm sorry, but as I've tried to learn Haskell in 2 month sprints 4 separate
times and failed, I can not in good conscience recommend Haskell, ever. I like
the language allot, but even the programmers I believe are extremely talented
just cannot learn it, let alone 99% of people I have to work with who simply
can not even begin to make use of the language at it's most basic form.

A professor I knew, who was easily one of the more decorated in my university,
claimed he knew Haskell.

I had used Haskell to parse biomedical data for my course on biometrics, as
the data was inconsistent and full of errors, the correct design was to create
a monadic structure. I consulted that professor, and he was flummoxed, just on
the basic structure of the program (which was done in a basic top down style
of declaring the types and breaking large functions into small ones).

I fully accept my inability to use the language in a useful way may just be
symptomatic of me being an idiot. I fully accept that my professors inability
to understand the language in a any way may be symptomatic of him being an
idiot.

But as big a failure as I am at learning this language, I can't imagine the
result of tasking someone who doesn't enjoy programming with maintaining
Haskell.

If scala is worse, then that's just horrifying.

~~~
josh-j
Just considering the language, then I think Scala is considerably easier to
learn than haskell _if_ you're from an OO background. It's a multi-paradigm
language making it easy to use it like a better c++11. However, idiomatic
Scala is functional, and so you're pushed in another direction by the
community (but, importantly, not forced). However, starting with a blank
slate, then Haskell might be the easier language to learn.

But if we consider the resources to learn the language along with the
language, then I think Scala dominates Haskell. Haskell was painful for me to
learn because to become proficient I had to trudge through not only books but
wikis, blogs, and code. There is nothing like Odersky's Scala book in Haskell.
Learn you a Haskell, the Haskell wikibook, and Real World Haskell are all
_terrible_ at preparing someone to become a proficient haskeller because while
they show you the language they don't train you to think functionally.

In imperative languages you're giving a lot of sequential instructions to a
robot. In functional languages you're programming the robot to understand a
new language, and then you describe the way things ought to be in that
language.

~~~
GhotiFish
This is another thing I persistently thought while I was learning Haskell

    
    
       "It's a paradigm shift, you're used to programming
        imperatively, this is not imperative. Think back to when
        you first started programming, you got caught on doing
        simple things, right? This is the same."
    

On sober reflection, I don't buy this logic any more. Haskell's ability to be
generic is really cool, so cool that it has a massive standard library of
itemized, tried and tested bits of logic that can be used anywhere, and I do
mean anywhere. All of which you as a new programmer are tasked with getting
acquainted with. As a new programmer you must abstract your program out in a
way that fits one or more these component pieces, that can fit the standard
library. Ouch.

Of course, this library only gives you a toolbox to cover some fundamental
logic, you can express really interesting things in short lines if you're
skilled enough to abstract your problem out into general behaviour. Even I got
this far, but when the problem your working on is best modelled through state,
which is basically everything, you now have to understand monads.

What portion of the population do you think can utter these words confidently?
"I Understand Monads"

Haskell provides no ramp up, there is no learning curve. I don't believe
Haskell's problem is that it's different, I believe it's problem is that it's
_different and difficult_.

~~~
josh-j
It is different and difficult. I think that's because functional programming
isn't simply a sideways step from imperative programming, but is instead a
level of abstraction higher than imperative programming.

Hofstadter says analogy is the core of cognition. We tie unknown things to
known things to understand them, and I think that's why you get all these bad
analogies where people try to tie the more abstract concepts of fp like monads
to everyday things ( "monads are like burritos," for example).

And this really doesn't make sense because monads and such are pure
abstractions. How do you tie a pure abstraction to something concrete? It's
like saying zero is like a burrito.

The better analogies tie pure abstractions like monads and arrows to other
abstractions that you already understand. For instance, Odersky trains you by
iteratively refactoring imperative Scala code into more functional code, and
thereby gradually carrying you up the ladder of abstraction.

------
lumberjack
I was kind of disappointed that they went with a flat file approach for
permanent storage, especially because the documentation for the typical RDBMS
interaction isn't exactly comprehensive.

------
tferris
What's the fastest templating engine for Go? And how does it compare to
respective implementations in other languages?

------
humanspecies
Go still hasn't found a niche to be useful to. Nobody's giving up 30 years of
C for systems programming, nobody's going to use Go for web apps when higher
level languages are clearly more practical, nobody will give up Haskell for
scientific and massive parallel programming. All in all I think Go is an
interesting experiment but it serves no purpose that I can use right now

~~~
bromang
C/C++ is the language of choice for scientific and massively parallel
programming. as far as I know Haskell is not really competitive in that area.

~~~
lutusp
> C/C++ is the language of choice ...

Linus Torvalds would disagree that C and C++ are the same language as
suggested by "C/C++" and by the singular pronoun that follows.

<http://harmful.cat-v.org/software/c++/linus>

And maybe too much weight is given to Torvalds' views on this and other
topics.

~~~
danieldk
_Linus Torvalds would disagree that C and C++ are the same language as
suggested by "C/C++" and by the singular pronoun that follows._

One can easily program as if it were C, using templates to avoid ugly macro
mess for generic algorithms and types.

Edit: corrected is -> as.

~~~
lutusp
> One can easily program is if [sic] it were C, using templates to avoid ugly
> macro mess for generic algorithms and types.

Did you mean "as if"? If so, that's exactly what Torvalds objects to -- the
things about C++ that supposedly represent improvements over C. He goes on
about how many of the conveniences of C++ -- like the STL -- aren't as wrung
out as most people think and don't actually work as intended.

I don't necessarily agree with his position in all respects, but some of the
enhancements in C++, aren't actually enhancements.

------
neya
Why do people choose 'Go' over Scala? The latter is a 'better' choice (in my
opinion) for web applications and add in the play framework, you've got an
ultra-fast, scalable web app. running in minutes. I do admit that Scala has a
steeper learning curve, but my guess is that it's worth it.

Can anyone explain WHY Scala seems to be ignored by most of the programming
community, especially here on HN, where everyone seems to be in favor of
either Node.js or Go... ? Is there anyone who can provide some constructive
negative feedback regarding Scala (apart from the learning curve) over GO?

~~~
zemo
Gopher here. I'll try my best as to why I chose Go over Scala; this isn't
meant to be "why I think Go is better than Scala", it's "how Go kept me
interested from zero to gopher, while Scala failed to attract my attention".

Scala didn't keep me curious for long enough to get good at it. I took a look
at some examples, flipped through a textbook, and just came to the conclusion
that there were way too many features and it appeared to be too clever for me
to care. Things like impressive one-liners don't impress me; they do the
opposite. That it's built on the JVM doesn't particularly appeal to me because
I don't have any existing JVM-dependent projects. Examples like this:
<http://www.scala-lang.org/node/225>

    
    
        /** Turn command line arguments to uppercase */
        object Main {
          def main(args: Array[String]) {
            val res = for (a <- args) yield a.toUpperCase
            println("Arguments: " + res.toString)
          }
        }
    

the toUpperCase method being called without parens is bothersome to me, since
it makes it ambiguous what is and is not a function call. The for loop being
an expression is strange to me; it's a construct that appears to add no value
to the programer, at a significant cost of clarity. It must make me seem very
stupid to argue against looping constructs as simple expressions, but I think
this type of notation is unnecessarily terse. Go doesn't have this type of
thing, because the language is designed more for clarity than for terseness. I
don't think that this is elegant:

    
    
        for (a <- args) yield a.toUpperCase
    

I think it's far too clever. Beyond the method call, another thing that
appears to be hidden here is the creation of the target list to which the
uppercase letters are being stored. How many memory allocations are there in
this statement? What if the body of that loop is conditional and we don't know
how much space we need in advance? Yes, it's nice to look at, and I can see
how it might be exciting to understand that for the first time, but...
everything that it adds seems to be completely unimportant, but the operations
that much be happening have been hidden from view. Great, we've saved a bit of
typing, but in the process, we've lost a lot of understanding about how our
program behaves.

Then there are other simple things. I really enjoy that curly brackets are
mandatory on looping constructs in Go; I noticed that Scala has the feature
that you can leave them off and it only includes the next statement. I find
that feature profoundly annoying and prefer that it does not exist. I really
like the way the tooling enforces formatting. I really like the way that Go is
militant. When I write Go, I feel like I'm at work assembling an information
processing machine; I don't feel like I'm writing poetry. I don't _want_ to
feel like I'm writing poetry. I'm happy to be making information machines,
because that's the honest truth of the craft. The poetry lies in what those
machines do; the art is in the output. To me, writing a boring program whose
code is very clever is like writing a boring poem in beautiful calligraphy and
arguing that the beauty of the calligraphy makes the poem better.

So that's why I went with Go, and not Scala. Of course, there are things I
wish we had; specifically operator overloading and something akin to generics,
the former we almost certainly will never get, while the latter remains an
open question. A part of me misses having properties or Python's decorators,
but... these are features that I've found can easily create maintenance
problems; features that have caused trouble for me in the past.

Go, of course, has its warts (some would argue that the language made entirely
of warts), but while learning the language I always got the feeling that the
things that were annoying were good for me; that the warts were like being
told to eat your vegetables. After a year and a half of programming Go
regularly, I've found that to be largely true. My old code is much easier for
me to go back to than the equivalent in other languages, and I've found my Go
projects to be very easy to maintain, overall.

Go's code is the right level of terseness for me. It's far, far shorter than
equivalent Java code and it's very clear. To me, elegance is clarity. To
others, elegance is terseness. It's all a matter of opinion. I think you'd be
hard-pressed to find someone that chose Go over Scala because of the merits of
what can be built with one tool over the other; I reckon they're quite
comparable in this regard.

~~~
mafribe
For loops being expressions is a source of power and uniformity in languages
like Scala. It really makes your life easier in many situations. It's an
unusual way of looking at loops when you come from a background in imperative
programming, but once you realise that imperative programming is not the only
way to compute, your life as a programmer becomes easier!

Maybe, at some point, if you have spare time, I recommend that you give a
modern language like Scala, Haskell or ML/Ocaml/F# that don't distinguish
statements from expressions a second chance.

~~~
PySlice
I have not written my first Go (or Scala) program yet, but I have written some
F# code and loved the language (and the fact that everything is an expression
too). It does have som complex features, and special syntax appears very
often, but after reading just a bit of documentation, I can easily understand
the core concepts and syntax.

On the other hand, Scala gives me a completely different feeling: when reading
the docs and samples, I often ask myself:

How can I mentally parse this?

It's nice that I can abbreviate some common constructs (when writing), but
_when reading_ code, how can I tell which concepts are being used? How do I
look up these operators when they could come from anywhere (global, first
operand, second operand, implicit conversion, etc.)

How do I know when parentheses, dots, curly braces, are mandatory or optional?
Could the compiler misunderstand me in complex situations? Where does this
construct really end if so many things are optional? At least F# uses
indentation, so I know the compiler will warn me if I wrote something that is
not quite right according to the precedence rules.

There are too many implicit things going on, how do I know which meaning of _
(underscore) is meant here?

~~~
happy_dino
I'd say this is largely a non-problem. If you already know F#, then Scala is a
much simpler, more consistent language. In a way, Scala seems to be a refined,
better designed version of F#.

For instance, F# has support for functional and object-oriented programming,
but most people I spoke to recommend just ignoring the object parts. That's
certainly my impression, too. Compared to Scala, F# didn't manage to combine
FP and OOP into a single, coherent approach. You have more or less ML's type
system with the object stuff bolted on.

Another example would be that F# has tons of features where a single one could
suffice. Consider the Unit of Measurement stuff, the various forms of
(computation) expressions and type providers. Scala can do all of that and a
lot more with "just" macros.

> It's nice that I can abbreviate some common constructs

Not sure what you mean with that.

> How do I look up these operators when they could come from anywhere (global,
> first operand, second operand, implicit conversion, etc.)

Not really. There are no operators, everything is a method invocation. The
method is either defined on the type of the left, or added by an conversion
from that type. That's it.

> How do I know when parentheses, dots, curly braces, are mandatory or
> optional?

Method calls with one argument can leave out dot and parentheses. If a method
has a side effect, you define and call it with parentheses, otherwise you
leave them out.

> There are too many implicit things going on, how do I know which meaning of
> _ (underscore) is meant here?

People love to make up scary examples, but I have never seen any actual misuse
of implicits in real code. The meaning of the underscore doesn't change, it is
always the same: "There exists something, but I don't care to give it a name."

I hope that helps a bit!

~~~
PySlice
> If you already know F#, then Scala is a much simpler Well, F# does seem to
> have a lot of "bolted-on" features, but Scala always gives the impression
> that things "come out of nowhere", e.g. a simple underscore turns the whole
> expression into a lambda! It looks neat, but I will need some practice to
> get used to things like this. But, as I said, this is just a superficial
> analysis, some thing we can only learn after some practicing.

> Not sure what you mean with that. Braces, parenthesis, dots, semicolons, and
> IIRC you can use the arrow => without anything on its left side.

> The method is either defined on the type of the left, or added by an
> conversion from that type. That's it.

Unless it ends with a colon, right?

> Method calls with one argument can leave out dot and parentheses

That's somewhat simpler than I expected. I thought it was something Perl-like
or Ruby-like (where obj.method + 1 is different from obj.method +1). There
should be some way to get a reference to a method without calling it, that I
still haven't learnt.

> If a method has a side effect, you define and call it with parentheses,
> otherwise you leave them out

Not sure I understand this. Is this the preferred coding style or something
enforced by the compiler?

> I hope that helps a bit! Yes, it helped! Thanks!

