Gábor Bakos | 1 May 2007 22:24
Picon

Re: Still annotations

Hi Nikolay,

Thank you for the fix. I think the mentioned web page could serve an example for the usage of arrays as parameters.
As I see in the <at> throws annotation, it does not allow Arrays for values. Is this mean, that the annotations may be multiple times from the same type at the same position? (I think it would be more natural if <at> throws accept array of classes.)
Best regards, gabor

2007/4/27, Nikolay Mihaylov <nikolay.mihaylov-p8DiymsW2f8@public.gmane.org>:
Hi Gabor,

You hit the right syntax but you also hit a bug in the compiler which
must have appeared when we changed the way array values are
constructed. It is now fixed in the repository and will be part of
the next release. Until then there's no way to use arrays in
annotations. Sorry for the inconvenience.

BTW, the syntax for annotation application is more flexible.  For
instance, in your case one could write <at> SuppressWarnings(Array
("unused")). Note that (1) you never need to write the type of the
Array and (2) for Java annotations the constructor parameter is the
annotation attribute with the name 'value'. Also, if you have empty
constructor argument list you need not write the empty parentheses, i.e.

<at> SuppressWarnings{val value = Array("unused")}

instead of

<at> SuppressWarnings(){val value = Array("unused"))}

For more details go to

     http://www.scala-lang.org/intro/annotations.html

Greetings

Nikolay


> Hi all,
>
> I still could not find the solution to this newbie question...
> Could you tell me the proper syntax? (How can I set annotation
> values for fields expecting a constant array?)
> (From my previous post I have tried the following syntax too:
> <at> SuppressWarnings(){val value=Array[String]("unused")}.
> The compiler's response was:
> Severity and Description    Path    Resource    Location
> Creation Time    Id
> attribute argument needs to be a constant; found: scala.Array.apply
> [java.lang.String]("unused")
> )
> Best regards, gabor
>

Tony Morris | 2 May 2007 00:59

HOF instead of DD

I was under the impression that I could always replace Dynamic Dispatch
with a Higher-Order Function, but I have trivialised a case where I am
now questioning this original belief. Note in the trait T, the return
type is inferred by the assigned value.

In the code below, I'd like to offer function o2 where the trait T is
never considered, since it is replaced with a HOF. However, my attempt
(o2) will fail to compile. Can [function o1 + trait T] be converted to a
HOF without the use of any traits?

trait T {
  def f[a](n: Int): a
}

object O {
  def o1(t: T): String = {
    val x: String = t.f(7)
    x
  }

  def o2[a](f: Int => a): String = {
    val x: String = f(7)
    x
  }
}

--

-- 
Tony Morris
http://tmorris.net/

Jamie Webb | 2 May 2007 01:32

Re: HOF instead of DD

On 2007-05-02 08:59:49 Tony Morris wrote:
> I was under the impression that I could always replace Dynamic
> Dispatch with a Higher-Order Function, but I have trivialised a case
> where I am now questioning this original belief. Note in the trait T,
> the return type is inferred by the assigned value.

I think your belief is correct.

> In the code below, I'd like to offer function o2 where the trait T is
> never considered, since it is replaced with a HOF. However, my attempt
> (o2) will fail to compile. Can [function o1 + trait T] be converted
> to a HOF without the use of any traits?
> 
> trait T {
>   def f[a](n: Int): a
> }
> 
> object O {
>   def o1(t: T): String = {
>     val x: String = t.f(7)
>     x
>   }
> 
>   def o2[a](f: Int => a): String = {
>     val x: String = f(7)
>     x
>   }
> }

Take a closer look at trait T. The type contract for f is "must be able
to return a value of an arbitrary type". I think the only way to
satisfy this is for the implementation of f to always throw an
exception. Thus your trait is equivalent to:

  trait T {
      def f(n : Int) : Nothing
  }

And this is of course easy to translate into a higher-order function.
The same pattern of eliminating type parameters should apply in all
cases, and no generality is lost by doing so.

/J

Tony Morris | 2 May 2007 01:53

Re: HOF instead of DD

I don't think your equivalence is correct. I see no legitimate reason to
ever use Nothing (or Any), other than to appeal to the way Java is (and
this might be a case). Further, I do not wish to accept the restrictions
imposed by doing this, even if I was to concede (for which I have found
no good reasons so far).

Simply,
def f[a](f: Foo): a
is *very* different to
f(foo: Foo): Nothing
for exactly the same reason that (Java):
<A> A f(Foo f)
is very different to:
Object f(Foo f)
Without going into it much further, these distinctions are evident when
it comes to the problems associated with the Java wildcard <?>. And
where do you need to look for those problems? Why, Scala itself!

The simpler question for me might be, can I add a type parameter to a
function argument, whose type is a function?

Certainly, I can do this in other languages with strong type systems and
parametric polymorphism. I understand if the answer is "no, because Java
said so".

Tony Morris
http://tmorris.net/

