math.max(a, b, c)

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
41 messages Options
123
Reply | Threaded
Open this post in threaded view
|

math.max(a, b, c)

Russ P.
I hesitate to bring this up because it is so trivial, but wouldn't it make sense for the min and max functions in scala.math to accept more than two arguments? Why not change this:

def max(x: Int, y: Int): Int

to this:

def max(x: Int*): Int

or, to force at least one argument:

def max(x: Int, y: Int*): Int

Yes, I realize there are simple ways to accomplish the same thing (e.g., List(a, b, c).max), but this would be convenient in some instances, and I assume it is trivial to implement. I have had occasion to find the min or max of three or more numbers.

While we're at it, how about

def mean(x: Double*): Double

Russ P.

--
http://RussP.us
Reply | Threaded
Open this post in threaded view
|

RE: math.max(a, b, c)

Chris Marshall
I don't think that this will be popular with those who prefer performance given the array/sequence creation overhead; although arguably they are in the minority and could roll their own functions.

Chris


Date: Fri, 7 Jan 2011 11:13:22 -0800
Subject: [scala-debate] math.max(a, b, c)
From: [hidden email]
To: [hidden email]

I hesitate to bring this up because it is so trivial, but wouldn't it make sense for the min and max functions in scala.math to accept more than two arguments? Why not change this:

def max(x: Int, y: Int): Int

to this:

def max(x: Int*): Int

or, to force at least one argument:

def max(x: Int, y: Int*): Int

Yes, I realize there are simple ways to accomplish the same thing (e.g., List(a, b, c).max), but this would be convenient in some instances, and I assume it is trivial to implement. I have had occasion to find the min or max of three or more numbers.

While we're at it, how about

def mean(x: Double*): Double

Russ P.

--
http://RussP.us
Reply | Threaded
Open this post in threaded view
|

Re: math.max(a, b, c)

Daniel Sobral
In reply to this post by Russ P.
It is not without consequence:

scala> object M {
     |   def max(xs: Int*) = xs.reduceLeft(_ max _)
     | }
defined module M

scala> List(1, 2, 3, 4, 5).reduceLeft(math.max)
res31: Int = 5

scala> List(1, 2, 3, 4, 5).reduceLeft(M.max)  
<console>:11: error: type mismatch;
 found   : (Int*) => Int
 required: (?, Int) => ?
       List(1, 2, 3, 4, 5).reduceLeft(M.max)
                                        ^


On Fri, Jan 7, 2011 at 17:13, Russ Paielli <[hidden email]> wrote:
I hesitate to bring this up because it is so trivial, but wouldn't it make sense for the min and max functions in scala.math to accept more than two arguments? Why not change this:

def max(x: Int, y: Int): Int

to this:

def max(x: Int*): Int

or, to force at least one argument:

def max(x: Int, y: Int*): Int

Yes, I realize there are simple ways to accomplish the same thing (e.g., List(a, b, c).max), but this would be convenient in some instances, and I assume it is trivial to implement. I have had occasion to find the min or max of three or more numbers.

While we're at it, how about

def mean(x: Double*): Double

Russ P.

--
http://RussP.us



--
Daniel C. Sobral

I travel to the future all the time.
Reply | Threaded
Open this post in threaded view
|

Re: math.max(a, b, c)

Rex Kerr-2
In reply to this post by Russ P.
I would prefer to have an entire numeric library a la Apache Commons math (not all of it, perhaps, but a reasonable subset).  Simply adding a max function alone does not seem to me to solve a significant number of problems since it is so easy to implement (unlike, e.g. the lnGamma function), and having it take varargs instead of an array (with possible slicing) is not obviously the way to go for performance.

  --Rex

On Fri, Jan 7, 2011 at 2:13 PM, Russ Paielli <[hidden email]> wrote:
I hesitate to bring this up because it is so trivial, but wouldn't it make sense for the min and max functions in scala.math to accept more than two arguments? Why not change this:

def max(x: Int, y: Int): Int

