This page is no longer maintained — Please continue to the home page at www.scala-lang.org

Naive proposal du jour: Extractor error messages

7 replies
Alex Cruise
Joined: 2008-12-17,
User offline. Last seen 2 years 26 weeks ago.
Let's say you've written an extractor that works beautifully, but when it fails, you'd like to return extra information about why it failed.  While the standard pattern matching idiom leaves no place for such information to escape, I think it'd be neat if it could be included in any MatchError that might be generated.
Here's an example that I wrote just now; it tests whether the scrutinee Map is a super-Map of some predefined Map:
case class SubMap[K,V](toBeMatched: Map[K,V]) { 
   def unapply(in: Map[K,V]): Boolean = {
     val matches = in.filterKeys(toBeMatched.keySet)
     if (matches.size < toBeMatched.size) {
       println("At least one key didn't match (%d < %d)".format(matches.size, toBeMatched.size))
       false
     } else {
       for ((k,v) <- matches) {
         if (in(k) != v) {
           println("Input's %s->%s didn't match expected %s".format(k, in(k), v))
           return false
         }
       }
       return true
     }
   }
}

Obviously those println statements stick out like a sore thumb, but the intent is clear.  As a user of an extractor, it'd be nice to get the information out of some kind of wormhole without having to resort to dirty tricks that are basically tantamount to errno.h.
So, what if extractors could return Eithers instead of Options?

Boolean                => Either[String,Boolean] (Either[String,Unit] would be equivalent, but probably confusing) Option[X]              => Either[String, X]Option[Tuple<n>] => Either[String, Tuple<n>[...]]
Obviously, in cases where no MatchError is possible (e.g. collect), this wouldn't add any value, but I think it'd be kinda neat...
TIA for your comments and flames!
-0xe1a
Naftoli Gugenheim
Joined: 2008-12-17,
User offline. Last seen 42 years 45 weeks ago.
Re: Naive proposal du jour: Extractor error messages
How would you expect code using it to look, and where would the error message go?

On Tue, Jan 17, 2012 at 4:13 PM, Alex Cruise <alex [at] cluonflux [dot] com> wrote:
Let's say you've written an extractor that works beautifully, but when it fails, you'd like to return extra information about why it failed.  While the standard pattern matching idiom leaves no place for such information to escape, I think it'd be neat if it could be included in any MatchError that might be generated.
Here's an example that I wrote just now; it tests whether the scrutinee Map is a super-Map of some predefined Map:
case class SubMap[K,V](toBeMatched: Map[K,V]) { 
   def unapply(in: Map[K,V]): Boolean = {
     val matches = in.filterKeys(toBeMatched.keySet)
     if (matches.size < toBeMatched.size) {
       println("At least one key didn't match (%d < %d)".format(matches.size, toBeMatched.size))
       false
     } else {
       for ((k,v) <- matches) {
         if (in(k) != v) {
           println("Input's %s->%s didn't match expected %s".format(k, in(k), v))
           return false
         }
       }
       return true
     }
   }
}

Obviously those println statements stick out like a sore thumb, but the intent is clear.  As a user of an extractor, it'd be nice to get the information out of some kind of wormhole without having to resort to dirty tricks that are basically tantamount to errno.h.
So, what if extractors could return Eithers instead of Options?

Boolean                => Either[String,Boolean] (Either[String,Unit] would be equivalent, but probably confusing) Option[X]              => Either[String, X]Option[Tuple<n>] => Either[String, Tuple<n>[...]]
Obviously, in cases where no MatchError is possible (e.g. collect), this wouldn't add any value, but I think it'd be kinda neat...
TIA for your comments and flames!
-0xe1a

Martin McNulty
Joined: 2011-10-13,
User offline. Last seen 42 years 45 weeks ago.
Re: Naive proposal du jour: Extractor error messages
This sounds a lot like Scalaz validations...

2012/1/18 Naftoli Gugenheim <naftoligug [at] gmail [dot] com>
How would you expect code using it to look, and where would the error message go?

On Tue, Jan 17, 2012 at 4:13 PM, Alex Cruise <alex [at] cluonflux [dot] com> wrote:
Let's say you've written an extractor that works beautifully, but when it fails, you'd like to return extra information about why it failed.  While the standard pattern matching idiom leaves no place for such information to escape, I think it'd be neat if it could be included in any MatchError that might be generated.
Here's an example that I wrote just now; it tests whether the scrutinee Map is a super-Map of some predefined Map:
case class SubMap[K,V](toBeMatched: Map[K,V]) { 
   def unapply(in: Map[K,V]): Boolean = {
     val matches = in.filterKeys(toBeMatched.keySet)
     if (matches.size < toBeMatched.size) {
       println("At least one key didn't match (%d < %d)".format(matches.size, toBeMatched.size))
       false
     } else {
       for ((k,v) <- matches) {
         if (in(k) != v) {
           println("Input's %s->%s didn't match expected %s".format(k, in(k), v))
           return false
         }
       }
       return true
     }
   }
}

Obviously those println statements stick out like a sore thumb, but the intent is clear.  As a user of an extractor, it'd be nice to get the information out of some kind of wormhole without having to resort to dirty tricks that are basically tantamount to errno.h.
So, what if extractors could return Eithers instead of Options?

