The Artima Developer Community
Sponsored Link

Java Community News
Implicit Arguments in Scala

16 replies on 2 pages. Most recent reply: Apr 1, 2008 4:36 PM by Andy Dent

Welcome Guest
  Sign In

Go back to the topic listing  Back to Topic List Click to reply to this topic  Reply to this Topic Click to search messages in this forum  Search Forum Click for a threaded view of the topic  Threaded View   
Previous Topic   Next Topic
Flat View: This topic has 16 replies on 2 pages [ 1 2 | » ]
Frank Sommers

Posts: 2642
Nickname: fsommers
Registered: Jan, 2002

Implicit Arguments in Scala Posted: Mar 7, 2008 8:52 PM
Reply to this message Reply
Summary
In a recent blog post, David MacIver discusses a useful Scala construct: implicit function arguments.
Advertisement

An often convenient programming construct in Scala is implicit method arguments. In a recent blog post, An introduction to implicit arguments, David MacIver writes that,

SBinary and Scalacheck are part of a small set of libraries that make extensive use of implicit arguments in a style very reminiscent of Haskell type classes. I'm hoping this style of programming will get more common in Scala—it's a really useful technique... But ... you need to really understand how implicit arguments in Scala work...

As a starting point, in Scala you can declare a method to have multiple argument lists... This has one advantage though. You can declare the last parameter list of a function to be implicit. The syntax for this works as follows:

scala> def speakImplicitly (implicit greeting : String) = println(greeting)
speakImplicitly: (implicit String)Unit

scala> speakImplicitly("Goodbye world")
Goodbye world

scala> speakImplicitly
:6: error: no implicit argument matching parameter type String was foud.

scala> implicit val hello = "Hello world"
hello: java.lang.String = Hello world

scala> speakImplicitly
Hello world

So, we can call this as normal but, additionally, we can leave out the implicit argument list and the compiler will look for a value in the enclosing scope which has been marked as implicit. If we try to do that and there is no such value in scope then the compiler will complain.

MacIver then discusses the uses of implicit arguments in case the wrong arguments types are provided, when subtypes are specified, as well as parameterized implicit types. MacIver also provides several detailed examples of idiomatic use of implicit Scala argument types.

What do you think of MacIver's take on implicit arguments?


Carson Gross

Posts: 153
Nickname: cgross
Registered: Oct, 2006

Re: Implicit Arguments in Scala Posted: Mar 7, 2008 9:01 PM
Reply to this message Reply
Stark, raving lunacy?

Cheers,
Carson

Cedric Beust

Posts: 140
Nickname: cbeust
Registered: Feb, 2004

Re: Implicit Arguments in Scala Posted: Mar 7, 2008 9:53 PM
Reply to this message Reply
There are a lot of things I like in Scala, but implicit arguments (well, this kind anyway) scare me because they act exactly like global variables.

Even worse: your methods can now receive different arguments just based on what modules are being mixed in...

Am I the only one who really dislikes this feature?

--
Cedric

Jayce Vaidyan

Posts: 8
Nickname: finite42
Registered: Mar, 2007

Re: Implicit Arguments in Scala Posted: Mar 8, 2008 10:54 AM
Reply to this message Reply
Scala is supposed to tackled larger projects than languages like Java.

However, I have seen disturbing trends in the Scala blogosphere, where almost all Scala bloggers seem to be obsessed with outdoing Ruby and Perl in writing one-liners that only less than 1% of the programming community is capable of understanding (granted, they are the smartest 1%, but think about the 99% who have to waste time trying to understand it when, with very little extra implicit code everyone could benefit).

Features like the Perlish _ (think $_) and implicit arguments will allow clever code, but at what cost?

I learned and used Perl in the "post Best Practices" world (not the book, which came later), and I saw first hand, in the field, where those best practices were applied---a huge chunk of it was about discouraging the (ab)use of most things implicit.

I am perfectly ok with features that reduce obfuscation through boilerplate (e.g., like the ones that we have to deal with in languages like Java, C, etc) However, obfuscation can, and in more cases, go the other way. The question is: What do we gain? A few keystrokes (10-20s saved) while writing vs. 10-20 minutes of trying to figure out what is going on (which have to be repeated with each new programming who will have to use this)