Jamie Webb wrote:
> On 2007-05-02 08:59:49 Tony Morris wrote:
>> I was under the impression that I could always replace Dynamic
>> Dispatch with a Higher-Order Function, but I have trivialised a case
>> where I am now questioning this original belief. Note in the trait T,
>> the return type is inferred by the assigned value.
> 
> I think your belief is correct.
> 
>> In the code below, I'd like to offer function o2 where the trait T is
>> never considered, since it is replaced with a HOF. However, my attempt
>> (o2) will fail to compile. Can [function o1 + trait T] be converted
>> to a HOF without the use of any traits?
>>
>> trait T {
>>   def f[a](n: Int): a
>> }
>>
>> object O {
>>   def o1(t: T): String = {
>>     val x: String = t.f(7)
>>     x
>>   }
>>
>>   def o2[a](f: Int => a): String = {
>>     val x: String = f(7)
>>     x
>>   }
>> }
> 
> Take a closer look at trait T. The type contract for f is "must be able
> to return a value of an arbitrary type". I think the only way to
> satisfy this is for the implementation of f to always throw an
> exception. Thus your trait is equivalent to:
> 
>   trait T {
>       def f(n : Int) : Nothing
>   }
> 
> And this is of course easy to translate into a higher-order function.
> The same pattern of eliminating type parameters should apply in all
> cases, and no generality is lost by doing so.
> 
> /J
> 

Jamie Webb | 2 May 2007 06:56

Re: HOF instead of DD

On 2007-05-02 09:53:50 Tony Morris wrote:
> I don't think your equivalence is correct.

If that is the case, please demonstrate it by providing a type-safe
implementation for T, which returns a value.

> I see no legitimate reason
> to ever use Nothing (or Any), other than to appeal to the way Java is
> (and this might be a case).

The Nothing type has nothing to do with Java. It's the empty type,
which is the return type of functions which do not return. It's
entirely sound and legitimate. So is Any. For example, how else would
you define the == method?

I don't believe the method signature you gave can be implemented except
by never returning (or by casting an arbitrary value, which cannot be
type-safe), therefore its return type is effectively Nothing.

> The simpler question for me might be, can I add a type parameter to a
> function argument, whose type is a function?

No. Scala only has rank-1 polymorphism.

As I said before, I think it ought to always be possible to eliminate
these anyway, though it looks like actually the compiler can't quite
manage it. I'm not sure if this is a bug or a 'limitation'.

Consider:

  trait T2 {
      def f[A](x : A) : A
  }

We can't shoehorn f into the Function1 type because of the type
parameter, but when accepting such a function as an argument it should
always be possible to know what values the type variable will take, e.g.

  def foo(f : (Int => Int) with (String => String)) = (f(5), f("x"))

Unfortunately the compiler accepts the above but doesn't seem to know
what to do with that sort of type.

> I understand if the answer is "no, because Java said so".

Again, this is not a matter which concerns Java. All this stuff is
erased before Java sees it.

Probably the reason Scala has no rank-2 polymorphism is just that the
type system is already complicated enough without it.

/J

Tony Morris | 2 May 2007 07:25

Re: HOF instead of DD

Jamie Webb wrote:
> On 2007-05-02 09:53:50 Tony Morris wrote:
>> I don't think your equivalence is correct.
> 
> If that is the case, please demonstrate it by providing a type-safe
> implementation for T, which returns a value.

Sorry, my mistake. The following code more closely represents my initial
intention.

trait T {
  def f[a](n: Int): U[a]
}

object T {
  def t = new T {
    def f[a](n: Int): U[a] = U.u: U[a]
  }
}

trait U[a] {

}

object U {
  def u[a] = new U[a] {

  }
}

> 
>> I see no legitimate reason
>> to ever use Nothing (or Any), other than to appeal to the way Java is
>> (and this might be a case).
> 
> The Nothing type has nothing to do with Java. 

Sure it does. In Java, it is called null.

> It's the empty type,
> which is the return type of functions which do not return. It's
> entirely sound and legitimate. So is Any. 

I could understand a case for Nothing (perhaps), but certainly not for
Any, other than, because it is imposed by constraints of maintaining
compatibility with Java.

> For example, how else would
> you define the == method?

I have already redefined it and use it all the time. It is of type a =>
a => Boolean as it should have been from the start (of Java). Makes life
a whole lot easier.

Tony Morris
http://tmorris.net/

Jamie Webb | 2 May 2007 13:26

Re: HOF instead of DD

On 2007-05-02 15:25:40 Tony Morris wrote:
> >> I see no legitimate reason
> >> to ever use Nothing (or Any), other than to appeal to the way Java
> >> is (and this might be a case).
> > 
> > The Nothing type has nothing to do with Java. 
> 
> Sure it does. In Java, it is called null.

No. null is the one and only value of type Null, and Null is the least
reference type. By contrast, there are no values at all of type
Nothing. There is no Java equivalent (though the Java compiler must
surely have such a concept internally).

