Question

Let's say I want to fork a thread within a do-notation block, but I don't care about the thread id. If I write

forkIO action

GHC issues warning

Warning: A do-notation statement discarded a result of type ThreadId. Suppress this warning by saying

_ <- forkOS action

This is a good idea as I want to show that the program is discarding some result. However, this way it won't be apparent what's being discarded. I could write

threadId <- forkIO action

but then we're hiding the fact that we won't use threadId anywhere, and GHC correctly warns

Warning: Defined but not used: threadId

It seems that prepending underscore solves both problems:

_threadId <- forkIO action

My questions are: Is using variables starting with underscores legal according to Haskell's language specification? How portable is it? Is it documented somewhere? Is it encouraged for cases like this - to document that a result is being ignored?

Was it helpful?

Solution

Yes. In section 2.4 of the 2010 specification, it says

Underscore, _, is treated as a lowercase letter, and can occur wherever a lowercase letter can.

...so _threadId is a legal identifier according to the language spec which should be utterly portable.

However, _ all by itself is a reserved identifier, used as wild card in patterns.

...so you can't use _ alone outside patterns, thus can't use that value.

Compilers that offer warnings for unused identifiers are encouraged to suppress such warnings for identifiers beginning with underscore. This allows programmers to use _foo for a parameter that they expect to be unused.

So _threadId is an ordinary identifier which you could use elsewhere, but you shouldn't be warned if you throw it away.

(Exactly the same text is in the Haskell 98 report.)


Examples:

main = do
     _two <- return 2
     print _two       -- works

compiles and prints 2 according to the spec and

main = do
    _two <- return 2
    print 3           -- no warnings, but oops, didn't use _two

compiles without warning according to the spec, and

main = do
    _ <- return 2
    print _        -- syntax error: _ used as identifier

is a syntax error according to the spec.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top