It is unclear from the article what exactly we would gain from this.

The ability to declare an input that matches a latent type for a single method? What if I have two methods with such methods. All we have to rely on is type info.

The following tries to build a situation where this implicit feature comes in handy (based on the examples in the article):

object Ri {
def f(x: String)(implicit y: String) = "R.f(" + x + "," + y + ")"
}

object Mi {
def g(x: String, y: String)(implicit z: String) = "M.f(" + x + "," + y + "," + z + ")"
}

object Pain extends Application {
implicit val x = "A"
// implicit val y = "L" // not possible (to avoid ambiguitiy)
println( Ri.f("Va") )
println( Ri.f("La") )
println( Mi.g("Yo", "Yo") )
println( Mi.g("Da", "Ja") )
}

Now, that is handy to call Ri.f(). But now I can't give a different value for Mi.g() (which is better than having random behavior). But worse, no warnings will be issued if I missed (in this case, it is quite unlikely, but quite likely in real life). What if this is part of a library that you did not write. Accidents can happen.

The same thing can be done much more safely, and with greater flexibility, using partial functions, currying (or whatever it is called) (and in this case, a lot less boilerplate, 8 characters less :-) ).

object R {
def f(y: String)(x: String) = "R.f(" + x + "," + y + ")"
}

object M {
def g(z: String)(x: String, y: String) = "M.f(" + x + "," + y + "," + z + ")"
}

object Main extends Application {
def fx = R.f("A")_
def gx = M.g("L")_

println( fx("Va") )
println( fx("La") )
println( gx("Yo", "Yo") )
println( gx("Da", "Ja") )
}

I suppose I haven't understood this very well. Probably have to go through David MacIver's suggested readings to find more examples.

Although, I am sceptical about the cost-benefit advantage of implicit arguments, I thank bloggers like David R. MacIver and Daniel Spiewak for regularly providing insights into Scala and other things. Keep blogging.

Fred Garvin

Posts: 52
Nickname: fredgarvin
Registered: Jan, 2008

Re: Implicit Arguments in Scala Posted: Mar 8, 2008 11:26 AM
Reply to this message Reply
Is it April 1st?... Nope, I had to check because this is such a ridiculous feature.

Seriously, the more I learn about Scala the less excited I am about the language. This feature especially is not only counterintuitive, it is downright dangerous. It invites crazy code like this: http://michid.wordpress.com/2008/02/08/implicit-double-dispatch-revisited/

Lex Spoon

Posts: 6
Nickname: lexspoon
Registered: Oct, 2006

Re: Implicit Arguments in Scala Posted: Mar 8, 2008 2:16 PM
Reply to this message Reply
I can't speak for anyone else, but I am cowriting Programming in Scala and I don't think people should make code so short as to be unreadable. The proper use of implicits is to leave out stuff that is obvious. For code that is not obvious, implicits should not be used to hide it.

The advice we give in the book is that the type of an implicit parameter should include a role-specific name in it. The type "String" would violate this, because a String could be anything. I expect David only used type String so as to keep the example short. Programming in Scala has a similar example using type Int, and indeed we only include it to show how the feature works.

For code you intend to maintain, it would be better for the implicit greeting parameter to be, say, of type Greeting. Greeting would be a class with one field that holds the actual greeting. If you set things up like this, then the implicitly passed object is always going to be of type Greeting, so the system will not to pass any old random string that is in scope. Scala will only pass a string that is marked as a greeting, and it will only do so if there is precisely one such greeting in scope. Assuming that you actually do want greetings to be implicit, this setup should do what everyone expects.

In general, I agree that there is a danger in powerful language features: they can make code so short as to be incomprehensible. Scala makes some such language features available nonetheless, in cases where the feature seems useful. For implicits, the use is that even with Scala's other features, some code really is completely obvious. Implicits should be used to remove this obvious code, not to remove code the reader would actually like to look at.

Jayce Vaidyan

Posts: 8
Nickname: finite42
Registered: Mar, 2007

