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

the scala @experiment

9 replies
extempore
Joined: 2008-12-17,
User offline. Last seen 35 weeks 3 days ago.

For a while I have tried to mark anything I checked in which might not
be greeted by universal enthusiasm with @experimental on the theory that
when someone did notice it and I had to revert it, it'd be difficult for
any bleeding-edgers to be too attached. Still, even months later I'm
not at all sure anyone has ever seen much of it, so I'm going to stick
my head in the vise and list it all right here.

I'm not even going to argue for keeping any of it, since (and I say this
in total seriousness) I have achieved a near-perfect inverse correlation
between time spent on subject-specific advocacy and longevity of any
associated code. I'll only suggest that it'd be nice if we could remove
all the @experimentals, which means everything either gets reverted or
has the mole lasered off.

These entire classes/objects are so annotated:

src/compiler/scala/tools/nsc/io/Process.scala
src/library/scala/collection/immutable/GenericRange.scala
src/library/scala/concurrent/DelayedLazyVal.scala
src/library/scala/reflect/Invocation.scala
src/library/scala/reflect/RichClass.scala

And these files contain the following @experimental methods:

src/library/scala/collection/Iterator.scala

def filterMap[B](pf: PartialFunction[Any, B]): Iterator[B]

src/library/scala/collection/TraversableLike.scala

def filterMap[B, That](pf: PartialFunction[Any, B])(implicit bf: CanBuildFrom[Repr, B, That]): That
def toSet[B >: A]: immutable.Set[B]

src/library/scala/Function.scala

// On object Function
// (Listing this one is causing me to flinch involuntarily)
case class ??[T](x: T)

src/library/scala/Option.scala

// on object Option
def apply[A](x: A): Option[A]

// on instances of Option
def orNull[A1 >: A](implicit ev: Null <:< A1): A1
def filterMap[B](pf: PartialFunction[Any, B]): Option[B]

src/library/scala/PartialFunction.scala

// the whole object PartialFunction, containing:
def cond[T](x: T)(pf: PartialFunction[T, Boolean]): Boolean
def condOpt[T,U](x: T)(pf: PartialFunction[T, U]): Option[U]

Chris Marshall
Joined: 2009-06-17,
User offline. Last seen 44 weeks 3 days ago.
RE: the scala @experiment
I have had a look around some of the on-the-horizon features and will comment on those.


> src/library/scala/collection/immutable/GenericRange.scala

I don't think this is powerful enough - for example an open-closed (or closed-open) range is not possible and you should be able to create Range on any type T when supplied an Ordering[T]. For example, having a Range[Date] (for some useful Date impl) or a Range[Instant] is a common use-case. I have a Java implementation of such a class.

> src/library/scala/reflect/Invocation.scala

I would like to see examples of the usage of this which are *realistic*. For example, if I knew the name of a method and its arguments, then I would just call the method as opposed to using the "o 'foo" syntax. I tried to use this to invoke a method called "methodName" with "args": Any* and couldn't figure it out.

> And these files contain the following @experimental methods:
>
> src/library/scala/collection/Iterator.scala
>
> def filterMap[B](pf: PartialFunction[Any, B]): Iterator[B]
>
> src/library/scala/collection/TraversableLike.scala
>
> def filterMap[B, That](pf: PartialFunction[Any, B])(implicit bf: CanBuildFrom[Repr, B, That]): That
> def toSet[B >: A]: immutable.Set[B]

I like the filterMap functionality - very useful. Also I agree that toSet is also useful, even if the code to DIY is hardly onerous.

> src/library/scala/Option.scala
>
> // on object Option
> def apply[A](x: A): Option[A]
>
> // on instances of Option
> def orNull[A1 >: A](implicit ev: Null <:< A1): A1
> def filterMap[B](pf: PartialFunction[Any, B]): Option[B]

I think these are all very useful - the orNull and the apply(x) particularly so, as I have to deal with a lot of legacy Java libs. Definitely vote to keep all this in. I would also like to have this functionality on Option:

  def notEmptyAnd(f : T => Boolean) : Boolean = this match { case None => false; case Some(t) => f(t) }

  def isEmptyOr(f : T => Boolean) : Boolean = this match { case None => true; case Some(t) => f(t) }

But then that's just me!

Chris



New Windows 7: Find the right PC for you. Learn more.
Seth Tisue
Joined: 2008-12-16,
User offline. Last seen 34 weeks 3 days ago.
Re: the scala @experiment

