Michael Snoyman | 25 Feb 07:06 2013

RFC: rewrite-with-location proposal

Quite a while back, Simon Hengel and I put together a proposal[1] for a new feature in GHC. The basic idea is pretty simple: provide a new pragma that could be used like so:

error :: String -> a
errorLoc :: IO Location -> String -> a
{-# REWRITE_WITH_LOCATION error errorLoc #-}

Then all usages of `error` would be converted into calls to `errorLoc` by the compiler, passing in the location information of where the call originated from. Our three intended use cases are:

* Locations for failing test cases in a test framework
* Locations for log messages
* assert/error/undefined

Note that the current behavior of the assert function[2] already includes this kind of approach, but it is a special case hard-coded into the compiler. This proposal essentially generalizes that behavior and makes it available for all functions, whether included with GHC or user-defined.

The proposal spells out some details of this approach, and contrasts with other methods being used today for the same purpose, such as TH and CPP.
_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe <at> haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe
Joachim Breitner | 25 Feb 09:57 2013
Picon

Re: RFC: rewrite-with-location proposal

Hi,

Am Montag, den 25.02.2013, 08:06 +0200 schrieb Michael Snoyman:
> Quite a while back, Simon Hengel and I put together a proposal[1] for
> a new feature in GHC. The basic idea is pretty simple: provide a new
> pragma that could be used like so:
> 
> error :: String -> a
> errorLoc :: IO Location -> String -> a
> {-# REWRITE_WITH_LOCATION error errorLoc #-}

in light of attempts to split base into a pure part (without IO) and
another part, I wonder if the IO wrapping is really necessary.

Can you elaborate the reason why a simple "Location ->" is not enough?

Thanks,
Joachim

--

-- 
Joachim "nomeata" Breitner
Debian Developer
  nomeata <at> debian.org | ICQ# 74513189 | GPG-Keyid: 4743206C
  JID: nomeata <at> joachim-breitner.de | http://people.debian.org/~nomeata

_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe <at> haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe
Simon Hengel | 25 Feb 10:13 2013
Picon

Re: RFC: rewrite-with-location proposal

On Mon, Feb 25, 2013 at 09:57:04AM +0100, Joachim Breitner wrote:
> Hi,
> 
> Am Montag, den 25.02.2013, 08:06 +0200 schrieb Michael Snoyman:
> > Quite a while back, Simon Hengel and I put together a proposal[1] for
> > a new feature in GHC. The basic idea is pretty simple: provide a new
> > pragma that could be used like so:
> > 
> > error :: String -> a
> > errorLoc :: IO Location -> String -> a
> > {-# REWRITE_WITH_LOCATION error errorLoc #-}
> 
> in light of attempts to split base into a pure part (without IO) and
> another part, I wonder if the IO wrapping is really necessary.
> 
> Can you elaborate the reason why a simple "Location ->" is not enough?

The IO helps with reasoning.  Without it you could write code that does
something different depending on the call site.  Here is an example:

    someBogusThingy :: Int
    someBogusThingy = ..

    someBogusThingyLoc :: Location -> Int
    someBogusThingyLoc loc
      | (even . getLine) loc = 23
      | otherwise            = someBogusThingyLoc

    {-# REWRITE_WITH_LOCATION someBogusThingy someBogusThingyLoc #-}

Now someBogusThingy behaves different depending on whether the call site
is on an even or uneven line number.  Admittedly, the example is
contrived, but I hope it illustrates the issue.

I do not insist on keeping it.  If we, as a community, decide, that we
do not need the IO here.  Then I'm fine with dropping it.

Cheers,
Simon
Michael Snoyman | 25 Feb 10:16 2013

Re: RFC: rewrite-with-location proposal




On Mon, Feb 25, 2013 at 11:13 AM, Simon Hengel <sol <at> typeful.net> wrote:
On Mon, Feb 25, 2013 at 09:57:04AM +0100, Joachim Breitner wrote:
> Hi,
>
> Am Montag, den 25.02.2013, 08:06 +0200 schrieb Michael Snoyman:
> > Quite a while back, Simon Hengel and I put together a proposal[1] for
> > a new feature in GHC. The basic idea is pretty simple: provide a new
> > pragma that could be used like so:
> >
> > error :: String -> a
> > errorLoc :: IO Location -> String -> a
> > {-# REWRITE_WITH_LOCATION error errorLoc #-}
>
> in light of attempts to split base into a pure part (without IO) and
> another part, I wonder if the IO wrapping is really necessary.
>
> Can you elaborate the reason why a simple "Location ->" is not enough?

The IO helps with reasoning.  Without it you could write code that does
something different depending on the call site.  Here is an example:


    someBogusThingy :: Int
    someBogusThingy = ..

    someBogusThingyLoc :: Location -> Int
    someBogusThingyLoc loc
      | (even . getLine) loc = 23
      | otherwise            = someBogusThingyLoc

    {-# REWRITE_WITH_LOCATION someBogusThingy someBogusThingyLoc #-}

Now someBogusThingy behaves different depending on whether the call site
is on an even or uneven line number.  Admittedly, the example is
contrived, but I hope it illustrates the issue.

I do not insist on keeping it.  If we, as a community, decide, that we
do not need the IO here.  Then I'm fine with dropping it.


And FWIW, my vote *does* go towards dropping it. I put this proposal in the same category as rewrite rules in general: it's certainly possible for a bad implementation to wreak havoc, but it's the responsibility of the person using the rewrite rules to ensure that doesn't happen.

Michael 
_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe <at> haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe
Joachim Breitner | 25 Feb 10:17 2013
Picon

Re: RFC: rewrite-with-location proposal

Hi,

Am Montag, den 25.02.2013, 10:13 +0100 schrieb Simon Hengel:
> On Mon, Feb 25, 2013 at 09:57:04AM +0100, Joachim Breitner wrote:
> > Hi,
> > 
> > Am Montag, den 25.02.2013, 08:06 +0200 schrieb Michael Snoyman:
> > > Quite a while back, Simon Hengel and I put together a proposal[1] for
> > > a new feature in GHC. The basic idea is pretty simple: provide a new
> > > pragma that could be used like so:
> > > 
> > > error :: String -> a
> > > errorLoc :: IO Location -> String -> a
> > > {-# REWRITE_WITH_LOCATION error errorLoc #-}
> > 
> > in light of attempts to split base into a pure part (without IO) and
> > another part, I wonder if the IO wrapping is really necessary.
> > 
> > Can you elaborate the reason why a simple "Location ->" is not enough?
> 
> The IO helps with reasoning.  Without it you could write code that does
> something different depending on the call site.  Here is an example:
> 
> 
>     someBogusThingy :: Int
>     someBogusThingy = ..
> 
>     someBogusThingyLoc :: Location -> Int
>     someBogusThingyLoc loc
>       | (even . getLine) loc = 23
>       | otherwise            = someBogusThingyLoc
> 
>     {-# REWRITE_WITH_LOCATION someBogusThingy someBogusThingyLoc #-}
> 
> Now someBogusThingy behaves different depending on whether the call site
> is on an even or uneven line number.  Admittedly, the example is
> contrived, but I hope it illustrates the issue.

ok, I mentally applied REWRITE_WITH_LOCATION before wondering about
reasoning about the code. But you are right that it would be nice if the
rewrite rule would be valid as well.

I’m not firmly commited either way.

Greetings,
Joachim

--

-- 
Joachim "nomeata" Breitner
Debian Developer
  nomeata <at> debian.org | ICQ# 74513189 | GPG-Keyid: 4743206C
  JID: nomeata <at> joachim-breitner.de | http://people.debian.org/~nomeata

_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe <at> haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe
Alexander Kjeldaas | 25 Feb 10:21 2013
Picon

Re: RFC: rewrite-with-location proposal


Immediately, the alternative of introducing bound variables in the environment that is available to rewrite rules comes to mind as a more general way of doing this.

So this example from the GHC docs:
{-# RULES
  "map/map"    forall f g xs.  map f (map g xs) = map (f.g) xs
  "map/append" forall f xs ys. map f (xs ++ ys) = map f xs ++ map f ys
 #-}

For some source:
  map f (map g xs)

it is translated into:
   
   let location = "somefile.hs:234"
   in map (f.g) xs

So for error:

{-# RULES
  "error/location"    error s = errorLoc location s
 #-}

is translated into:
   let location = "somefile.hs:345"
   in errorLoc location s


Alexander

_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe <at> haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe
Twan van Laarhoven | 25 Feb 10:40 2013
Picon

Re: RFC: rewrite-with-location proposal

On 25/02/13 07:06, Michael Snoyman wrote:
> Quite a while back, Simon Hengel and I put together a proposal[1] for a new
> feature in GHC. The basic idea is pretty simple: provide a new pragma that could
> be used like so:
>
> error :: String -> a
> errorLoc :: IO Location -> String -> a
> {-# REWRITE_WITH_LOCATION error errorLoc #-}
>
> Then all usages of `error` would be converted into calls to `errorLoc` by the
> compiler, passing in the location information of where the call originated from.
> Our three intended use cases are:

I think there is no need to have a separate REWRITE_WITH_LOCATION rule. What if 
the compiler instead rewrites 'currentLocation' to the current location? Then 
you'd just define the rule:

{-# REWRITE "errorLoc" error = errorLoc currentLocation #-}

I'm also pretty sure that something like this has been proposed in the past.

Twan
Simon Hengel | 25 Feb 12:46 2013
Picon

Re: RFC: rewrite-with-location proposal

On Mon, Feb 25, 2013 at 10:40:29AM +0100, Twan van Laarhoven wrote:
> I think there is no need to have a separate REWRITE_WITH_LOCATION
> rule. What if the compiler instead rewrites 'currentLocation' to the
> current location? Then you'd just define the rule:
>
> {-# REWRITE "errorLoc" error = errorLoc currentLocation #-}

REWRITE rules are only enabled with -O.  Source locations are also
useful during development (when you care more about compilation time
than efficient code and hence use -O0).  So I'm not sure whether it's a
good idea to lump those two things together.

Cheers,
Simon
Alexander Kjeldaas | 25 Feb 13:15 2013
Picon

Re: RFC: rewrite-with-location proposal

On Mon, Feb 25, 2013 at 12:46 PM, Simon Hengel <sol <at> typeful.net> wrote:
On Mon, Feb 25, 2013 at 10:40:29AM +0100, Twan van Laarhoven wrote:
> I think there is no need to have a separate REWRITE_WITH_LOCATION
> rule. What if the compiler instead rewrites 'currentLocation' to the
> current location? Then you'd just define the rule:
>
> {-# REWRITE "errorLoc" error = errorLoc currentLocation #-}

REWRITE rules are only enabled with -O.  Source locations are also
useful during development (when you care more about compilation time
than efficient code and hence use -O0).  So I'm not sure whether it's a
good idea to lump those two things together.


I could imagine that source locations being useful when debugging rewrite rules for example.

I think your argument makes sense, but why not fix that specifically?

{-# REWRITE ALWAYS "errorLoc" error = errorLoc currentLocation #-}

Alexander

_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe <at> haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe
Michael Snoyman | 25 Feb 13:41 2013

Re: RFC: rewrite-with-location proposal




On Mon, Feb 25, 2013 at 2:15 PM, Alexander Kjeldaas <alexander.kjeldaas <at> gmail.com> wrote:
On Mon, Feb 25, 2013 at 12:46 PM, Simon Hengel <sol <at> typeful.net> wrote:
On Mon, Feb 25, 2013 at 10:40:29AM +0100, Twan van Laarhoven wrote:
> I think there is no need to have a separate REWRITE_WITH_LOCATION
> rule. What if the compiler instead rewrites 'currentLocation' to the
> current location? Then you'd just define the rule:
>
> {-# REWRITE "errorLoc" error = errorLoc currentLocation #-}

REWRITE rules are only enabled with -O.  Source locations are also
useful during development (when you care more about compilation time
than efficient code and hence use -O0).  So I'm not sure whether it's a
good idea to lump those two things together.


I could imagine that source locations being useful when debugging rewrite rules for example.

I think your argument makes sense, but why not fix that specifically?

{-# REWRITE ALWAYS "errorLoc" error = errorLoc currentLocation #-}



At that point, we've now made two changes to REWRITE rules:

1. They can takes a new ALWAYS parameters.
2. There's a new, special identifier currentLocation available.

What would be the advantage is of that approach versus introducing a single new REWRITE_WITH_LOCATION pragma?

Michael
_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe <at> haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe
Twan van Laarhoven | 25 Feb 14:02 2013
Picon

Re: RFC: rewrite-with-location proposal

On 25/02/13 13:41, Michael Snoyman wrote:
>
> At that point, we've now made two changes to REWRITE rules:
>
> 1. They can takes a new ALWAYS parameters.
> 2. There's a new, special identifier currentLocation available.
>
> What would be the advantage is of that approach versus introducing a single new
> REWRITE_WITH_LOCATION pragma?

You are probably right. Ghc already has some logic in place for doing this with 
'assert':

-- Return an expression for (assertError "Foo.hs:27")
mkAssertErrorExpr = ..

finishHsVar name
  = do { ignore_asserts <- goptM Opt_IgnoreAsserts
       ; if ignore_asserts || not (name `hasKey` assertIdKey)
	then return (HsVar name, unitFV name)
	else do { e <- mkAssertErrorExpr
		; return (e, unitFV name) } }

So the check is name `hasKey` assertIdKey. I.e. it is a literal check whether 
the name is assert. Maybe that could be extended to check whether the name is 
declared as assert-like.

Of course the real solution is to have proper stack traces.

Twan
Petr Pudlák | 25 Feb 14:02 2013
Picon

Re: RFC: rewrite-with-location proposal




2013/2/25 Michael Snoyman <michael <at> snoyman.com>

At that point, we've now made two changes to REWRITE rules:

1. They can takes a new ALWAYS parameters.
2. There's a new, special identifier currentLocation available.

What would be the advantage is of that approach versus introducing a single new REWRITE_WITH_LOCATION pragma?

Just a remark: 'currentLocation' is not a function (it's a special keyword) but behaves like one - it returns some kind of value. But it's not referentially transparent - it returns a different value depending on where it's used. This is something that I really don't expect from Haskell.  So having it return `IO Location` seems therefore much better option. And if someone really wants to get the location as a pure value, (s)he can simply wrap it with `unsafePerformIO`, which signals code readers to be careful with that part.

  Best regards,
  Petr
_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe <at> haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe
Alexander Kjeldaas | 25 Feb 15:15 2013
Picon

Re: RFC: rewrite-with-location proposal


My initial thought as I read the proposal was to represent currentLocation as a lexical bound variable, thus "error" is rewritten to the expression:

let currentLocation = "someplace.hs:123"
in errorLoc currentLocation

there is no referntial transparency issue in that because there is no global function "currentLocation", it's a lexically bound variable in the rewrite environment.

Btw, I'm happy that people want to implement whatever they feel like.  Feel free to do whatever makes sense.  My comments are not meant to discourage this :-)

Alexander



On Mon, Feb 25, 2013 at 2:02 PM, Petr Pudlák <petr.mvd <at> gmail.com> wrote:



2013/2/25 Michael Snoyman <michael <at> snoyman.com>

At that point, we've now made two changes to REWRITE rules:

1. They can takes a new ALWAYS parameters.
2. There's a new, special identifier currentLocation available.

What would be the advantage is of that approach versus introducing a single new REWRITE_WITH_LOCATION pragma?

Just a remark: 'currentLocation' is not a function (it's a special keyword) but behaves like one - it returns some kind of value. But it's not referentially transparent - it returns a different value depending on where it's used. This is something that I really don't expect from Haskell.  So having it return `IO Location` seems therefore much better option. And if someone really wants to get the location as a pure value, (s)he can simply wrap it with `unsafePerformIO`, which signals code readers to be careful with that part.

  Best regards,
  Petr

_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe <at> haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe
Roman Cheplyaka | 25 Feb 16:59 2013

Re: RFC: rewrite-with-location proposal

* Petr Pudlák <petr.mvd <at> gmail.com> [2013-02-25 14:02:28+0100]
> 2013/2/25 Michael Snoyman <michael <at> snoyman.com>
> 
> >
> > At that point, we've now made two changes to REWRITE rules:
> >
> > 1. They can takes a new ALWAYS parameters.
> > 2. There's a new, special identifier currentLocation available.
> >
> > What would be the advantage is of that approach versus introducing a
> > single new REWRITE_WITH_LOCATION pragma?
> >
> 
> Just a remark: 'currentLocation' is not a function (it's a special keyword)
> but behaves like one - it returns some kind of value. But it's not
> referentially transparent - it returns a different value depending on where
> it's used. This is something that I really don't expect from Haskell.  So
> having it return `IO Location` seems therefore much better option. And if
> someone really wants to get the location as a pure value, (s)he can simply
> wrap it with `unsafePerformIO`, which signals code readers to be careful
> with that part.

Wrapping it in IO doesn't make it any more referentially transparent, if
you think about it.

Roman
Daniel Trstenjak | 26 Feb 09:52 2013
Picon

Re: RFC: rewrite-with-location proposal


Hi Michael,

On Mon, Feb 25, 2013 at 02:41:19PM +0200, Michael Snoyman wrote:
> At that point, we've now made two changes to REWRITE rules:
> 
> 1. They can takes a new ALWAYS parameters.
> 2. There's a new, special identifier currentLocation available.
> 
> What would be the advantage is of that approach versus introducing a single
> new REWRITE_WITH_LOCATION pragma?

The name REWRITE_WITH_LOCATION could indicate that it's just a
REWRITE with an additional location, but not that it's used by
the compiler in a different way.

Perhaps using just another word instead of REWRITE could indicate
the difference of application.

Greetings,
Daniel
Simon Peyton-Jones | 25 Feb 15:42 2013
Picon

Re: RFC: rewrite-with-location proposal

I’m afraid the rewrite-rule idea won’t work.  RULES are applied during optimisation, when tons of inlining has happened and the program has been shaken around a lot. No reliable source location information is available there.

 

See http://hackage.haskell.org/trac/ghc/wiki/ExplicitCallStack; and please edit it.

 

One idea I had, which that page does not yet describe, is to have an implicit parameter,
something like ?loc::Location, with

          errLoc :: ?loc:Location => String -> a

          errLoc s = error (“At “ ++ ?loc ++ “\n” ++ s)

 

This behave exactly like an ordinary implicit parameter, EXCEPT that if there is no binding for ?loc::Location, then the current location is used.  Thus

 

myErr :: ?loc:Location => Int -> a

myErr n = errLoc (show n)

 

foo :: Int -> int

foo n | n<0 = myErr n

        | otherwise = ...whatever...

 

When typechecking ‘foo’ we need ?loc:Location, and so the magic is that we use the location of the call of myErr in foo.

 

Simon

 

 

 

From: haskell-cafe-bounces <at> haskell.org [mailto:haskell-cafe-bounces <at> haskell.org] On Behalf Of Alexander Kjeldaas
Sent: 25 February 2013 12:16
To: Simon Hengel
Cc: Haskell Cafe
Subject: Re: [Haskell-cafe] RFC: rewrite-with-location proposal

 

On Mon, Feb 25, 2013 at 12:46 PM, Simon Hengel <sol <at> typeful.net> wrote:

On Mon, Feb 25, 2013 at 10:40:29AM +0100, Twan van Laarhoven wrote:
> I think there is no need to have a separate REWRITE_WITH_LOCATION
> rule. What if the compiler instead rewrites 'currentLocation' to the
> current location? Then you'd just define the rule:
>
> {-# REWRITE "errorLoc" error = errorLoc currentLocation #-}

REWRITE rules are only enabled with -O.  Source locations are also
useful during development (when you care more about compilation time
than efficient code and hence use -O0).  So I'm not sure whether it's a
good idea to lump those two things together.

 

I could imagine that source locations being useful when debugging rewrite rules for example.

 

I think your argument makes sense, but why not fix that specifically?

 

{-# REWRITE ALWAYS "errorLoc" error = errorLoc currentLocation #-}

 

Alexander

 

_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe <at> haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe
Kim-Ee Yeoh | 25 Feb 18:30 2013

Re: RFC: rewrite-with-location proposal

On Mon, Feb 25, 2013 at 9:42 PM, Simon Peyton-Jones <simonpj <at> microsoft.com> wrote:

One idea I had, which that page does not yet describe, is to have an implicit parameter,
something like ?loc::Location


+1

Implicit params has a bad rap in some circles because of counterintuitive behavior when manually binding the parameter (the syntax is partly to blame).

Since ?loc is never bound by hand, there should be no problems.

-- Kim-Ee
_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe <at> haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe
Michael Snoyman | 25 Feb 19:19 2013

Re: RFC: rewrite-with-location proposal




On Mon, Feb 25, 2013 at 4:42 PM, Simon Peyton-Jones <simonpj <at> microsoft.com> wrote:

I’m afraid the rewrite-rule idea won’t work.  RULES are applied during optimisation, when tons of inlining has happened and the program has been shaken around a lot. No reliable source location information is available there.

 


Do you mean that the proposal itself won't work, or specifically implementing this features in terms of existing rewrite rules won't work?
 

One thing I'd disagree with on that page is point (3). While it's certainly nice to have a full stack trace, implementing just shallow call information is incredibly useful. For logging and test framework usages, it in fact completely covers the use case. And even for debugging, I think it would be a massive step in the right direction.

I'll admit to ignorance on the internals of GHC, but it seems like doing the shallow source location approach would be far simpler than a full trace. I'd hate to lose a very valuable feature because we can't implement the perfect feature.
 

One idea I had, which that page does not yet describe, is to have an implicit parameter,
something like ?loc::Location, with

          errLoc :: ?loc:Location => String -> a

          errLoc s = error (“At “ ++ ?loc ++ “\n” ++ s)

 

This behave exactly like an ordinary implicit parameter, EXCEPT that if there is no binding for ?loc::Location, then the current location is used.  Thus

 

myErr :: ?loc:Location => Int -> a

myErr n = errLoc (show n)

 

foo :: Int -> int

foo n | n<0 = myErr n

        | otherwise = ...whatever...

 

When typechecking ‘foo’ we need ?loc:Location, and so the magic is that we use the location of the call of myErr in foo.

 

Simon

 

 

 

From: haskell-cafe-bounces <at> haskell.org [mailto:haskell-cafe-bounces <at> haskell.org] On Behalf Of Alexander Kjeldaas
Sent: 25 February 2013 12:16
To: Simon Hengel
Cc: Haskell Cafe
Subject: Re: [Haskell-cafe] RFC: rewrite-with-location proposal

 

On Mon, Feb 25, 2013 at 12:46 PM, Simon Hengel <sol <at> typeful.net> wrote:

On Mon, Feb 25, 2013 at 10:40:29AM +0100, Twan van Laarhoven wrote:
> I think there is no need to have a separate REWRITE_WITH_LOCATION
> rule. What if the compiler instead rewrites 'currentLocation' to the
> current location? Then you'd just define the rule:
>
> {-# REWRITE "errorLoc" error = errorLoc currentLocation #-}

REWRITE rules are only enabled with -O.  Source locations are also
useful during development (when you care more about compilation time
than efficient code and hence use -O0).  So I'm not sure whether it's a
good idea to lump those two things together.

 

I could imagine that source locations being useful when debugging rewrite rules for example.

 

I think your argument makes sense, but why not fix that specifically?

 

{-# REWRITE ALWAYS "errorLoc" error = errorLoc currentLocation #-}

 

Alexander

 


_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe <at> haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe <at> haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe
Simon Peyton-Jones | 26 Feb 11:06 2013
Picon

Re: RFC: rewrite-with-location proposal

Do you mean that the proposal itself won't work, or specifically implementing this features in terms of existing rewrite rules won't work?

 

I meant the latter.

 

I'll admit to ignorance on the internals of GHC, but it seems like doing the shallow source location approach would be far simpler than a full trace. I'd hate to lose a very valuable feature because we can't implement the perfect feature.

 

I agree with that sentiment. But in fact I suspect that getting a stack is little or no harder than the shallow thing.

 

My “implicit parameter” suggestion was trying to re-use an existing feature, with a small twist, to do what you want, rather than to implement something brand new.

Simon

 

From: michael.snoyman <at> gmail.com [mailto:michael.snoyman <at> gmail.com] On Behalf Of Michael Snoyman
Sent: 25 February 2013 18:19
To: Simon Peyton-Jones
Cc: Alexander Kjeldaas; Simon Hengel; Haskell Cafe
Subject: Re: [Haskell-cafe] RFC: rewrite-with-location proposal

 

 

 

On Mon, Feb 25, 2013 at 4:42 PM, Simon Peyton-Jones <simonpj <at> microsoft.com> wrote:

I’m afraid the rewrite-rule idea won’t work.  RULES are applied during optimisation, when tons of inlining has happened and the program has been shaken around a lot. No reliable source location information is available there.

 

 

Do you mean that the proposal itself won't work, or specifically implementing this features in terms of existing rewrite rules won't work?

 

 

One thing I'd disagree with on that page is point (3). While it's certainly nice to have a full stack trace, implementing just shallow call information is incredibly useful. For logging and test framework usages, it in fact completely covers the use case. And even for debugging, I think it would be a massive step in the right direction.

 

I'll admit to ignorance on the internals of GHC, but it seems like doing the shallow source location approach would be far simpler than a full trace. I'd hate to lose a very valuable feature because we can't implement the perfect feature.

 

One idea I had, which that page does not yet describe, is to have an implicit parameter,
something like ?loc::Location, with

          errLoc :: ?loc:Location => String -> a

          errLoc s = error (“At “ ++ ?loc ++ “\n” ++ s)

 

This behave exactly like an ordinary implicit parameter, EXCEPT that if there is no binding for ?loc::Location, then the current location is used.  Thus

 

myErr :: ?loc:Location => Int -> a

myErr n = errLoc (show n)

 

foo :: Int -> int

foo n | n<0 = myErr n

        | otherwise = ...whatever...

 

When typechecking ‘foo’ we need ?loc:Location, and so the magic is that we use the location of the call of myErr in foo.

 

Simon

 

 

 

From: haskell-cafe-bounces <at> haskell.org [mailto:haskell-cafe-bounces <at> haskell.org] On Behalf Of Alexander Kjeldaas
Sent: 25 February 2013 12:16
To: Simon Hengel
Cc: Haskell Cafe
Subject: Re: [Haskell-cafe] RFC: rewrite-with-location proposal

 

On Mon, Feb 25, 2013 at 12:46 PM, Simon Hengel <sol <at> typeful.net> wrote:

On Mon, Feb 25, 2013 at 10:40:29AM +0100, Twan van Laarhoven wrote:
> I think there is no need to have a separate REWRITE_WITH_LOCATION
> rule. What if the compiler instead rewrites 'currentLocation' to the
> current location? Then you'd just define the rule:
>
> {-# REWRITE "errorLoc" error = errorLoc currentLocation #-}

REWRITE rules are only enabled with -O.  Source locations are also
useful during development (when you care more about compilation time
than efficient code and hence use -O0).  So I'm not sure whether it's a
good idea to lump those two things together.

 

I could imagine that source locations being useful when debugging rewrite rules for example.

 

I think your argument makes sense, but why not fix that specifically?

 

{-# REWRITE ALWAYS "errorLoc" error = errorLoc currentLocation #-}

 

Alexander

 


_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe <at> haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe

 

_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe <at> haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe
Michael Snoyman | 26 Feb 13:24 2013

Re: RFC: rewrite-with-location proposal




On Tue, Feb 26, 2013 at 12:06 PM, Simon Peyton-Jones <simonpj <at> microsoft.com> wrote:

Do you mean that the proposal itself won't work, or specifically implementing this features in terms of existing rewrite rules won't work?

 

I meant the latter.

 

I'll admit to ignorance on the internals of GHC, but it seems like doing the shallow source location approach would be far simpler than a full trace. I'd hate to lose a very valuable feature because we can't implement the perfect feature.

 

I agree with that sentiment. But in fact I suspect that getting a stack is little or no harder than the shallow thing.

 

My “implicit parameter” suggestion was trying to re-use an existing feature, with a small twist, to do what you want, rather than to implement something brand new.


I personally have very little opinion about how this feature is implemented. But would this approach implement the shallow trace, or the full stack trace?

Michael
 

Simon

 

From: michael.snoyman <at> gmail.com [mailto:michael.snoyman <at> gmail.com] On Behalf Of Michael Snoyman
Sent: 25 February 2013 18:19
To: Simon Peyton-Jones
Cc: Alexander Kjeldaas; Simon Hengel; Haskell Cafe


Subject: Re: [Haskell-cafe] RFC: rewrite-with-location proposal

 

 

 

On Mon, Feb 25, 2013 at 4:42 PM, Simon Peyton-Jones <simonpj <at> microsoft.com> wrote:

I’m afraid the rewrite-rule idea won’t work.  RULES are applied during optimisation, when tons of inlining has happened and the program has been shaken around a lot. No reliable source location information is available there.

 

 

Do you mean that the proposal itself won't work, or specifically implementing this features in terms of existing rewrite rules won't work?

 

 

One thing I'd disagree with on that page is point (3). While it's certainly nice to have a full stack trace, implementing just shallow call information is incredibly useful. For logging and test framework usages, it in fact completely covers the use case. And even for debugging, I think it would be a massive step in the right direction.

 

I'll admit to ignorance on the internals of GHC, but it seems like doing the shallow source location approach would be far simpler than a full trace. I'd hate to lose a very valuable feature because we can't implement the perfect feature.

 

One idea I had, which that page does not yet describe, is to have an implicit parameter,
something like ?loc::Location, with

          errLoc :: ?loc:Location => String -> a

          errLoc s = error (“At “ ++ ?loc ++ “\n” ++ s)

 

This behave exactly like an ordinary implicit parameter, EXCEPT that if there is no binding for ?loc::Location, then the current location is used.  Thus

 

myErr :: ?loc:Location => Int -> a

myErr n = errLoc (show n)

 

foo :: Int -> int

foo n | n<0 = myErr n

        | otherwise = ...whatever...

 

When typechecking ‘foo’ we need ?loc:Location, and so the magic is that we use the location of the call of myErr in foo.

 

Simon

 

 

 

From: haskell-cafe-bounces <at> haskell.org [mailto:haskell-cafe-bounces <at> haskell.org] On Behalf Of Alexander Kjeldaas
Sent: 25 February 2013 12:16
To: Simon Hengel
Cc: Haskell Cafe
Subject: Re: [Haskell-cafe] RFC: rewrite-with-location proposal

 

On Mon, Feb 25, 2013 at 12:46 PM, Simon Hengel <sol <at> typeful.net> wrote:

On Mon, Feb 25, 2013 at 10:40:29AM +0100, Twan van Laarhoven wrote:
> I think there is no need to have a separate REWRITE_WITH_LOCATION
> rule. What if the compiler instead rewrites 'currentLocation' to the
> current location? Then you'd just define the rule:
>
> {-# REWRITE "errorLoc" error = errorLoc currentLocation #-}

REWRITE rules are only enabled with -O.  Source locations are also
useful during development (when you care more about compilation time
than efficient code and hence use -O0).  So I'm not sure whether it's a
good idea to lump those two things together.

 

I could imagine that source locations being useful when debugging rewrite rules for example.

 

I think your argument makes sense, but why not fix that specifically?

 

{-# REWRITE ALWAYS "errorLoc" error = errorLoc currentLocation #-}

 

Alexander

 


_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe <at> haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe

 


_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe <at> haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe
Gershom Bazerman | 26 Feb 16:51 2013
Picon

Re: RFC: rewrite-with-location proposal

On 2/25/13 9:42 AM, Simon Peyton-Jones wrote:
<!-- /* Font Definitions */ <at> font-face {font-family:Calibri; panose-1:2 15 5 2 2 2 4 3 2 4;} <at> font-face {font-family:Tahoma; panose-1:2 11 6 4 3 5 4 4 2 4;} <at> font-face {font-family:Verdana; panose-1:2 11 6 4 3 5 4 4 2 4;} /* Style Definitions */ p.MsoNormal, li.MsoNormal, div.MsoNormal {margin:0cm; margin-bottom:.0001pt; font-size:12.0pt; font-family:"Times New Roman","serif";} a:link, span.MsoHyperlink {mso-style-priority:99; color:blue; text-decoration:underline;} a:visited, span.MsoHyperlinkFollowed {mso-style-priority:99; color:purple; text-decoration:underline;} span.EmailStyle17 {mso-style-type:personal-reply; font-family:"Verdana","sans-serif"; color:#1F497D;} .MsoChpDefault {mso-style-type:export-only; font-family:"Calibri","sans-serif"; mso-fareast-language:EN-US;} <at> page WordSection1 {size:612.0pt 792.0pt; margin:72.0pt 72.0pt 72.0pt 72.0pt;} div.WordSection1 {page:WordSection1;} -->

I’m afraid the rewrite-rule idea won’t work.  RULES are applied during optimisation, when tons of inlining has happened and the program has been shaken around a lot. No reliable source location information is available there.

 

See http://hackage.haskell.org/trac/ghc/wiki/ExplicitCallStack; and please edit it.

 

One idea I had, which that page does not yet describe, is to have an implicit parameter,
something like ?loc::Location, with

          errLoc :: ?loc:Location => String -> a

          errLoc s = error (“At “ ++ ?loc ++ “\n” ++ s)

 

This behave exactly like an ordinary implicit parameter, EXCEPT that if there is no binding for ?loc::Location, then the current location is used.  Thus


I like the general approach of this proposal quite a bit. I'd very much like Location to be not just a string, but a record type. Ideally we could recover not just module name, line and character, but also the name of the function that takes the location. This would eliminate an entire swath of use-cases for Template Haskell. For example, I've worked out a template-haskell-free version of the Cloud Haskell closure API, which hopefully is getting merged in at some point. The major drawback it has is that the user is required to provide a globally-unique identifier for each closure, ideally stable across compilations. The current TH code solves this by grabbing the function and module name. If we could get direct access to these things without requiring template haskell, that would be quite nice. Other types of RPC libraries I've worked on could similarly benefit from this.

Cheers,
Gershom


_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe <at> haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe
Alberto G. Corona | 3 Mar 23:41 2013
Picon

Re: RFC: rewrite-with-location proposal

Additionally, Another  way to include line number information and to improve readability of the degugging code  is to add "verify"  as an  "assert" with flipped parameters so we can write:

let x= head xs                 `verify` (not $ null xs)

So the assertions appear on the right , separated from the  rest of the code.

instead of

let x= assert (not $ null xs) xs





2013/2/26 Gershom Bazerman <gershomb <at> gmail.com>
On 2/25/13 9:42 AM, Simon Peyton-Jones wrote:

I’m afraid the rewrite-rule idea won’t work.  RULES are applied during optimisation, when tons of inlining has happened and the program has been shaken around a lot. No reliable source location information is available there.

 

See http://hackage.haskell.org/trac/ghc/wiki/ExplicitCallStack; and please edit it.

 

One idea I had, which that page does not yet describe, is to have an implicit parameter,
something like ?loc::Location, with

          errLoc :: ?loc:Location => String -> a

          errLoc s = error (“At “ ++ ?loc ++ “\n” ++ s)

 

This behave exactly like an ordinary implicit parameter, EXCEPT that if there is no binding for ?loc::Location, then the current location is used.  Thus


I like the general approach of this proposal quite a bit. I'd very much like Location to be not just a string, but a record type. Ideally we could recover not just module name, line and character, but also the name of the function that takes the location. This would eliminate an entire swath of use-cases for Template Haskell. For example, I've worked out a template-haskell-free version of the Cloud Haskell closure API, which hopefully is getting merged in at some point. The major drawback it has is that the user is required to provide a globally-unique identifier for each closure, ideally stable across compilations. The current TH code solves this by grabbing the function and module name. If we could get direct access to these things without requiring template haskell, that would be quite nice. Other types of RPC libraries I've worked on could similarly benefit from this.

Cheers,
Gershom



_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe <at> haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe




--
Alberto.
_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe <at> haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe
Evan Laforge | 2 Dec 22:43 2013
Picon

Re: RFC: rewrite-with-location proposal

Hey, whatever happened with this?  Is there anything in the way of
getting this merged?  Is there some way I could help?

On Sun, Feb 24, 2013 at 10:06 PM, Michael Snoyman <michael <at> snoyman.com> wrote:
> Quite a while back, Simon Hengel and I put together a proposal[1] for a new
> feature in GHC. The basic idea is pretty simple: provide a new pragma that
> could be used like so:
>
> error :: String -> a
> errorLoc :: IO Location -> String -> a
> {-# REWRITE_WITH_LOCATION error errorLoc #-}
>
> Then all usages of `error` would be converted into calls to `errorLoc` by
> the compiler, passing in the location information of where the call
> originated from. Our three intended use cases are:
>
> * Locations for failing test cases in a test framework
> * Locations for log messages
> * assert/error/undefined
>
> Note that the current behavior of the assert function[2] already includes
> this kind of approach, but it is a special case hard-coded into the
> compiler. This proposal essentially generalizes that behavior and makes it
> available for all functions, whether included with GHC or user-defined.
>
> The proposal spells out some details of this approach, and contrasts with
> other methods being used today for the same purpose, such as TH and CPP.
>
> Michael
>
> [1] https://github.com/sol/rewrite-with-location
> [2]
> http://hackage.haskell.org/packages/archive/base/4.6.0.1/doc/html/Control-Exception.html#v:assert
>
> _______________________________________________
> Haskell-Cafe mailing list
> Haskell-Cafe <at> haskell.org
> http://www.haskell.org/mailman/listinfo/haskell-cafe
>
Simon Hengel | 2 Dec 23:06 2013
Picon

Re: RFC: rewrite-with-location proposal

Hi Evan!

On Mon, Dec 02, 2013 at 01:43:31PM -0800, Evan Laforge wrote:
> Hey, whatever happened with this?

My code for this is here:

    https://github.com/sol/ghc/commits/rewrite-with-location

Revision 03e63f0a70ec8c0fece4049c2d714ea533494ec2 was fully functional,
but it needs to be rebased on current master.  The missing feature here
is that type checking only happens on rewrite.  I just added a wip
commit with local modifications that do the type checking earlier, when
the module with the rewrite pragma is compiled.

> Is there anything in the way of getting this merged?  Is there some
> way I could help?

This needs rebasing + I'm not sure if the wip commit currently compiles.
I'm somewhat swamped, so I'm not sure when I'll have time to work on
this.  If you want to help, that would be awesome!  I'm happy to help
with any questions (solirc on freenode, feel free to say hello in #hspec
;).

Cheers,
Simon
Simon Peyton-Jones | 5 Dec 13:13 2013
Picon

Re: RFC: rewrite-with-location proposal

Simon

Interesting!

There's been lot of work on this kind of thing, mostly collected here:
https://ghc.haskell.org/trac/ghc/wiki/ExplicitCallStack

I didn't know about your work, so I've added it.

I'd be happy to see progress on this front. Tristan's "Finding the needle" stuff was close to "ready" but
there were some awkward points (described in his paper) that meant he didn't feel it was done.

To progress this, it'd be helpful to look at his work, articulate what the differences are, perhaps take the
best of both, identify weak spots, and figure out what (if anything) should be done about them.  

We don't want the best to be the enemy of the good, but it's also worth ensuring that we take advantage of all
the land-mine-discovery that earlier work has done.

Simon

| -----Original Message-----
| From: Haskell-Cafe [mailto:haskell-cafe-bounces <at> haskell.org] On Behalf
| Of Simon Hengel
| Sent: 02 December 2013 22:06
| To: Evan Laforge
| Cc: Haskell Cafe
| Subject: Re: [Haskell-cafe] RFC: rewrite-with-location proposal
| 
| Hi Evan!
| 
| On Mon, Dec 02, 2013 at 01:43:31PM -0800, Evan Laforge wrote:
| > Hey, whatever happened with this?
| 
| My code for this is here:
| 
|     https://github.com/sol/ghc/commits/rewrite-with-location
| 
| Revision 03e63f0a70ec8c0fece4049c2d714ea533494ec2 was fully functional,
| but it needs to be rebased on current master.  The missing feature here
| is that type checking only happens on rewrite.  I just added a wip
| commit with local modifications that do the type checking earlier, when
| the module with the rewrite pragma is compiled.
| 
| > Is there anything in the way of getting this merged?  Is there some
| > way I could help?
| 
| This needs rebasing + I'm not sure if the wip commit currently compiles.
| I'm somewhat swamped, so I'm not sure when I'll have time to work on
| this.  If you want to help, that would be awesome!  I'm happy to help
| with any questions (solirc on freenode, feel free to say hello in #hspec
| ;).
| 
| Cheers,
| Simon
| _______________________________________________
| Haskell-Cafe mailing list
| Haskell-Cafe <at> haskell.org
| http://www.haskell.org/mailman/listinfo/haskell-cafe

Gmane