Re: Implicit Arguments in Scala Posted: Mar 8, 2008 4:58 PM
Reply to this message Reply
> ... The proper use of
> implicits is to leave out stuff that is obvious. For code
> that is not obvious, implicits should not be used to hide
> it.
> ...For implicits, the use is that even with Scala's
> other features, some code really is completely obvious.
> Implicits should be used to remove this obvious code, not
> t to remove code the reader would actually like to look at.
> ...Scala will only pass
> a string that is marked as a greeting, and it will only do
> so if there is precisely one such greeting in scope.

Thanks Lex Spoon.
That does clarify the meaning and use of this feature.

> ...The advice we give in the book is that the type of an
> implicit parameter should include a role-specific name in
> it. The type "String" would violate this, because a
> String could be anything.... Programming in
> Scala has a similar example using type Int, and indeed we
> only include it to show how the feature works.

Is it possible to change this example to use a container/case class?

Type is so important in this case, so any example that deals with this must emphasize this.

Anyone learning Scala would be learning the basics of things like Some(x) before reaching explicit arguments. So, using a container or case class for the example won't make it too complicated.

Also, in the future, FindBugs and PMD equivalents for Scala could flag the use of standard and basic types like Int and String for implicit arguments as serious errors. :-)

On the matter of emphasizing the importance of types, consider exceptions. Most of the time, what really matters is the type of exception.

One of the things that Guido van Rossum thinks was a mistake in Python was the decision to let exceptions be anything, including strings and other random stuff. This will be fixed in Python 3.0. and has been deprecated for a long, long, time.

Cedric Beust

Posts: 140
Nickname: cbeust
Registered: Feb, 2004

Re: Implicit Arguments in Scala Posted: Mar 8, 2008 11:33 PM
Reply to this message Reply
Hi Lex, and thanks for the clarifications.

First of all, I have to say I really like the book and I think that you, Bill and Martin did a great job at presenting a tough subject with interesting examples and a style that's pleasant to read.

Having said that, you haven't addressed the point I mentioned earlier, namely: your methods can suddenly receive unexpected parameters just because you mixed in different modules.

This is actually even worse than the "fragile base class" problem, in which adding methods in a base class can possibly break clients. With implicits, it's now possible to break entire code bases just by specifying a few implicits. At best, you'll create an ambiguity that the compiler will catch. At worst, methods will start receiving parameters that were never passed before.

Do you have any comments on this?

--
Cedric

Martin Odersky

Posts: 84
Nickname: modersky
Registered: Sep, 2003

Re: Implicit Arguments in Scala Posted: Mar 9, 2008 3:16 AM
Reply to this message Reply
Hi Cedric,

> Having said that, you haven't addressed the point I
> mentioned earlier, namely: your methods can suddenly
> receive unexpected parameters just because you mixed in
> different modules.
>
> This is actually even worse than the "fragile base class"
> problem, in which adding methods in a base class can
> possibly break clients. With implicits, it's now possible
> to break entire code bases just by specifying a few
> implicits. At best, you'll create an ambiguity that the
> compiler will catch. At worst, methods will start
> receiving parameters that were never passed before.
>
It's indeed similar to the fragile baseclass problem. Both virtual members and implicit parameters give you great expressiveness which can lead to problems if misused. You can solve the fragile baseclass problem by making all your methods final. You can solve the unwanted implicits problem by not using any.

In practice, of course, you want to find the right mixture between expressiveness and safety. You'll accept some virtual methods, and you'll accept some implicit parameters at places where they are really useful. And they are amazingly useful when used as a tool in the right hands.

For instance ScalaCheck lets you write properties of your programs and then constructs unit tests for these properties automatically. Several bugs in the standard Scala library have been found this way. Without implicit parameters, the plumbing you'd have to do to set up the properties would make them much uglier, so people most likely would not write any. So that's an example where implicits are really useful. Expect to see many more libraries that do amazing things like ScalaCheck in the future.

Cheers

-- Martin

P.S. I think this discussion highlights a bit the design philosophies behind Java and Scala. They are not the same. Scala puts more trust in its users that they will do the right thing. Maybe this assumption is wrong, and users will make a mess of it, but that's what Scala is.

Michael Dürig

Posts: 2
Nickname: michid
Registered: Mar, 2008

