Opened 5 years ago

Closed 5 years ago

#9794 closed feature request (duplicate)

Additional assert function: assert :: Bool -> String -> a -> a

Reported by: rodlogic Owned by:
Priority: normal Milestone:
Component: Compiler (Type checker) Version: 7.8.3
Keywords: Cc:
Operating System: Unknown/Multiple Architecture: Unknown/Multiple
Type of failure: None/Unknown Test Case:
Blocked By: Blocking:
Related Tickets: Differential Rev(s):
Wiki Page:

Description

Currently, we have an assert function in GHC.Base:

-- Assertion function.  This simply ignores its boolean argument.
-- The compiler may rewrite it to @('assertError' line)@.

-- | If the first argument evaluates to 'True', then the result is the
-- second argument.  Otherwise an 'AssertionFailed' exception is raised,
-- containing a 'String' with the source file and line number of the
-- call to 'assert'.
--
-- Assertions can normally be turned on or off with a compiler flag
-- (for GHC, assertions are normally on unless optimisation is turned on
-- with @-O@ or the @-fignore-asserts@
-- option is given).  When assertions are turned off, the first
-- argument to 'assert' is ignored, and the second argument is
-- returned as the result.

--      SLPJ: in 5.04 etc 'assert' is in GHC.Prim,
--      but from Template Haskell onwards it's simply
--      defined here in Base.lhs
assert :: Bool -> a -> a
assert _pred r = r

This get's rewritten by the type checker to assertError:

Note [Adding the implicit parameter to 'assert']
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The typechecker transforms (assert e1 e2) to (assertError "Foo.hs:27"
e1 e2).  This isn't really the Right Thing because there's no way to
"undo" if you want to see the original source code in the typechecker
output.  We'll have fix this in due course, when we care more about
being able to reconstruct the exact original program.

I would like to propose an additional one:

assertStr :: Bool -> String -> a -> a
assertStr _pred msg r = r

NOTE: what is a name that is more consistent with the code base?

That would get rewritten as:

assertError ("Foo.hs:27 - " ++ show msg) e1 e2

Why?

This makes assertions a bit more meaningful when reading the error message, and they can replace the existing ASSERT2 macros throughout the code base.

Change History (2)

comment:1 Changed 5 years ago by simonpj

The difficulty here is that these functions are not abstractable. For example, in GHC we'd want a function

assertGHC :: Bool -> SDoc -> a -> a

where the second argument is an SDoc not a string. We could define it in a library module, in terms your assertStr, thue:

assertGHC b doc x = assertStr b (showSDoc doc) x

but now the location reported would be in the library module.

How to make this abstractable? See #9049, esp ExplicitCallStack/ImplicitLocations

I'm reluctant make the present thing a tiny bit better; I'd rather do something more thorough. I'd be happy if someone made progress on #9049.

Simon

comment:2 in reply to:  1 Changed 5 years ago by rodlogic

Resolution: duplicate
Status: newclosed

Replying to simonpj:

The difficulty here is that these functions are not abstractable. For example, in GHC we'd want a function

assertGHC :: Bool -> SDoc -> a -> a

where the second argument is an SDoc not a string. We could define it in a library module, in terms your assertStr, thue:

assertGHC b doc x = assertStr b (showSDoc doc) x

but now the location reported would be in the library module.

How to make this abstractable? See #9049, esp ExplicitCallStack/ImplicitLocations

I'm reluctant make the present thing a tiny bit better; I'd rather do something more thorough. I'd be happy if someone made progress on #9049.

Simon

I now understand the basic problem and what you mean by 'abstractable': we can't just change the existing GHC.Base.assert function to include a message parameter and create a wrapper function to keep it backwards compatible. And introducing a new assertStr would require a second hard-coded wiring into the compiler to make it just like assert.

I am new to GHC, but would be willing to give it a shot if you can give me a few pointers. For now, I will close this ticket as a duplicate of #9049 to keep things centralized and add a reference back here.

Moving to #9049 ...

Note: See TracTickets for help on using tickets.