Idiomatic way to express the equivalent of an assertion

714 views
Skip to first unread message

ray....@gmail.com

unread,
May 4, 2016, 8:46:30 PM5/4/16
to golang-nuts
I'm well aware of the fact that Go does not have assertions and fully agree with "Why Does Go Not Have Assertions?" I agree that programmers may use assertions as crutches in production code.

So what, then, is a nice way to write expository code that is used to explain the language to a reader? For example, in Lua, if wanted to explain scope to someone, I could give them the executable code:

-- Lua
x = 1
do
  assert(x == 1)    -- global x because local not yet seen
  local x = x + 2   -- uses global x on right hand side
  assert(x == 3)    -- now, FINALLY, we see the local x
end
assert(x == 1)      -- back in the global scope, local gone


and in Python I can explain types to people with executable code like

# Python
assert type(5) == int
assert type(True) == bool
assert type(5.7) == float
assert type(9 + 5j) == complex

and even in Ruby, we don't have asserts, but we can simulate them with `fail unless`:

# Ruby
fail unless 5.send(:abs) == 5
fail unless 5.send('abs') == 5
fail unless 5.abs == 5

In Clojure I have to import something from core, but it's pretty lightweight once I add a use line:

; Clojure
(use 'clojure.test)
(is (= (type 3) Long))
(is (= (type 5.0) Double))
(is (= (type 4/7) clojure.lang.Ratio))
(is (= (type 5N) clojure.lang.BigInt))

Each of these things allow one to illustrate features of the language without using comments (which there's no reason to believe) and print statements (which require looking at), and that's super nice, IMHO.

What can I write in Go? Is it correct to use panics? Or log.Fatal? I would really like to know the idiomatic equivalent of the above in Go. Here is what I have tried:

// Go
package main

import "math"

func twice(f func(float64)float64, x float64) float64 {
return f(f(x))
}

func square(x float64) float64 {
return x * x
}

func main() {
addTwo := func(x float64)float64 {return x + 2}
if twice(square, 4) != 256 {panic("")}
if twice(addTwo, 100) != 104 {panic("")}
if twice(math.Log2, 256) != 3 {panic("")}
}

I'm not sure about if....panic.

What should I do? What is the most idiomatic way to do this in Go?

Yes I do know how to use the testing package. Is that the best way?


Caleb Spare

unread,
May 4, 2016, 8:53:57 PM5/4/16
to ray....@gmail.com, golang-nuts
You could always write an assert function: https://play.golang.org/p/yvOOHrsMt1

Depending on the context, Go's testable examples might be useful: https://blog.golang.org/examples

-Caleb​

--
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 golang-nuts...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

ray....@gmail.com

unread,
May 4, 2016, 9:02:24 PM5/4/16
to golang-nuts, ray....@gmail.com
Wow, I totally missed the GoDoc examples. And yes, thanks for the example assert function---I had thought about writing one but wanted to make sure panicking was the right thing to do in this case, which I think it is.

Jesse McNelis

unread,
May 4, 2016, 10:36:42 PM5/4/16
to ray....@gmail.com, golang-nuts
On Thu, May 5, 2016 at 10:04 AM, <ray....@gmail.com> wrote:
> I'm well aware of the fact that Go does not have assertions and fully agree
> with "Why Does Go Not Have Assertions?" I agree that programmers may use
> assertions as crutches in production code.
>

The FAQ doesn't really mention it, but the main reason Go doesn't have
assertions is that a common feature for languages that include
assertions is the ability to ignore/remove them when building for
production.

Python has this, pass in the -O flag and your assertions won't execute.
C does a similar thing.

This gets tricky when your assertions have side effects.
Suddenly, assert(sendTheEmails()) doesn't send the emails in production.

ray....@gmail.com

unread,
May 5, 2016, 4:41:56 AM5/5/16
to golang-nuts, ray....@gmail.com, jes...@jessta.id.au
This makes good sense. I really like the testable examples feature, and that's what I've gone with. 

Konstantin Khomoutov

unread,
May 5, 2016, 8:34:37 AM5/5/16
to ray....@gmail.com, golang-nuts
On Wed, 4 May 2016 17:04:06 -0700 (PDT)
ray....@gmail.com wrote:

> I'm well aware of the fact that Go does not have assertions and fully
> agree with "Why Does Go Not Have Assertions?"
> <https://golang.org/doc/faq#assertions> I agree that programmers may
> use assertions as crutches in production code.
>
> So what, then, is a nice way to write expository code that is used to
> explain the language to a reader? For example, in Lua, if wanted to
> explain scope to someone, I could give them the executable code:
[...]

You could as well exploit the testing facility built into the standard
Go toolchain with the support of the standard package "testing".

Basically, it you'd like to test something, write a test ;-)

See https://golang.org/cmd/go/#hdr-Test_packages

Konstantin Khomoutov

unread,
May 5, 2016, 8:42:41 AM5/5/16
to ray....@gmail.com, golang-nuts
On Thu, 5 May 2016 15:34:12 +0300
Konstantin Khomoutov <flat...@users.sourceforge.net> wrote:

[...]
> > So what, then, is a nice way to write expository code that is used
> > to explain the language to a reader? For example, in Lua, if wanted
> > to explain scope to someone, I could give them the executable code:
> [...]
>
> You could as well exploit the testing facility built into the standard
> Go toolchain with the support of the standard package "testing".
>
> Basically, it you'd like to test something, write a test ;-)
>
> See https://golang.org/cmd/go/#hdr-Test_packages

See also: https://github.com/golang/go/wiki/TableDrivenTests
Reply all
Reply to author
Forward
0 new messages