to this:

def max(x: Int*): Int

or, to force at least one argument:

def max(x: Int, y: Int*): Int

Yes, I realize there are simple ways to accomplish the same thing (e.g., List(a, b, c).max), but this would be convenient in some instances, and I assume it is trivial to implement. I have had occasion to find the min or max of three or more numbers.

While we're at it, how about

def mean(x: Double*): Double

Russ P.

--
http://RussP.us

Reply | Threaded
Open this post in threaded view
|

Re: RE: [scala-debate] math.max(a, b, c)

Kevin Wright-3
In reply to this post by Chris Marshall


On 7 Jan 2011 19:18, "Chris Marshall" <[hidden email]> wrote:
>
> I don't think that this will be popular with those who prefer performance given the array/sequence creation overhead; although arguably they are in the minority and could roll their own functions.
>
> Chris
>

I'd say the opposite is true. If you want this functionality then just use a fold, or Seq#max

> ________________________________
> Date: Fri, 7 Jan 2011 11:13:22 -0800
> Subject: [scala-debate] math.max(a, b, c)
> From: [hidden email]
> To: [hidden email]
>
>
> I hesitate to bring this up because it is so trivial, but wouldn't it make sense for the min and max functions in scala.math to accept more than two arguments? Why not change this:
>
> def max(x: Int, y: Int): Int
>
> to this:
>
> def max(x: Int*): Int
>
> or, to force at least one argument:
>
> def max(x: Int, y: Int*): Int
>
> Yes, I realize there are simple ways to accomplish the same thing (e.g., List(a, b, c).max), but this would be convenient in some instances, and I assume it is trivial to implement. I have had occasion to find the min or max of three or more numbers.
>
> While we're at it, how about
>
> def mean(x: Double*): Double
>
> Russ P.
>
> --
> http://RussP.us

Reply | Threaded
Open this post in threaded view
|

Re: math.max(a, b, c)

Tony Morris

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

On 08/01/11 05:23, Kevin Wright wrote:
>
>
> On 7 Jan 2011 19:18, "Chris Marshall" <[hidden email]
> [hidden email]> wrote:
>>
>> I don't think that this will be popular with those who prefer
> performance given the array/sequence creation overhead; although
> arguably they are in the minority and could roll their own
> functions.
>>
>> Chris
>>
>
> I'd say the opposite is true. If you want this functionality then
> just use a fold, or Seq#max
>
>

Abstract on the type constructor.

Scalaz has this.
https://github.com/scalaz/scalaz/blob/master/core/src/main/scala/scalaz/MA.scala#L134

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

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.10 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/

iEYEARECAAYFAk0nb1kACgkQmnpgrYe6r62LVwCfQyHVYxvsnn0H7BWCp8qqWvD4
DRwAoKIl7nOQ+O7O/z/pEvIqOT7ux1ok
=ehCq
-----END PGP SIGNATURE-----

Reply | Threaded
Open this post in threaded view
|

Re: math.max(a, b, c)

Russ P.
In reply to this post by Daniel Sobral
On Fri, Jan 7, 2011 at 11:19 AM, Daniel Sobral <[hidden email]> wrote:
It is not without consequence:

scala> object M {
     |   def max(xs: Int*) = xs.reduceLeft(_ max _)
     | }
defined module M

scala> List(1, 2, 3, 4, 5).reduceLeft(math.max)
res31: Int = 5

scala> List(1, 2, 3, 4, 5).reduceLeft(M.max)  
<console>:11: error: type mismatch;
 found   : (Int*) => Int
 required: (?, Int) => ?
       List(1, 2, 3, 4, 5).reduceLeft(M.max)
                                        ^

I think you've shown that you would lose the ability to use min or max as infix operators. Frankly, I didn't even know that was possible. Nor can I think of a reason that I would ever want to do it. If I am missing an important use case, please let me know.

Russ P.

--
http://RussP.us
Reply | Threaded
Open this post in threaded view
|

Re: math.max(a, b, c)