>>>>> "Paul" == Paul Phillips writes:

Paul> src/library/scala/collection/TraversableLike.scala
Paul> def toSet[B >: A]: immutable.Set[B]

This is really handy. I use it all the time. I hope it is accepted as
a standard part of the collections API.

Obviously you can do the same thing with Set() ++ foo or Set(foo:_*),
but I find it really helps the readability of code if you can make
chains of operations where all of the links all read in the same
direction. An example from one of my Project Euler solutions:

(0 until rowCount).flatMap(row).toSet.filter(isSquareFree)

This is far easier to read than the alternatives without toSet:

(Set() ++ (0 until rowCount).flatMap(row)).filter(isSquareFree)

Set((0 until rowCount).flatMap(row):_*).filter(isSquareFree)

To read these your eyes and your mind have to reverse direction a lot.

odersky
Joined: 2008-07-29,
User offline. Last seen 45 weeks 6 days ago.
Re: the scala @experiment

Agreed about toSet, but in general I'm not keen on the @experimental
idea. The problem is that you are never sure whether you have tagged
enough. For instance, let's say GenericRange is experimental, and
there are factory methods in Range that create one. How do we make
sure these are marked as @experimental as well?

Or, another scenario: I'm fixing a bug that's critical for lift, but
some experimental stuff breaks on the fix. Should I hold off with
fixing the bug until the experimental thing is resolved?

Cheers

David Hall 4
Joined: 2009-08-21,
User offline. Last seen 42 years 45 weeks ago.
Re: the scala @experiment

On Wed, Nov 4, 2009 at 11:17 AM, Seth Tisue wrote:
>>>>>> "Paul" == Paul Phillips writes:
>
>  Paul> src/library/scala/collection/TraversableLike.scala
>  Paul> def toSet[B >: A]: immutable.Set[B]
>
> This is really handy.  I use it all the time.  I hope it is accepted as
> a standard part of the collections API.

Just a thought, but would it maybe make sense to have a method just
called "to" with a signature like:

@experiment
def to[CC[_]](implicit bf: CanBuildFrom[Repr,A,CC[A]])

?

And so you could say to[Set], to[List], to[HashSet] ?

The only obvious downside I can see is you aren't (as far as I can
tell) able to override for a particular result type, so that
Seq(...).toSeq doesn't make a copy. Though maybe you could add another
implicit param to check if Repr and CC[A] were the same...

extempore
Joined: 2008-12-17,
User offline. Last seen 35 weeks 3 days ago.
Re: the scala @experiment

On Wed, Nov 04, 2009 at 08:44:17PM +0100, martin odersky wrote:
> Agreed about toSet, but in general I'm not keen on the @experimental
> idea. The problem is that you are never sure whether you have tagged
> enough. For instance, let's say GenericRange is experimental, and
> there are factory methods in Range that create one. How do we make
> sure these are marked as @experimental as well?

Make sure? Not so easy, but it has an awful lot of company in the
compiler in that regard. What I could easily do (and intended as part
of the "@experimental vision") is roll out another compiler flag like
"-no-experimental" which would make it a compile time error to use any
of them. Or if that's not enough turn it around, they're only useable
if you compile with -experimental.

> Or, another scenario: I'm fixing a bug that's critical for lift, but
> some experimental stuff breaks on the fix. Should I hold off with
> fixing the bug until the experimental thing is resolved?

Break it. That's @experimental guy's problem, looks like it's back into
the lab with him.

odersky
Joined: 2008-07-29,
User offline. Last seen 45 weeks 6 days ago.
Re: the scala @experiment

On Wed, Nov 4, 2009 at 9:02 PM, Paul Phillips wrote:
> On Wed, Nov 04, 2009 at 08:44:17PM +0100, martin odersky wrote:
>> Agreed about toSet, but in general I'm not keen on the @experimental
>> idea. The problem is that you are never sure whether you have tagged
>> enough. For instance, let's say GenericRange is experimental, and
>> there are factory methods in Range that create one. How do we make
>> sure these are marked as @experimental as well?
>
> Make sure? Not so easy, but it has an awful lot of company in the
> compiler in that regard.  What I could easily do (and intended as part
> of the "@experimental vision") is roll out another compiler flag like
> "-no-experimental" which would make it a compile time error to use any
> of them.  Or if that's not enough turn it around, they're only useable
> if you compile with -experimental.
>
>> Or, another scenario: I'm fixing a bug that's critical for lift, but
>> some experimental stuff breaks on the fix. Should I hold off with
>> fixing the bug until the experimental thing is resolved?
>
> Break it.  That's @experimental guy's problem, looks like it's back into
> the lab with him.
>
Yes, but how do I do that if @experimental is just an annotation? At
least of there are compile-time errors those need to be fixed, right?