Boolean                => Either[String,Boolean] (Either[String,Unit] would be equivalent, but probably confusing) Option[X]              => Either[String, X]Option[Tuple<n>] => Either[String, Tuple<n>[...]]
Obviously, in cases where no MatchError is possible (e.g. collect), this wouldn't add any value, but I think it'd be kinda neat...
TIA for your comments and flames!
-0xe1a


Alex Cruise
Joined: 2008-12-17,
User offline. Last seen 2 years 26 weeks ago.
Re: Naive proposal du jour: Extractor error messages
On Wed, Jan 18, 2012 at 12:32 AM, Naftoli Gugenheim <naftoligug [at] gmail [dot] com> wrote:
How would you expect code using it to look, and where would the error message go?

The user code would look exactly the same; it's just that in the event of a MatchError, the compiler would take the Left-value and use it in the MatchError's error message.  When no MatchError is forthcoming (either because the extractor succeeded, or it's being called from a "safe" context like collect, no difference is observable.
Of course, when there are multiple failing extractors, we'd have to decide which error message(s) to use--either concatenate them, or last one wins.  And in the event of a successful match from a subsequent pattern, the error messages would obviously be discarded. 
-0xe1a
Naftoli Gugenheim
Joined: 2008-12-17,
User offline. Last seen 42 years 45 weeks ago.
Re: Naive proposal du jour: Extractor error messages
Ah, so the compiler has to handle the message. Two thoughts: (1) the virtual pattern matcher probably makes this a lot easier to implement, and (2) this is more the job of an annotation than Either.


On Wed, Jan 18, 2012 at 2:10 PM, Alex Cruise <alex [at] cluonflux [dot] com> wrote:
On Wed, Jan 18, 2012 at 12:32 AM, Naftoli Gugenheim <naftoligug [at] gmail [dot] com> wrote:
How would you expect code using it to look, and where would the error message go?

The user code would look exactly the same; it's just that in the event of a MatchError, the compiler would take the Left-value and use it in the MatchError's error message.  When no MatchError is forthcoming (either because the extractor succeeded, or it's being called from a "safe" context like collect, no difference is observable.
Of course, when there are multiple failing extractors, we'd have to decide which error message(s) to use--either concatenate them, or last one wins.  And in the event of a successful match from a subsequent pattern, the error messages would obviously be discarded. 
-0xe1a

Alex Cruise
Joined: 2008-12-17,
User offline. Last seen 2 years 26 weeks ago.
Re: Naive proposal du jour: Extractor error messages
On Mon, Jan 23, 2012 at 7:27 PM, Naftoli Gugenheim <naftoligug [at] gmail [dot] com> wrote:
Ah, so the compiler has to handle the message. Two thoughts: (1) the virtual pattern matcher probably makes this a lot easier to implement,

Let's hope! 
and (2) this is more the job of an annotation than Either.

That would work, but for complex extractors that can fail in a variety of ways, there'd be no way to distinguish them.
-0xe1a
moors
Joined: 2010-10-06,
User offline. Last seen 36 weeks 4 days ago.
Re: Naive proposal du jour: Extractor error messages
tid: 10 status: 1 [note: this part of the virtualizing pattern matcher is not implemented yet and it's pretty low priority]
that said -- nice use case!
in principle, with the virtualizing pattern matcher you can override[1] the match monad (normally it's Option) to something more akin to the Parser monad,which supports customizing error messages
with parameterized extractors[2], you could customize the error message in each pattern, or your extractor could simply be hard-wired with a given message
adriaan
[1] this is possible right now, but I haven't experimented much with alternative monads -- also, monad composition is known to be hard, and synthesized extractors (those for case classes) are hardwired to using Option, so mixing and matching your own extractors with existing ones that use a different monad could turn out to be tricky[2] i have experimented with this, but it's not implemented(outside that experimental branch)/spec'ed/sipped/...
Tony Morris
Joined: 2008-12-19,
User offline. Last seen 30 weeks 4 days ago.
Re: Naive proposal du jour: Extractor error messages

See Control.Failure on hackage for a decent library to generalise failure. It requires fundeps though iirc, so not sure how a port would go.

On Feb 6, 2012 11:03 PM, "Adriaan Moors" <adriaan [dot] moors [at] gmail [dot] com> wrote:
[note: this part of the virtualizing pattern matcher is not implemented yet and it's pretty low priority]
that said -- nice use case!
in principle, with the virtualizing pattern matcher you can override[1] the match monad (normally it's Option) to something more akin to the Parser monad, which supports customizing error messages
with parameterized extractors[2], you could customize the error message in each pattern, or your extractor could simply be hard-wired with a given message
adriaan
[1] this is possible right now, but I haven't experimented much with alternative monads -- also, monad composition is known to be hard, and synthesized extractors (those for case classes) are hardwired to using Option, so mixing and matching your own extractors with existing ones that use a different monad could turn out to be tricky [2] i have experimented with this, but it's not implemented(outside that experimental branch)/spec'ed/sipped/...

Copyright © 2012 École Polytechnique Fédérale de Lausanne (EPFL), Lausanne, Switzerland