Razvan Cojocaru-2
I think the point is that you can no longer use it in folds, sorts etc without an intermediary lambda, thus potentially breaking tons of existing code. 

Thanks,
Razvan

On 2011-01-07, at 3:07 PM, Russ Paielli <[hidden email]> wrote:

On Fri, Jan 7, 2011 at 11:19 AM, Daniel Sobral <[hidden email]> wrote:
It is not without consequence:

scala> object M {
     |   def max(xs: Int*) = xs.reduceLeft(_ max _)
     | }
defined module M

scala> List(1, 2, 3, 4, 5).reduceLeft(math.max)
res31: Int = 5

scala> List(1, 2, 3, 4, 5).reduceLeft(M.max)  
<console>:11: error: type mismatch;
 found   : (Int*) => Int
 required: (?, Int) => ?
       List(1, 2, 3, 4, 5).reduceLeft(M.max)
                                        ^

I think you've shown that you would lose the ability to use min or max as infix operators. Frankly, I didn't even know that was possible. Nor can I think of a reason that I would ever want to do it. If I am missing an important use case, please let me know.

Russ P.

--
http://RussP.us
Razvan Cojocaru,
Work: http://www.sigma-systems.com
Playground: http://wiki.homecloud.ca
Latest cool toys: Scripster and Gremlins
Follow me: RSS Feed, Twitter, GitHub.
Reply | Threaded
Open this post in threaded view
|

Re: math.max(a, b, c)

Dennis Haupt-2
one could define max(a,b,c*) in addition to the existing max(a,b)

Am 09.01.2011 14:37, schrieb Razvan Cojocaru:
I think the point is that you can no longer use it in folds, sorts etc without an intermediary lambda, thus potentially breaking tons of existing code. 

Thanks,
Razvan

On 2011-01-07, at 3:07 PM, Russ Paielli <[hidden email]> wrote:

On Fri, Jan 7, 2011 at 11:19 AM, Daniel Sobral <[hidden email]> wrote:
It is not without consequence:

scala> object M {
     |   def max(xs: Int*) = xs.reduceLeft(_ max _)
     | }
defined module M

scala> List(1, 2, 3, 4, 5).reduceLeft(math.max)
res31: Int = 5

scala> List(1, 2, 3, 4, 5).reduceLeft(M.max)  
<console>:11: error: type mismatch;
 found   : (Int*) => Int
 required: (?, Int) => ?
       List(1, 2, 3, 4, 5).reduceLeft(M.max)
                                        ^

I think you've shown that you would lose the ability to use min or max as infix operators. Frankly, I didn't even know that was possible. Nor can I think of a reason that I would ever want to do it. If I am missing an important use case, please let me know.

Russ P.

--
http://RussP.us

Reply | Threaded
Open this post in threaded view
|

Re: math.max(a, b, c)

Kevin Wright-3


On 9 January 2011 13:53, HamsterofDeath <[hidden email]> wrote:
one could define max(a,b,c*) in addition to the existing max(a,b)


Overloading comes with its own unique issues though, so I wouldn't be too hasty in doing this.

 
Am 09.01.2011 14:37, schrieb Razvan Cojocaru:
I think the point is that you can no longer use it in folds, sorts etc without an intermediary lambda, thus potentially breaking tons of existing code. 

Thanks,
Razvan

On 2011-01-07, at 3:07 PM, Russ Paielli <[hidden email]> wrote:

On Fri, Jan 7, 2011 at 11:19 AM, Daniel Sobral <[hidden email]> wrote:
It is not without consequence:

scala> object M {
     |   def max(xs: Int*) = xs.reduceLeft(_ max _)
     | }
defined module M

scala> List(1, 2, 3, 4, 5).reduceLeft(math.max)
res31: Int = 5

scala> List(1, 2, 3, 4, 5).reduceLeft(M.max)  
<console>:11: error: type mismatch;
 found   : (Int*) => Int
 required: (?, Int) => ?
       List(1, 2, 3, 4, 5).reduceLeft(M.max)
                                        ^