extempore
Joined: 2008-12-17,
User offline. Last seen 35 weeks 3 days ago.
Re: the scala @experiment

On Wed, Nov 04, 2009 at 09:38:57PM +0100, martin odersky wrote:
> Yes, but how do I do that if @experimental is just an annotation? At
> least of there are compile-time errors those need to be fixed, right?

I'm not entirely sure what scenario you are envisioning, but what I'm
trying to say is that if it's @experimental and it gets in your way, get
it out of your way by whatever means necessary, and that it is incumbent
upon whatever anonymous parties checked in something @experimental to
sort things out afterward.

And in the case of a particular anonymous party named me, I find this
all hypothetical to the point of pathology because I hold my
"@experimental" code to the same standards I do all the rest of my code.
The annotation is really a way of communicating that the code has not
(yet, the anonymous party hopes) been officially endorsed and should be
treated accordingly.

dcsobral
Joined: 2009-04-23,
User offline. Last seen 38 weeks 5 days ago.
Re: the scala @experiment
I think this has much merit. It is similar to the breakOut builder. In fact, it could probably be written as something like:   def to[CC[_]]((implicit bf: CanBuildFrom[Repr,A,CC[A]]) = this.map(x => x)(breakOut)   On the other hand, I dislike "to", because it's already used for Range, and, generally speaking, too vague. As alternatives, I'd say makeA (seq.makeA[List]) or turnInto (list.turnInto[Set]). The former sounds more purely functional.
On Wed, Nov 4, 2009 at 5:42 PM, David Hall <dlwh@cs.berkeley.edu> wrote:
On Wed, Nov 4, 2009 at 11:17 AM, Seth Tisue <seth@tisue.net> wrote:
>>>>>> "Paul" == Paul Phillips <paulp@improving.org> writes:
>
>  Paul> src/library/scala/collection/TraversableLike.scala
>  Paul> def toSet[B >: A]: immutable.Set[B]
>
> This is really handy.  I use it all the time.  I hope it is accepted as
> a standard part of the collections API.

Just a thought, but would it maybe make sense to have a method just
called "to" with a signature like:

@experiment
def to[CC[_]](implicit bf: CanBuildFrom[Repr,A,CC[A]])

?

And so you could say to[Set], to[List], to[HashSet] ?

The only obvious downside I can see is you aren't (as far as I can
tell) able to override for a particular result type, so that
Seq(...).toSeq doesn't make a copy. Though maybe you could add another
implicit param to check if Repr and CC[A] were the same...

-- David



--
Daniel C. Sobral

Veni, vidi, veterni.
odersky
Joined: 2008-07-29,
User offline. Last seen 45 weeks 6 days ago.
Re: the scala @experiment

On Wed, Nov 4, 2009 at 9:53 PM, Paul Phillips wrote:
> On Wed, Nov 04, 2009 at 09:38:57PM +0100, martin odersky wrote:
>> Yes, but how do I do that if @experimental is just an annotation? At
>> least of there are compile-time errors those need to be fixed, right?
>
> I'm not entirely sure what scenario you are envisioning, but what I'm
> trying to say is that if it's @experimental and it gets in your way, get
> it out of your way by whatever means necessary, and that it is incumbent
> upon whatever anonymous parties checked in something @experimental to
> sort things out afterward.

How? Delete it? This might cause an avalanche of other breakage.
No, I really think we need to keep trunk (i.e. the next release
candidate) separate from stuff that's preliminary and experimental.
>
> And in the case of a particular anonymous party named me, I find this
> all hypothetical to the point of pathology because I hold my
> "@experimental" code to the same standards I do all the rest of my code.
> The annotation is really a way of communicating that the code has not
> (yet, the anonymous party hopes) been officially endorsed and should be
> treated accordingly.
>
I was not talking about you in particular. I know your coding
standards. But I also know that I spent no small time updating
GenericRange which was @experimental when I changed Range to be
strict. in that case, it was not a critical bug, so I did not mind
doing it, but there could be other situations where I would have a
problem with experimantal code.

Cheers

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