> > For example, how else would
> > you define the == method?
> 
> I have already redefined it and use it all the time. It is of type a
> => a => Boolean as it should have been from the start (of Java).
> Makes life a whole lot easier.

I'm not sure what your version achieves? If you compare two values of
different types, the type variable will be instantiated to the common
supertype, which in the limit is Any.

/J

Eric Willigers | 2 May 2007 14:56
Picon

Strange behaviour with invalid sequence arguments

A few times I've used the List(a, b, c) notation and accidentally 
including a trailing comma: List(a, b, c, )

This is easy to do when the items are on separate lines, so I'm starting 
to instead use the notation
val data =
     a ::
     b ::
     c ::
     Nil

(This layout also has the advantage that no other lines need editing 
when an item is added or removed, even at the beginning or end,
and source code changes from different branches can be merged quite easily.)

When I accidentally enter List(a, b, c, ) the interesting thing is that 
I don't directly receive a parse error, instead I usually receive a type 
error.

Some test code is attached.

Suppose B is an object.

List(B,B,B,)
is reported as having type scala.List[(B.type, B.type, B.type)]
and
List(B,)
is reported as having type scala.List[(B.type,)]

Is this intentional?  What does type (B.type,) mean?

I'm noticing that the "Hamming distance" between different legal 
programs is becoming quite small (excluding distance achieved through 
the type system, which becomes more and more important). Perhaps this is 
an inevitable property of ideal languages for embedded DSLs.


class A {}
case object B extends A {}

object Test extends Application
{
    // accidental trailing comma, expected compilation error
    val data4 = List(B,B,B,B,)
    val data3 = List(B,B,B,)
    val data2 = List(B,B,)
    val data1 = List(B,)

    // error: illegal start of simple expression
    // val data0 = List(,)

    data4.foreach(&Console.println) // prints (B,B,B,B)
    data3.foreach(&Console.println) // prints (B,B,B)
    data2.foreach(&Console.println) // prints (B,B)
    data1.foreach(&Console.println) // prints (B)
}

abstract class Base
{
    val data4: List[A] = Nil
    val data3: List[A] = Nil
    val data2: List[A] = Nil
    val data1: List[A] = Nil

    val data0: List[A] = Nil
}

object Derived4 extends Base
{
    // error: error overriding value data4 in class Base of type scala.List[A];
    //   value data4 has incompatible type scala.List[(B.type, B.type, B.type, B.type)]
    // override val data4 = List(B,B,B,B,)

    // error: error overriding value data3 in class Base of type scala.List[A];
    //   value data3 has incompatible type scala.List[(B.type, B.type, B.type)]
    // override val data3 = List(B,B,B,)

    // error: error overriding value data2 in class Base of type scala.List[A];
    //   value data2 has incompatible type scala.List[(B.type, B.type)]
    // override val data2 = List(B,B,)

    // error: error overriding value data1 in class Base of type scala.List[A];
    //   value data1 has incompatible type scala.List[(B.type,)]
    // override val data1 = List(B,)

    // error: illegal start of simple expression
    // error: ')' expected but '}' found.
    // override val data0 = List(,)
}
Adriaan Moors | 2 May 2007 15:07
Picon

Re: Strange behaviour with invalid sequence arguments


On 02 May 2007, at 14:56, Eric Willigers wrote:

> List(B,B,B,)
> is reported as having type scala.List[(B.type, B.type, B.type)]
> and
> List(B,)
> is reported as having type scala.List[(B.type,)]
>
> Is this intentional?  What does type (B.type,) mean?
yes, this is the syntax denote unary tuple types. I.e., Tuple1[B.type]
you need the trailing comma there to differentiate from parenthesis  
that are only used for grouping

adriaan

David Pollak | 2 May 2007 15:39
Picon
Gravatar

Fwd: HOF instead of DD



---------- Forwarded message ----------
From: David Pollak <feeder.of.the.bears-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
Date: May 2, 2007 6:39 AM
Subject: Re: [scala-lounge] HOF instead of DD
To: Jamie Webb <j <at> jwebb.sygneca.com>



On 5/2/07, Jamie Webb <j <at> jwebb.sygneca.com> wrote:
On 2007-05-02 15:25:40 Tony Morris wrote:
> >> I see no legitimate reason
> >> to ever use Nothing (or Any), other than to appeal to the way Java
> >> is (and this might be a case).
> >
> > The Nothing type has nothing to do with Java.
>
> Sure it does. In Java, it is called null.

No. null is the one and only value of type Null, and Null is the least
reference type. By contrast, there are no values at all of type
Nothing. There is no Java equivalent (though the Java compiler must
surely have such a concept internally).

I believe the JVM does have the concept of Nothing... it's called void.

There are methods that can have a return type void.  The byte-code is verified such that there is no return value placed on the stack at any point that the method exits.

Thanks,

David

--
lift, the fast, powerful, easy web framework
http://liftweb.net


--
lift, the fast, powerful, easy web framework
http://liftweb.net

Gmane