I think you've shown that you would lose the ability to use min or max as infix operators. Frankly, I didn't even know that was possible. Nor can I think of a reason that I would ever want to do it. If I am missing an important use case, please let me know.

Russ P.

--
http://RussP.us




--
Kevin Wright

gtalk / msn : [hidden email]
[hidden email]mail: [hidden email]
vibe / skype: kev.lee.wright
twitter: @thecoda

Reply | Threaded
Open this post in threaded view
|

Re: math.max(a, b, c)

Dennis Haupt-2
give it another name: maxOf(a,b*) :D

Am 09.01.2011 15:18, schrieb Kevin Wright:


On 9 January 2011 13:53, HamsterofDeath <[hidden email]> wrote:
one could define max(a,b,c*) in addition to the existing max(a,b)


Overloading comes with its own unique issues though, so I wouldn't be too hasty in doing this.

 
Am 09.01.2011 14:37, schrieb Razvan Cojocaru:
I think the point is that you can no longer use it in folds, sorts etc without an intermediary lambda, thus potentially breaking tons of existing code. 

Thanks,
Razvan

On 2011-01-07, at 3:07 PM, Russ Paielli <[hidden email]> wrote:

On Fri, Jan 7, 2011 at 11:19 AM, Daniel Sobral <[hidden email]> wrote:
It is not without consequence:

scala> object M {
     |   def max(xs: Int*) = xs.reduceLeft(_ max _)
     | }
defined module M

scala> List(1, 2, 3, 4, 5).reduceLeft(math.max)
res31: Int = 5

scala> List(1, 2, 3, 4, 5).reduceLeft(M.max)  
<console>:11: error: type mismatch;
 found   : (Int*) => Int
 required: (?, Int) => ?
       List(1, 2, 3, 4, 5).reduceLeft(M.max)
                                        ^

I think you've shown that you would lose the ability to use min or max as infix operators. Frankly, I didn't even know that was possible. Nor can I think of a reason that I would ever want to do it. If I am missing an important use case, please let me know.

Russ P.

--
http://RussP.us




--
Kevin Wright

gtalk / msn : [hidden email]
mail: [hidden email]
vibe / skype: kev.lee.wright
twitter: @thecoda


Reply | Threaded
Open this post in threaded view
|

Re: math.max(a, b, c)

Nils Kilden-Pedersen
In reply to this post by Kevin Wright-3
On Sun, Jan 9, 2011 at 8:18 AM, Kevin Wright <[hidden email]> wrote:


On 9 January 2011 13:53, HamsterofDeath <[hidden email]> wrote:
one could define max(a,b,c*) in addition to the existing max(a,b)


Overloading comes with its own unique issues though, so I wouldn't be too hasty in doing this.

You mean in general, or for the specific case given?

Reply | Threaded
Open this post in threaded view
|

Re: math.max(a, b, c)

Kevin Wright-3


On 9 January 2011 15:10, Nils Kilden-Pedersen <[hidden email]> wrote:
On Sun, Jan 9, 2011 at 8:18 AM, Kevin Wright <[hidden email]> wrote:


On 9 January 2011 13:53, HamsterofDeath <[hidden email]> wrote:
one could define max(a,b,c*) in addition to the existing max(a,b)


Overloading comes with its own unique issues though, so I wouldn't be too hasty in doing this.

You mean in general, or for the specific case given?


In general.  It's like going overboard on inheritance, I find that avoiding it tends to leads towards better designs.


--
Kevin Wright

gtalk / msn : [hidden email]
[hidden email]mail: [hidden email]
vibe / skype: kev.lee.wright
twitter: @thecoda

Reply | Threaded
Open this post in threaded view
|

Re: math.max(a, b, c)

Martin Odersky
I don't see the need for n-ary max, given that we have infix max.

math.max(1, 2, 3)

would be neither shorter nor more legible or more efficient than

1 max 2 max 3

