Happy April Fool's Day

I’ll be streaming some live coding again, on this April Fool’s day. No joke. I hope you’ll join me. It’s April Fool’s day. And I also recently learned of #AprilCools – the idea of doing something off-topic, but serious, rather than cringey on April first. So this year, I, eh… extended my “Learn Go” book review series to review a book about learning Go…. the game, not the language. Have a watch.


Terminating blocks

Terminating statements … A block in which the statement list ends in a terminating statement. What exactly does this mean? It means that if you have an (explicit) code block that ends in a terminating statement, the block itself is considered a terminating statement. Confused? How about an example: func foo() { if somethingInterestingHappened() { fmt.Println("Wow, that was interesting!") return } fmt.Println("That was boring.") } In this example, return is a terminating statement, as we saw [two days ago](/ archive/2024-03-27-terminating-statements/).


Don't panic!

Later today, at 15:00 UTC, I’ll be joining Denis Čahuk and Adrian Stanek on their regular Livestream, Our Tech Journey, to talk about TDD, Go, and do some live coding. Join us! The second in our list of terminating statements is… panic! Terminating statements … A call to the built-in function panic. Don’t panic. Don’t panic is such ubiquitous Go advice that it’s one of the famous Go proverbs. So why do we have a built-in panic function if we’re not supposed to use it?


Terminating statements

Terminating statements A terminating statement interrupts the regular flow of control in a block. The following statements are terminating: A “return” or “goto” statement. The return statement should be familiar to virtually everyone. And the fact that it interrupts the regular flow of control should be no surprise: func foo() { fmt.Println("Hello there") return fmt.Println("You'll never see me!") } In this above example, the second fmt.Println is never called for fairly obvious reasons: The preceeding return statement interrupts the flow, and returns control control flow back to whatever code called foo() in the first place.


Statements

At long last, we have completed the section of the spec on expressions… and now we move on to: Statements Statements control execution. Statement = Declaration | LabeledStmt | SimpleStmt | GoStmt | ReturnStmt | BreakStmt | ContinueStmt | GotoStmt | FallthroughStmt | Block | IfStmt | SwitchStmt | SelectStmt | ForStmt | DeferStmt . SimpleStmt = EmptyStmt | ExpressionStmt | SendStmt | IncDecStmt | Assignment | ShortVarDecl . In my experience, the terms “expression” and “statement” and “declaration” are often confused and conflated.


Order of evaluation and floating point numbers

Today I’ll be live streaming again! This time, picking up where we left off last week, and adding another feature to my new Go code rewriter and simplifier. Join me! Order of Evaluation … Floating-point operations within a single expression are evaluated according to the associativity of the operators. Explicit parentheses affect the evaluation by overriding the default associativity. In the expression x + (y + z) the addition y + z is performed before adding x.


Initialization dependencies

Here’s a thing you’ve likely never thought about: What if you have a compound assignment statement, where one of the variables depends on the other in the same statement. That’s what we’re looking at today. Order of Evaluation … At package level, initialization dependencies override the left-to-right rule for individual initialization expressions, but not for operands within each expression: var a, b, c = f() + v(), g(), sqr(u()) + v() func f() int { return c } func g() int { return a } func sqr(x int) int { return x*x } // functions u and v are independent of all other variables and functions So first notice that calling f() returns c, and calling g() returns a.

Subscribe to Boldly Go: Daily

Every day I'll send you advice to improve your understanding of Go. Don't miss out! I will respect your inbox, and honor my privacy policy.

Unsure? Browse the archive.


Unordered evaluation

Yesterday’s spec quote included a sentence we breezed over. Today we’re going to dig in a bit more: Order of Evaluation … the order of those events compared to the evaluation and indexing of x and the evaluation of y and z is not specified, except as required lexically. What exactly does that mean? Well, the example that follows in the spec makes it a bit more clear, but in a nutshell, the order of evaluation for index expressions is not defined.


Order of Evaluation

Let’s talk about… the order of evaluation! You might think you have a strong grasp on this concept, but many languages have their own nuanced take on evaluation order in some cases. And then JavaScript has “hoisting”, which kinda spits in the face of order of evaluation. Before we dive in, here’s a short pop-quiz. What does this short program output when executed? package main import "fmt" func init() { fmt.


Constant expressions, part III

Did you miss yesterday’s Ask-me-anything session? You probably did. I had about 10-15 people there. But even with a small group, we had a ton of great questions! The Q&A session lasted about an hour, and covered topics such as book recommendations for going deeper into Go, what project to build to learn concurrency, and much more. Catch the replay on YouTube. Let’s continue our discussion of constant expressions, with some more miscellaneous rules:


Constant expressions, continued

Today I’ll be answering your questions on my weekly live stream. Have a question about Go? About CI/CD? About my favorite pizza toppings? Join me! Or submit your question early and catch the replay, if you can’t join live. Today we continue the section on Constant expressions, with a grab bag of miscellaneous rules. Constant expressions … Applying the built-in function complex to untyped integer, rune, or floating-point constants yields an untyped complex constant.