Eric Kolotyluk | 9 Feb 10:13
Picon
Gravatar

2012 Programming Competition

I was wondering if there were any people interested in a friendly little programming competition with a real cash reward.
  1. We need some judges. I plan on putting up some of the money so I would like to be one of the judges. Since I am still a relative Scala neophyte my judging would focus on how a newbie values the results. It would be nice to get some other credible judges to focus on other issues, maybe 3 more, possibly some well known or famous judges like that, what's his name, Odersky or something ;-) Seriously Martin it would be excellent if you could participate.
  2. We need some judging criteria and I invite people to suggest some criteria such as readability, robustness, performance, elegance, innovation, usability, etc. or maybe something more detailed or interesting.
  3. We need goal. I have a smallish application I use when learning a new language and comparing language features. I have implemented the same application in C#/WPF, Java/Swing and Java FX Script. I will not reveal the details of the application now, but I plan to write a sufficient set of requirements/specifications. However, the application has be written before in a single file of code without too much trouble so one requirement will be that it has to be a Scala FX application in a single file. This is obviously a GUI application and concurrent programming will be an issue, and scalability on multi-core systems would be a nice to have. Maybe there would be extra credit for effective use of continuations.
  4. We need contestants willing put their code before the community as the best example. This should not take more 40 hours of effort, but could be much much less for proficient coders and people would have two weeks elapsed time to complete their submission after the requirements are broadcast.
  5. We need testers willing to verify program correctness and requirements coverage in support of the judges.
  6. We need a prize. I am willing to put up to $512 USD (possibly more if there is enough excitement). I welcome other sponsors as well to give our challengers some incentive. Cash pledges should be a power of 2 USD. Maybe we can come up with a cool certificate as well, or more than one prize.
What say you all - are you interested in a little bit fun?

Cheers, Eric
Liu Yongjian | 4 Feb 16:44
Picon

http://stackoverflow.com/questions/8891732/can-we-define-a-set-of-dsl-operation-in-scala-that-perform-parallelly-with-each

This is a question I posted on stackflow.com

Ryan Hendrickson | 2 Feb 17:39
Favicon

Optional parameters (a language proposal)

Hi all!

I've been kicking around this idea for an addition to Scala's core syntax for about a month, and I've started work on a patch to the compiler to implement it. I'd very much like to see if anyone else besides me has any interest in/feedback on this idea, and hopefully to promote it to a SIP.

In a nutshell: I want to allow optional parameters (kind of like default arguments, but different—complementary to them, in a sense) to functions, that behave like Option the same way that repeated/vararg parameters behave like Seq. This arises from a problem (of the class ‘useful, but could be more useful’) I have with default arguments. Read on for an explanation of the problem and what I'm trying to do about it.