Re: Implicit Arguments in Scala Posted: Mar 9, 2008 9:33 AM
Reply to this message Reply
I don't consider this crazy code. It is - in some respect - an application of the code follows type paradigm (see http://www.cs.kuleuven.be/~adriaan/files/Code-follows-Type%20Programming%20in%20Scala.pdf) which is well understood.

Vincent O'Sullivan

Posts: 724
Nickname: vincent
Registered: Nov, 2002

Re: Implicit Arguments in Scala Posted: Mar 9, 2008 1:23 PM
Reply to this message Reply
> The proper use of implicits is to leave out stuff that is obvious.

That's fine, but it does rather assume that everyone can agree on what is obvious and what isn't.

Alan Keefer

Posts: 29
Nickname: akeefer
Registered: Feb, 2007

Re: Implicit Arguments in Scala Posted: Mar 10, 2008 3:34 PM
Reply to this message Reply
I don't get it at all: as far as I can tell, this is just a way to make your code utterly incomprehensible. I really don't see the actual value in it; the examples given in the post are pretty trivial, so I'd be interested in hearing some actual use cases for this.

This feature (and a lot of Scala features) seems way too much like someone said "Hey, I have this one case where this crazy feature would really come in handy, let's add it to the language," which just isn't a great way to design a language. As everyone knows code is read more often than it's written, is changed more often than it's written from scratch, and that understanding someone else's code is difficult and time consuming. So code should generally be optimized for future maintainability and for comprehensibility. Implicit arguments seem like they add a huge cost in terms of readability and future modifiability, with only marginal (if any) improvements in being able to write the code.

The programming world already has enough rope to hang themselves with, so I'd much rather use a simpler language that doesn't have features that can be so easily abused.

V.H.Indukumar

Posts: 28
Nickname: vhi
Registered: Apr, 2005

Re: Implicit Arguments in Scala Posted: Mar 11, 2008 5:19 AM
Reply to this message Reply
We already have such a simple language... Java 1.4!

I think Scala fulfills the need for a language that is powerful and works within the JVM.

Anyway the Implicits arguments are to be used rarely, and usually you will get used to it.

One change I would like to see is that the Scala should make it illegal to use Implicit arguments in cases other than the user defined types to improve safety.

Andy Dent

Posts: 165
Nickname: andydent
Registered: Nov, 2005

Re: Implicit Arguments in Scala - AppMaker Posted: Mar 12, 2008 6:38 PM
Reply to this message Reply
I found this a fascinating post because the Scala feature hits my past and my future. Dating back to about 1993, the AppMaker v2 code generation language (built into the Mac-only AppMaker code generator) had a feature very like these implicit arguments.

For any argument in an AppMaker procedure, the caller could either define a local variable matching the argument name or they could explicitly assign the argument as a keyword argument eg: doStuff(msg="hello").

The implicit arguments could be inherited having being defined by a caller of the immediate context.

The really bizarre feature of this language was that it lacked global variables as such but had the orthogonal feature to implicit - exported variables which were a way for a function that you called to push a variable into the implicit space. Yes, this can get very painful to debug but can be amazingly useful. It is basically a strategy pattern for declarations - depending on which functions you call, a different set of variables might be published.

Ignacio Coloma

Posts: 2
Nickname: icoloma
Registered: May, 2007

Harder debugging Posted: Mar 13, 2008 3:08 AM
Reply to this message Reply
Now, when I am debugging (which I do _far_ more than writing code from scratch) if a method invocation fails (and I don't have a stack trace), I have to look some lines before, some lines after, the method declaration, etc.

Reminds me of old C++ code where I had to look for bugs on default constructors, operator overloads, etc to debug a single line of code. Scala is doing my work harder, and giving the rookie programmer a bug freeway included in the language.

Yep, we all should know the correct way to use this, much the same way as everybody has read Effective Java - only that in my world, developers don't quite often read books.

Flat View: This topic has 16 replies on 2 pages [ 1  2 | » ]
Topic: The Eclipse Graphical Modeling Framework Previous Topic   Next Topic Topic: Azul Releases Realtime Performance Monitor for Java

Sponsored Links



Google
  Web Artima.com   

Copyright © 1996-2019 Artima, Inc. All Rights Reserved. - Privacy Policy - Terms of Use