- About Scala
- Documentation
- Code Examples
- Software
- Scala Developers
Why does PartialFunction <: Function1?
Wed, 2009-07-29, 23:13
In a discussion in #scala this afternoon, the fact that Set[A] extends
(A => Boolean) and Sequence[A] extends PartialFunction[Int, A] came
up. It was pointed out that implementing something that is both a
Set[A] and a Sequence[A] (for example, TreeSet?) could not be properly
implemented due to the conflict between the erased types of Function1
in each respective case.
I hadn't thought about the fact that PartialFunction <: Function1
before, but now this seems like a very confusing decision to me. I
would expect it to be the other way round, since the way it currently
is means that a class of runtime exceptions is introduced for the
situation where a PartialFunction instance is passed to a function
that expects a Function1 and hence doesn't check isDefinedAt.
Now, of course, having Function1 extend PartialFunction directly won't
work because you can't overload apply(A) with different return types.
However, one could have something like the following:
trait PartialFunction[A,B] {
def papply(a: A): Option[B]
}
trait Function1[A,B] extends PartialFunction[A,B] {
def apply(a: A): B
override def papply(a: A) = Some(apply(a))
}
This would eliminate the need for runtime isDefinedAt checks, plug the
possible runtime exception hole, and even allow TreeSet[A] extends
Set[A] with Sequence[A].
So, why was it done the other way around? Can, and should, this be changed?
Kris
Wed, 2009-07-29, 23:27
#2
Re: Why does PartialFunction <: Function1?
*... as then the conflict would be between ...
--j
On Wed, Jul 29, 2009 at 3:20 PM, Jorge Ortiz <jorge.ortiz@gmail.com> wrote:
--j
On Wed, Jul 29, 2009 at 3:20 PM, Jorge Ortiz <jorge.ortiz@gmail.com> wrote:
Nitpick:
Your suggestion wouldn't allow TreeSet[A] extends Set[A] with Sequence[A], as then between PartialFunction[A, Boolean] (through Set[A]) and PartialFunction[Int, A] (through Sequence).
--j
On Wed, Jul 29, 2009 at 3:12 PM, Kris Nuttycombe <kris.nuttycombe@gmail.com> wrote:
In a discussion in #scala this afternoon, the fact that Set[A] extends
(A => Boolean) and Sequence[A] extends PartialFunction[Int, A] came
up. It was pointed out that implementing something that is both a
Set[A] and a Sequence[A] (for example, TreeSet?) could not be properly
implemented due to the conflict between the erased types of Function1
in each respective case.
I hadn't thought about the fact that PartialFunction <: Function1
before, but now this seems like a very confusing decision to me. I
would expect it to be the other way round, since the way it currently
is means that a class of runtime exceptions is introduced for the
situation where a PartialFunction instance is passed to a function
that expects a Function1 and hence doesn't check isDefinedAt.
Now, of course, having Function1 extend PartialFunction directly won't
work because you can't overload apply(A) with different return types.
However, one could have something like the following:
trait PartialFunction[A,B] {
def papply(a: A): Option[B]
}
trait Function1[A,B] extends PartialFunction[A,B] {
def apply(a: A): B
override def papply(a: A) = Some(apply(a))
}
This would eliminate the need for runtime isDefinedAt checks, plug the
possible runtime exception hole, and even allow TreeSet[A] extends
Set[A] with Sequence[A].
So, why was it done the other way around? Can, and should, this be changed?
Kris
Wed, 2009-07-29, 23:27
#3
Re: Why does PartialFunction <: Function1?
That's true. Should have thought more, but I think that the hierarchy
is still upside down.
Set[A] probably shouldn't extend PartialFunction[A, Boolean]; you
already have contains anyway, so it's kind of a superfluous syntactic
nicety.
Kris
On Wed, Jul 29, 2009 at 4:20 PM, Jorge Ortiz wrote:
> Nitpick:
>
> Your suggestion wouldn't allow TreeSet[A] extends Set[A] with Sequence[A],
> as then between PartialFunction[A, Boolean] (through Set[A]) and
> PartialFunction[Int, A] (through Sequence).
>
> --j
>
> On Wed, Jul 29, 2009 at 3:12 PM, Kris Nuttycombe
> wrote:
>>
>> In a discussion in #scala this afternoon, the fact that Set[A] extends
>> (A => Boolean) and Sequence[A] extends PartialFunction[Int, A] came
>> up. It was pointed out that implementing something that is both a
>> Set[A] and a Sequence[A] (for example, TreeSet?) could not be properly
>> implemented due to the conflict between the erased types of Function1
>> in each respective case.
>>
>> I hadn't thought about the fact that PartialFunction <: Function1
>> before, but now this seems like a very confusing decision to me. I
>> would expect it to be the other way round, since the way it currently
>> is means that a class of runtime exceptions is introduced for the
>> situation where a PartialFunction instance is passed to a function
>> that expects a Function1 and hence doesn't check isDefinedAt.
>>
>> Now, of course, having Function1 extend PartialFunction directly won't
>> work because you can't overload apply(A) with different return types.
>> However, one could have something like the following:
>>
>> trait PartialFunction[A,B] {
>> def papply(a: A): Option[B]
>> }
>>
>> trait Function1[A,B] extends PartialFunction[A,B] {
>> def apply(a: A): B
>> override def papply(a: A) = Some(apply(a))
>> }
>>
>> This would eliminate the need for runtime isDefinedAt checks, plug the
>> possible runtime exception hole, and even allow TreeSet[A] extends
>> Set[A] with Sequence[A].
>>
>> So, why was it done the other way around? Can, and should, this be
>> changed?
>>
>> Kris
>
>
Wed, 2009-07-29, 23:37
#4
Re: Why does PartialFunction <: Function1?
Nitpick:
Your suggestion wouldn't allow TreeSet[A] extends Set[A] with Sequence[A], as then between PartialFunction[A, Boolean] (through Set[A]) and PartialFunction[Int, A] (through Sequence).
--j
On Wed, Jul 29, 2009 at 3:12 PM, Kris Nuttycombe <kris.nuttycombe@gmail.com> wrote:
Your suggestion wouldn't allow TreeSet[A] extends Set[A] with Sequence[A], as then between PartialFunction[A, Boolean] (through Set[A]) and PartialFunction[Int, A] (through Sequence).
--j
On Wed, Jul 29, 2009 at 3:12 PM, Kris Nuttycombe <kris.nuttycombe@gmail.com> wrote:
In a discussion in #scala this afternoon, the fact that Set[A] extends
(A => Boolean) and Sequence[A] extends PartialFunction[Int, A] came
up. It was pointed out that implementing something that is both a
Set[A] and a Sequence[A] (for example, TreeSet?) could not be properly
implemented due to the conflict between the erased types of Function1
in each respective case.
I hadn't thought about the fact that PartialFunction <: Function1
before, but now this seems like a very confusing decision to me. I
would expect it to be the other way round, since the way it currently
is means that a class of runtime exceptions is introduced for the
situation where a PartialFunction instance is passed to a function
that expects a Function1 and hence doesn't check isDefinedAt.
Now, of course, having Function1 extend PartialFunction directly won't
work because you can't overload apply(A) with different return types.
However, one could have something like the following:
trait PartialFunction[A,B] {
def papply(a: A): Option[B]
}
trait Function1[A,B] extends PartialFunction[A,B] {
def apply(a: A): B
override def papply(a: A) = Some(apply(a))
}
This would eliminate the need for runtime isDefinedAt checks, plug the
possible runtime exception hole, and even allow TreeSet[A] extends
Set[A] with Sequence[A].
So, why was it done the other way around? Can, and should, this be changed?
Kris
Wed, 2009-07-29, 23:47
#5
Re: Why does PartialFunction <: Function1?
I would like to understand why Set and Sequence extend PartialFunction.
2009/7/29 Jorge Ortiz :
> Nitpick:
>
> Your suggestion wouldn't allow TreeSet[A] extends Set[A] with Sequence[A],
> as then between PartialFunction[A, Boolean] (through Set[A]) and
> PartialFunction[Int, A] (through Sequence).
>
> --j
>
> On Wed, Jul 29, 2009 at 3:12 PM, Kris Nuttycombe
> wrote:
>>
>> In a discussion in #scala this afternoon, the fact that Set[A] extends
>> (A => Boolean) and Sequence[A] extends PartialFunction[Int, A] came
>> up. It was pointed out that implementing something that is both a
>> Set[A] and a Sequence[A] (for example, TreeSet?) could not be properly
>> implemented due to the conflict between the erased types of Function1
>> in each respective case.
>>
>> I hadn't thought about the fact that PartialFunction <: Function1
>> before, but now this seems like a very confusing decision to me. I
>> would expect it to be the other way round, since the way it currently
>> is means that a class of runtime exceptions is introduced for the
>> situation where a PartialFunction instance is passed to a function
>> that expects a Function1 and hence doesn't check isDefinedAt.
>>
>> Now, of course, having Function1 extend PartialFunction directly won't
>> work because you can't overload apply(A) with different return types.
>> However, one could have something like the following:
>>
>> trait PartialFunction[A,B] {
>> def papply(a: A): Option[B]
>> }
>>
>> trait Function1[A,B] extends PartialFunction[A,B] {
>> def apply(a: A): B
>> override def papply(a: A) = Some(apply(a))
>> }
>>
>> This would eliminate the need for runtime isDefinedAt checks, plug the
>> possible runtime exception hole, and even allow TreeSet[A] extends
>> Set[A] with Sequence[A].
>>
>> So, why was it done the other way around? Can, and should, this be
>> changed?
>>
>> Kris
>
>
Thu, 2009-07-30, 02:57
#6
Re: Why does PartialFunction <: Function1?
And, furthermore, it's one excuse for not making Set co-variant. :-)
On Wed, Jul 29, 2009 at 7:25 PM, Kris Nuttycombe <kris.nuttycombe@gmail.com> wrote:
--
Daniel C. Sobral
Something I learned in academia: there are three kinds of academic reviews: review by name, review by reference and review by value.
On Wed, Jul 29, 2009 at 7:25 PM, Kris Nuttycombe <kris.nuttycombe@gmail.com> wrote:
That's true. Should have thought more, but I think that the hierarchy
is still upside down.
Set[A] probably shouldn't extend PartialFunction[A, Boolean]; you
already have contains anyway, so it's kind of a superfluous syntactic
nicety.
Kris
On Wed, Jul 29, 2009 at 4:20 PM, Jorge Ortiz<jorge.ortiz@gmail.com> wrote:
> Nitpick:
>
> Your suggestion wouldn't allow TreeSet[A] extends Set[A] with Sequence[A],
> as then between PartialFunction[A, Boolean] (through Set[A]) and
> PartialFunction[Int, A] (through Sequence).
>
> --j
>
> On Wed, Jul 29, 2009 at 3:12 PM, Kris Nuttycombe <kris.nuttycombe@gmail.com>
> wrote:
>>
>> In a discussion in #scala this afternoon, the fact that Set[A] extends
>> (A => Boolean) and Sequence[A] extends PartialFunction[Int, A] came
>> up. It was pointed out that implementing something that is both a
>> Set[A] and a Sequence[A] (for example, TreeSet?) could not be properly
>> implemented due to the conflict between the erased types of Function1
>> in each respective case.
>>
>> I hadn't thought about the fact that PartialFunction <: Function1
>> before, but now this seems like a very confusing decision to me. I
>> would expect it to be the other way round, since the way it currently
>> is means that a class of runtime exceptions is introduced for the
>> situation where a PartialFunction instance is passed to a function
>> that expects a Function1 and hence doesn't check isDefinedAt.
>>
>> Now, of course, having Function1 extend PartialFunction directly won't
>> work because you can't overload apply(A) with different return types.
>> However, one could have something like the following:
>>
>> trait PartialFunction[A,B] {
>> def papply(a: A): Option[B]
>> }
>>
>> trait Function1[A,B] extends PartialFunction[A,B] {
>> def apply(a: A): B
>> override def papply(a: A) = Some(apply(a))
>> }
>>
>> This would eliminate the need for runtime isDefinedAt checks, plug the
>> possible runtime exception hole, and even allow TreeSet[A] extends
>> Set[A] with Sequence[A].
>>
>> So, why was it done the other way around? Can, and should, this be
>> changed?
>>
>> Kris
>
>
--
Daniel C. Sobral
Something I learned in academia: there are three kinds of academic reviews: review by name, review by reference and review by value.
Personally, I'd prefer Function1 to be a subclass of PartialFunction, with isDefinedAt overridden to always return true.
On Wed, Jul 29, 2009 at 7:12 PM, Kris Nuttycombe <kris.nuttycombe@gmail.com> wrote:
--
Daniel C. Sobral
Something I learned in academia: there are three kinds of academic reviews: review by name, review by reference and review by value.