(Apologies if something like this came up and was rejected when default arguments were being proposed for 2.8. I'm pretty new to the Scala community, and while I read back through most of the scala-debate archives and didn't see any discussion of a feature like this, I'm well aware that I could have just missed it.)

1 Motivation

Suppose you have a service that looks like this:

class CookieBaker { def bakeCookies(quantity: Int, flavor: CookieFlavors.Value = CookieFlavors.ChocolateChip) = sys.error("Not implemented yet...") }

The fact that the default flavor is chocolate chip is an implementation detail of the baker. Callers don't need to know it, and the CookieBaker class could change the flavor at any time without having to change other code that truly is agnostic to the flavor of cookies produced. This is as it should be.

Now consider another class that uses CookieBaker:

class KitchenManager(cookieBaker: CookieBaker, cakeBaker: CakeBaker) { def bakeForParty(partySize: Int, cookieFlavor: CookieFlavors.Value = CookieFlavors.ChocolateChip) { cookieBaker.bakeCookies(partySize*3, cookieFlavor) cakeBaker.bakeCakes(partySize/4) } }

Now we are in trouble: we have redundantly specified that the default cookie flavor is chocolate chip in two separate classes. Maybe that's okay; it could be that in the domain of this problem, the KitchenManager and the CookieBaker separately have independent ideas about what the default cookie flavor should be (and at the moment, they happen to coincide). But let's assume in this case, if the KitchenManager is not told what cookie flavor to provide, it would prefer to defer to the CookieBaker.

So you can revise KitchenManager in a couple of different ways, none of which are great:

class KitchenManager(cookieBaker: CookieBaker, cakeBaker: CakeBaker) { def bakeForParty(partySize: Int, cookieFlavor: Option[CookieFlavors.Value]) { cookieFlavor match { case Some(flavor) => cookieBaker.bakeCookies(partySize*3, flavor) case None => cookieBaker.bakeCookies(partySize*3) } cakeBaker.bakeCakes(partySize/4) } }
class KitchenManager(cookieBaker: CookieBaker, cakeBaker: CakeBaker) { def bakeForParty(partySize: Int, cookieFlavor: CookieFlavors.Value) { cookieBaker.bakeCookies(partySize*3, cookieFlavor) cakeBaker.bakeCakes(partySize/4) } def bakeForParty(partySize: Int) { cookieBaker.bakeCookies(partySize*3) cakeBaker.bakeCakes(partySize/4) } }

(If I'm missing a very clean way to do this in existing Scala, please let me know!)

The first solution is a little ugly to call (callers have to use Some or None, which is both extra clutter and not consistent with the more lightweight calling pattern for CookieBaker), and a little ugly to implement (you have to call cookieBaker.bakeCookies in both cases of the match, with very similar arguments—and about the only thing you can factor out of this would be a def quantity = partySize*3, which certainly doesn't make the method much easier to read). You could solve the first of these problems with implicits and either some new Optional trait which is a dumb wrapper for an Option (sad) or implicit conversions to/from Option itself (potentially a source of bugs/confusion elsewhere!); but I think the second problem is basically intractable (and grows exponentially with the number of default arguments under consideration!).

The second solution is ideal to call, but has the same redundancy/exponential code growth problems as the first, and what's worse, the growth affects actual method overloads rather than case clauses isolated inside a single method. Plus, it feels plain dirty to use default arguments at one layer of the software, and overloads at another, when talking about the same thing threaded between the two layers.

There are other hacks: you could use (shudder) null as the default argument to KitchenManager, and trust that null doesn't have some special significance to some other part of the software. You could, if you can edit the CookieFlavors enum, give it a Default value, but then everything that ever takes a CookieFlavors.Value would have to define what to do if given a Default. None of these solutions feel good and Scala-ish to me.

Here's the code I'd like to write (the bold red bits are new syntax that this language proposal would enable):

class KitchenManager(cookieBaker: CookieBaker, cakeBaker: CakeBaker) { def bakeForParty(partySize: Int, cookieFlavor: CookieFlavors.Value?) { cookieBaker.bakeCookies(partySize*3, cookieFlavor:_?) cakeBaker.bakeCakes(partySize/4) } } myKitchenManager.bakeForParty(5) myKitchenManager.bakeForParty(10, CookieFlavors.Sugar) val optFlavor: Option[CookieFlavors.Value] = getCookieFlavorPreference myKitchenManager.bakeForParty(15, optFlavor:_?)

If it isn't obvious what the new ? syntax is intended to mean, consider it analogous to the * character in repeated parameters:

‘*’ is to scala.Seq as ‘?’ is to scala.Option

Just like * lets callers provide zero or more arguments for a parameter, which get wrapped up in a Seq, ? is intended to let callers provide zero or one arguments for a parameter, which gets wrapped up in an Option. The remainder of this document hammers out in pedantic detail what this means technically, but hopefully that analogy tells you enough to be able to understand the code and form an opinion on whether Scala would be better off with this feature.

Incidentally, I think of this improvement as two mostly independent features: optional parameters (the ability to declare a parameter with type T? as sugar for Option[T], with the feature that such parameters expect an argument of type T which may be missing) and option arguments (the ability to call a method expecting arguments of type T using arguments of type Option[T], if the language knows what to do if that argument is missing). The next two sections describe each of these separately, though their utility and the spirit of the */? analogy is I think most evident when both are considered together.

2 Optional Parameters

This proposed feature provides for the declaration/definition of functions with optional parameters with a syntax analogous to repeated parameters. The proposal builds on the work done with default arguments for Scala 2.8.

Parameter types can be suffixed with ‘?’ to indicate that a parameter is optional. Just as the type of a repeated parameter (annotated with T*) in the definition of the function is scala.Seq[T], the type of an optional parameter (annotated with T?) in the definition of the function is scala.Option[T]. When applying a function with one or more optional parameters, overload resolution, implicit conversions, and parameter binding proceed exactly as if each optional parameter a: T? were actually declared with a default argument as a: T = undefined, where undefined is a fictitious term of type T. After binding has succeeded, if optional parameter a is bound to an expression expr, that expression is lifted to scala.Some(expr); if a is not bound (where, for an ordinary parameter with a default argument, the compiler would insert a call to the default), the binding a = scala.None: Option[T] is used.

A function declaration/definition with optional parameters is valid if and only if the equivalent function with all optional parameters a: T? replaced with a: T = undefined would be valid. In particular, it is allowed to declare any number of optional or non-optional parameters in any order in a parameter section, but it is not allowed to have a parameter section with both optional parameters and a repeated parameter.

2.1 Syntax

The production of ParamType in SLS 2.9 chapter 4 is extended with the following clauses:

ParamType ::= Type ‘?’ | ‘=>’ Type ‘?’

2.2 Integration with other features

By-Name Parameters An optional parameter declared with the by-name arrow ‘=>’ works such that every usage of the parameter within the body of the function re-evaluates the lifted argument expression (scala.Some(expr) or scala.None, depending).

Default Arguments Works exactly as if the optional parameter a: T? were declared as a: T = undefined. An optional parameter may not be declared with a default argument itself, but within a single parameter section, optional parameters and parameters with default arguments may coexist.

Implicit Parameters If an optional parameter a: T? is implicit, an implicit value matching T (not scala.Option[T]) is searched for. If an implicit value v matching T is found, the value of a inside the function is scala.Some(v); if none is found, the value of a inside the function is scala.None.

Overloading For the purpose of determining whether a member definition matches another (per definition 5.1.4 in SLS 2.9), an optional parameter a: T? is considered to have type Option[T]. In addition, at most one overloaded alternative of a method is allowed to have default arguments or optional parameters (or both).

Overloading Resolution As with default arguments, when multiple overloaded alternatives are applicable, the alternative which uses optional parameters is never selected.

Overriding If a member M matches a non-private member M′ of a base class, then in addition to the existing restrictions on M and M′ defined in section 5.1.4 of SLS 2.9, this additional restriction applies to M: a parameter of M must be optional if and only if it corresponds to an optional parameter of M′. (In other words, even though the definition of matching is amended to define T? to be equivalent to Option[T], a T? parameter cannot be overridden with an Option[T] parameter or vice versa.)

Repeated Parameters As with default arguments, repeated parameters and optional parameters may not coexist in a parameter section.

2.3 Example

The following code is a trivial use of optional parameters:

def show(i: Int?) = i match { case Some(value) => println("i = " + value) case None => println("i is unspecified") } show(5) // prints "i = 5" show() // prints "i is unspecified"

It is semantically equivalent to the following Scala 2.9 code:

def show(i: Option[Int]) = i match { case Some(value) => println("i = " + value) case None => println("i is unspecified") } show(Some(5)) show(None)

3 Option Arguments

This proposed feature provides for using a scala.Option[T] to determine at runtime whether to ‘take the default’ when calling a function with a parameter of type T that is either optional or has a default argument.

Analogously to the existing sequence argument feature, an expression of type scala.Option[T] can be marked to be an option argument with a _? type annotation. For the purposes of resolving overloads and parameter binding, option arguments are taken to have type T, except that an option argument can only be considered compatible with optional parameters or parameters with default arguments; all other rules apply as usual. If the option argument expr: Option[T] is successfully bound to a parameter a: T = default, then the actual value of a in the function is expr.getOrElse(default). If the option argument is successfully bound to an optional parameter a: T?, then the actual value of a in the function is expr (skipping the usual lifting performed for optional parameters as described in section 2 of this proposal).

3.1 Syntax

The production of ArgumentExprs as defined in chapter 6 of SLS 2.9 is amended to the following:

ArgumentExprs ::= ‘(’ [Exprs1] ‘)’ | ‘(’ [Exprs ‘,’] PostfixExpr ‘:’ ‘_’ ‘*’ ’)’ | [nl] BlockExpr Exprs1 ::= Expr [‘:’ ‘_’ ‘?’] {‘,’ Expr [‘:’ ‘_’ ‘?’] }

Note that, for instance, someFunc(a:_?, b:_*) is syntactically invalid (and could never match a real function anyway, as repeated parameters and default argument/optional parameters can't coexist in a parameter section).

3.2 Integration with other features

By-Name Parameters An option argument to a function with a by-name parameter works such that every usage of the parameter within the body of the function re-evaluates the unlifted argument expression or the entire expr.getOrElse(default) expression, depending on whether the parameter is optional or has a default argument.

Overloading Resolution Because only one overload alternative can use default arguments or optional parameters, when applying an overloaded function with option arguments, only that alternative is considered for applicability. Option arguments do not allow for runtime switching between different overload alternatives.

3.3 Example

Continuing the example from 2.3:

val three = Some(3) show(three:_?) // same as show(3) show(None:_?) // same as show()
---------------------------------------- This message is intended exclusively for the individual(s) or entity to which it is addressed. It may contain information that is proprietary, privileged or confidential or otherwise legally exempt from disclosure. If you are not the named addressee, you are not authorized to read, print, retain, copy or disseminate this message or any part of it. If you have received this message in error, please notify the sender immediately by e-mail and delete all copies of the message.
Eric Kolotyluk | 31 Jan 09:40
Picon
Gravatar

Addicted to Pattern Matching

When I first started trying to learn Scala a few years ago there was so 
much hype in the documentation about how wonderful pattern matching was, 
but I didn't really pay much attention to it as I could not get a feel 
for the utility of it.

Now that I have been writing more product code in Scala, increasingly I 
find myself using match/case so much now that I am getting addicted to 
it. In fact I am increasingly finding new ways to make use of it and new 
ways to structure my code to make better use of it - for example 
creating case classes for function results.

Yesterday I started using regular expressions in Scala for the first 
time, and I really like how well they work with match/case.

Another thing I really like is that pattern matching can improve the 
readability of the code substantially. Sometimes if you take the time to 
set up your pattern matching code the problem and solution just jump 
right out at you.

One disappointment was I could not seem to get pattern matching to work 
well with arrays, such as Array[String]. I found various examples on the 
web, but could not seem to get any of them working. Fortunately 
converting Array[String] to List[String] is trivial, and lists work 
great with pattern matching. I always prefer working with lists, but all 
programs start with main(arguments : Array[String]).

Has anyone else found themselves getting addicted to pattern matching? 
Now when I promote Scala to others at work and elsewhere I'll be 
spending more time on the joys of pattern matching.

Does anyone know of a really good treatment of pattern matching from the 
basics to more sophisticated stuff - preferably with tons of examples?

Are there plans to add further enhancements to pattern matching in Scala?

Cheers, Eric

Ben Hutchison | 30 Jan 23:04
Picon
Gravatar

Re: An idea for reducing typeclass-related boilerplate

(returning to scala-debate after accidentally straying off-list)

On Tue, Jan 31, 2012 at 2:49 AM, Erik Osheim <erik <at> plastic-idolatry.com> wrote:
> On Tue, Jan 31, 2012 at 12:15:34AM +1100, Ben Hutchison wrote:
>> While it's possible to use the same typeclass twice in a method for
>> different types, I think its uncommon. I've not encountered code like
>> your example - why do you bring 2 numerics of unrelated type together
>> and want to operate on both?

> In the case I'm talking about there'd be conflicts around things like
> Numeric[A].fromInt(i:Int):A versus Numeric[B].fromInt(i:Int):B as well
> as Numeric[A].zero:A versus Numeric[B].zero:B. In fact, I have existing
> code that would be affected by this feature. So it's not a hypothetical
> or a thought experiment.
>
> To be clear, I'm not talking about situations where you want to call a
> method on "t" but rather where you need to call a method on "T".

Right. Generally, "constructors" provided by type classes.

I agree the the imports-of-parameters syntax doesn't have a neat
answer for ambiguous constructors. However, Pavel's proposal also has
problems with ambiguity when multiple typeclasses have a member with
the same name. Eg how could this (admittedly contrived) example be
resolved (using the syntax outlined by Pavel in the first post of the
thread):

trait Parser[A] {def parse(s: String): A}
trait Reader[A] {def parse(s: String): A}

def example[A: Parser, Reader](a: A) = {
  //want to invoke both the 'parse' methods of Reader and Parser, but
can't distinguish
  A.parse(a) +A.parse(a)
}

-Ben

Dan Rosen | 30 Jan 21:23
Picon
Gravatar

memoized functions / methods

I've been thinking about submitting a new SIP, but I want to get a sanity check and some help first...  I would like to be able to memoize the results of referentially transparent functions / methods.  I can do this manually by implementing some caching strategy encapsulated in, say, a MemoizedFunction[-T, +R]...  But that feels unsatisfying; I want language support.


For memoizing methods, I'd propose a new keyword: 'memo' (as in 'memo def', analogous to 'lazy val').  The semantics of "memo def f(a_1: T_1, a_2: T_2, ..., a_n: T_N): R" would be twofold: statically, the transitive closure of all functions called by 'f' must be referentially transparent; and dynamically, the result of invoking 'f' on some arguments (a_1..a_n) would be equivalent to getOrElseUpdate on some in-memory cache (the size of which is, let's say, implementation-dependent) using the tuple of those arguments as the key.  Note that although 'f' will not likely be synchronized (because why would you synchronize a method without side effects?) the getOrElseUpdate implementation would nevertheless require synchronization.

For memoizing functions, I have to admit my proposal is a bit more nebulous...  I think a MemoizedFunction trait is a good idea, and I'd suggest that the eta expansion of a 'memo def' should produce a MemoizedFunction.  But there are a couple things that are unclear to me:

  - In the case of 'val f = new MemoizedFunction[A, B] { def apply(a: A): B = .... }', the compiler would need to inspect the 'apply' method body to analyze for referential transparency, and I don't necessarily like the idea that the compiler would need to treat any library type as special...

  - In the case of 'val f: A => B = { a => ... }', how to indicate syntactically that the anonymous function is referentially transparent?

A couple other scattered thoughts I had, that might be worth mentioning:

  - It's probably a good idea to allow interchangeable caching strategies.  For example, assume users might want to use a cache tuned for their application (such as ehcache).  I figure a 'Cache' typeclass with a sensible default 'implicit val' provided in predef would be the way to go.

  - I worry about the performance cost of this proposal, because it conflates the notion of referential transparency (and being able to reason about it statically) with the runtime strategy of caching results.  For example, if I define 'memo def plus(a: Int, b: Int): Int = a + b', the proposal would say that Int.+() needs to be declared as 'memo def' and consequently cached.  It may be that keeping the two concerns separate is better, so that Int.+() can be annotated as idempotent but without incurring runtime space penalty.

Thoughts?
dr
Paul Phillips | 29 Jan 06:17

invariant ordering vs. refinement lubs

Since I know nobody could possibly be tired of this subject, and also
I didn't know what else to do with my test case.

class A { def f: Any }
class B extends A { def f: Int = 5 }
class C extends A { def f: Long = 5L }

object Test {
  def hello[T: Ordering](t1: T, t2: T) = ???

  implicit val AOrdering: Ordering[A] = ???

  hello(new B, new C)
  // ./a.scala:11: error: No implicit Ordering defined for A{def f: AnyVal}.
  //   hello(new B, new C)
  //        ^

  hello(new B, new C)(AOrdering)
  // ./a.scala:13: error: type mismatch;
  //  found   : Ordering[A]
  //  required: Ordering[A{def f: AnyVal}]
  // Note: A >: A{def f: AnyVal}, but trait Ordering is invariant in type T.
  // You may wish to investigate a wildcard type such as `_ >: A{def
f: AnyVal}`. (SLS 3.2.10)
  //   hello(new B, new C)(AOrdering)
  //                       ^

  hello[A](new B, new C)
  // that works of course
}

Ant Kutschera | 28 Jan 11:16
Picon

Actors, MapReduce and Java EE app servers

Hi,

Actors can be used to break tasks down into smaller chunks and process
them on multiple cores, or even multiple machines via remote actors.
Additionally, they can wrap mutable data, so you don't need to write
your own locking mechanisms on such data.

MapReduce in systems like Apache Hadoop break tasks down into smaller
chunks and process them on multiple cores, on multiple servers, but
have the benefit over actors that they work with distributed file
systems and databases, so out of the box you have persistence.  So far
as I know, Hadoop does not help with locking on mutable data.

Java EE application servers don't break work down into little tasks,
rather each single request (through say a call to a web service being
hosted on the app server) is a "little" task.  Once there is enough
load on the server (i.e. enough calls to the web service), the work is
evenly distributed across multiple cores.  You can deploy to a cluster
to scale out and have the processing done on multiple machines.

The question is: If I can choose between Java EE, MapReduce and
Actors, would I find that the only real "use case" for using Actors
would be pretty much only when I want to avoid locking on mutable
data?

If that is the case, then why do I read about people using Akka to
support the back end of web servers, and why did someone invest time
to create remote actors, without building a distributed file system?

Cheers,
Ant

Pavel Pavlov | 21 Jan 16:08
Picon
Gravatar

An idea for reducing typeclass-related boilerplate

Hi all,

Just have an idea how to make code which uses typeclasses better.
Consider an example:

def sum[T : Integral](list: List[T]): T = {
   
val integral = implicitly[Integral[T]]
   
import integral._
    list.foldLeft(integral.zero)(_ + _)
}

I suppose this is verbose and ugly. The alternative which do not use context bound is not good as well:

def sum[T](list: List[T])(implicit integral: Integral[T]): T = {
   
import integral._
    list.foldLeft(integral.zero)(_ + _)
}

In fact, what do we want here is to call `zero` method from something that is `Integral`.
Context bound syntax clearly expresses that T is Integral here.
With another bit of syntaxic sugar we can express our intensions straightforwardly:

def sum[T : Integral](list: List[T]): T = {
    list.foldLeft(T.zero)(_ + _)
}

As I can see now such syntax does not conflict with anything.
For me it's clear, easy to read and more 'high-level".
It hides the remaining typeclass implementation details (some of them are already hidden by context bound syntax) from the user.

What do you think?

Regards,
Pavel
Scala Mailing Lists | 21 Jan 15:32
Picon
Picon
Favicon
Gravatar

Mailing list reminder: Scala-debate

Welcome to the "Scala-debate" mailing list.

This automatic reminder is sent once a month to the list,
to keep subscribers up-to-date with the mailing list services,
and to help keeping the list on topic.

-------------------------------------------------------------------

The "Scala-debate" mailing list:

This list is a more relaxed forum for Scala discussions
that would probably be off-topic or too convoluted for
the other lists, but that may still be quite interesting
to follow for a selected readership.

In particular, the following are appropriate:

  * threads that evolved beyond their initial topic,
      and have become too long or convoluted to be
      of interest to most readers
  * threads discussing extremely specialized topics
  * threads that are mostly speculative in nature,
      out-of-the-box thinking, philosophical views
      (as long as they are still somehow related
      to Scala)
  * debates (of course)

The "Scala-debate" list is the natural destination of all
the threads that start on other mailing lists, but are no
longer on topic on their original list, or have turned
into an in-depth debate about something.

-------------------------------------------------------------------

Other information:

There are several Scala lists devoted to individual topics (and
more may be created in the future). For the full list, please
see: http://www.scala-lang.org/node/199

Try to avoid cross-posting whenever possible. If you can, select
the list that is closer to your topic and post in that list only.
In any case, never cross-post replies.

If you ever want to unsubscribe from this list, just visit this
page: http://groups.google.com/group/scala-debate/subscribe
or send an email to scala-debate+unsubscribe <at> googlegroups.com

Thank you!
The Scala Team

Alex Cruise | 18 Jan 20:10
Gravatar

Re: Naive proposal du jour: Extractor error messages

On Wed, Jan 18, 2012 at 12:32 AM, Naftoli Gugenheim <naftoligug <at> gmail.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

Gmane