Cheers

 -- Martin


Reply | Threaded
Open this post in threaded view
|

Re: math.max(a, b, c)

Dennis Haupt-2
you win, i forgot that one. i answered hastily.

Am 09.01.2011 16:35, schrieb martin odersky:

> I don't see the need for n-ary max, given that we have infix max.
>
> math.max(1, 2, 3)
>
> would be neither shorter nor more legible or more efficient than
>
> 1 max 2 max 3
>
> Cheers
>
>  -- Martin
>
>

Reply | Threaded
Open this post in threaded view
|

Re: math.max(a, b, c)

Nils Kilden-Pedersen
In reply to this post by Martin Odersky
On Sun, Jan 9, 2011 at 9:35 AM, martin odersky <[hidden email]> wrote:
I don't see the need for n-ary max, given that we have infix max.

math.max(1, 2, 3)

would be neither shorter nor more legible or more efficient than

1 max 2 max 3

Doesn't the infix require the construction of a RichInt on every invocation, or is infix max compiler optimized?
Reply | Threaded
Open this post in threaded view
|

Re: math.max(a, b, c)

Dennis Haupt-2
afaik the vm should be able to optimize the allocation away (escape analysis). but i never tested it.

Am 09.01.2011 18:35, schrieb Nils Kilden-Pedersen:
On Sun, Jan 9, 2011 at 9:35 AM, martin odersky <[hidden email]> wrote:
I don't see the need for n-ary max, given that we have infix max.

math.max(1, 2, 3)

would be neither shorter nor more legible or more efficient than

1 max 2 max 3

Doesn't the infix require the construction of a RichInt on every invocation, or is infix max compiler optimized?

Reply | Threaded
Open this post in threaded view
|

Re: math.max(a, b, c)

Rex Kerr-2
Rich max is not free, even with escape analysis:

java -XX:+DoEscapeAnalysis -cp /usr/share/scala/2.8/lib/scala-library.jar:. TwoMax
//(warmup elided)
Iteration 3
Infix Elapsed: 1.612 seconds
  Checksum = 661242756
Prefix Elapsed: 0.929 seconds
  Checksum = 661242756
If Elapsed: 0.929 seconds
  Checksum = 661242756

java -cp /usr/share/scala/2.8/lib/scala-library.jar:. TwoMax
//(warmup elided)
Iteration 3
Infix Elapsed: 4.574 seconds
  Checksum = 661242756
Prefix Elapsed: 0.922 seconds
  Checksum = 661242756
If Elapsed: 0.922 seconds
  Checksum = 661242756

Infix is (i max j), prefix is math.max(i,j), and if is (if (i<j) j else i).  (Code attached.)

Max of three shows exactly what you'd expect given the results for two.

  --Rex



On Sun, Jan 9, 2011 at 1:00 PM, HamsterofDeath <[hidden email]> wrote:
afaik the vm should be able to optimize the allocation away (escape analysis). but i never tested it.

Am 09.01.2011 18:35, schrieb Nils Kilden-Pedersen:
On Sun, Jan 9, 2011 at 9:35 AM, martin odersky <[hidden email]> wrote:
I don't see the need for n-ary max, given that we have infix max.

math.max(1, 2, 3)

would be neither shorter nor more legible or more efficient than

1 max 2 max 3

Doesn't the infix require the construction of a RichInt on every invocation, or is infix max compiler optimized?



TwoMax.scala (1K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: math.max(a, b, c)

Tony Morris
In reply to this post by Dennis Haupt-2

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

On 09/01/11 23:53, HamsterofDeath wrote:
> one could define max(a,b,c*) in addition to the existing max(a,b)
>


It can be generalised.

trait Semigroup[A] {
    def app(a1: A, a2: A): A

     def fold1[F[_]](as: F[A])(f: Foldable[F]): A =
        as.reduceRight(app)
}

case class Max(n: Int)

object Semigroup {
    implicit def MaxSemigroup = new Semigroup[Max] {
        def app(a1: Max, a2: Max) = Max(a1.n max a2.n)

        def fold1[F[_]](as: F[Max])(implicit f: Foldable[F]): Max =
            as.reduceLeft(app) // optimised
    }
}

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

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.10 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/

iEYEARECAAYFAk0qH/sACgkQmnpgrYe6r61zKwCfaMhnVXRI/8HmPvlly7ju6vCK
7ukAn0H553GcJO3mzt1WoMIOvQ3x/qaQ
=vy/V
-----END PGP SIGNATURE-----

Reply | Threaded
Open this post in threaded view
|

Re: math.max(a, b, c)

Dennis Haupt-2
In reply to this post by Rex Kerr-2
same here, except that the code gets executed faster in the first 2 iterations, then becomes slower. no idea why.
the infix version is probably slower because of some random overhead that's left after optimizing the object allocations away. -verbose:gc doesn't print anything at all.

Iteration 1
Infix Elapsed: 1,491 seconds
  Checksum = 661242756
Prefix Elapsed: 0,855 seconds
  Checksum = 661242756
If Elapsed: 1,168 seconds
  Checksum = 661242756

Iteration 2
Infix Elapsed: 1,484 seconds
  Checksum = 661242756
Prefix Elapsed: 0,853 seconds
  Checksum = 661242756
If Elapsed: 1,167 seconds
  Checksum = 661242756

Iteration 3
Infix Elapsed: 1,666 seconds
  Checksum = 661242756
Prefix Elapsed: 0,848 seconds
  Checksum = 661242756
If Elapsed: 0,847 seconds
  Checksum = 661242756

Iteration 4
Infix Elapsed: 1,668 seconds
  Checksum = 661242756
Prefix Elapsed: 0,847 seconds
  Checksum = 661242756
If Elapsed: 0,847 seconds
  Checksum = 661242756

Iteration 5
Infix Elapsed: 1,667 seconds
  Checksum = 661242756
Prefix Elapsed: 0,848 seconds
  Checksum = 661242756
If Elapsed: 0,846 seconds
  Checksum = 661242756

Iteration 6
Infix Elapsed: 1,665 seconds
  Checksum = 661242756
Prefix Elapsed: 0,847 seconds
  Checksum = 661242756
If Elapsed: 0,848 seconds
  Checksum = 661242756


Am 09.01.2011 20:29, schrieb Rex Kerr:
Rich max is not free, even with escape analysis:

java -XX:+DoEscapeAnalysis -cp /usr/share/scala/2.8/lib/scala-library.jar:. TwoMax
//(warmup elided)
Iteration 3
Infix Elapsed: 1.612 seconds
  Checksum = 661242756
Prefix Elapsed: 0.929 seconds
  Checksum = 661242756
If Elapsed: 0.929 seconds
  Checksum = 661242756

java -cp /usr/share/scala/2.8/lib/scala-library.jar:. TwoMax
//(warmup elided)
Iteration 3
Infix Elapsed: 4.574 seconds
  Checksum = 661242756
Prefix Elapsed: 0.922 seconds
  Checksum = 661242756
If Elapsed: 0.922 seconds
  Checksum = 661242756

Infix is (i max j), prefix is math.max(i,j), and if is (if (i<j) j else i).  (Code attached.)

Max of three shows exactly what you'd expect given the results for two.

  --Rex



On Sun, Jan 9, 2011 at 1:00 PM, HamsterofDeath <[hidden email]> wrote:
afaik the vm should be able to optimize the allocation away (escape analysis). but i never tested it.

Am 09.01.2011 18:35, schrieb Nils Kilden-Pedersen:
On Sun, Jan 9, 2011 at 9:35 AM, martin odersky <[hidden email]> wrote:
I don't see the need for n-ary max, given that we have infix max.

math.max(1, 2, 3)

would be neither shorter nor more legible or more efficient than

1 max 2 max 3

Doesn't the infix require the construction of a RichInt on every invocation, or is infix max compiler optimized?



123