SAM = Single Abstract Method It's how Java allows you to do stuff (like event handlers) that very clearly need first-class functions, even though the language doesn't have them.
As an example, imagine you want to take all the values in a list of integers, and multiply them by 2 With google collections, this can be done with the Function interface: http://google-collections.googlecode.com/svn/trunk/javadoc/com/google/common/base/Function.html <http://google-collections.googlecode.com/svn/trunk/javadoc/com/google/common/base/Function.html> final List<Integer> myList = ImmutableList.of(1,2,3); final Function<Integer, Integer> f = new Function<Integer, Integer> { public Integer apply(Integer from) { return from * 2; } } final List<Integer> result = Lists.transform(myList, f); That's an awful lot of boilerplate to capture the essential complexity "multiply by 2" Now imagine that you could use methods as fist-class functions, as Scala does: public int multByTwo(int from) { return from * 2; } . . . final List<Integer> myList = ImmutableList.of(1,2,3); final List<Integer> result = Lists.transform(myList, multByTwo); better already! and by getting rid of the type parameters, we've also been able use int instead of Integer, so double the benefit. (of course, auto-boxing will still be happening behind the scenes) Now take it to the next level, allow for anonymous functions, to be defined inline final List<Integer> myList = ImmutableList.of(1,2,3); final List<Integer> result = Lists.transform(myList, {int i => i * 2}); Or given that the compiler already knows the type of the list, we could use _ as a placeholder: final List<Integer> myList = ImmutableList.of(1,2,3); final List<Integer> result = Lists.transform(myList, {_ * 2}); This is already so much tidier than the original, but there's more... If we're programming in this style, and using a sequence of transformations on immutable lists, then we're going to see that `List<Integer>` type repeated, a lot. So lets just infer it! May as well make final the default while we're here: val myList = ImmutableList.of(1,2,3); val result = Lists.transform(myList, {_ * 2}); Almost there, this immutablity stuff is looking good, so it's probably better to make immutable list the default too: val myList = List(1,2,3); val result = Lists.transform(myList, {_ * 2}); next, we can get rid of that static method `Lists.transform`, static methods are a hangover from C/C++ anyway, and aren't very good object-orientation. Instead, we'll add a new method `map` on the List type, this is arguably a better name as it's also the term used in mathematics for the same concept. val myList = List(1,2,3); val result = myList.map(_ * 2); finally, to take it all the way to idiomatic Scala, we can use `map` in infix notation, and we'll also get rid of those niggling semicolons val myList = List(1,2,3) val result = myList map {_ * 2} and for comparison, here's the original again, using Java with a SAM type: final List<Integer> myList = ImmutableList.of(1,2,3); final Function<Integer, Integer> f = new Function<Integer, Integer> { public Integer apply(Integer from) { return from * 2; } } final List<Integer> result = Lists.transform(myList, f); So yes, SAM types are nasty when compared to the alternative... On 28 August 2010 00:23, Reinier Zwitserloot <[email protected]> wrote: > I think virtually everybody disagrees with you; SAMs aren't nasty. > Whatever makes you think they are? > > On Aug 27, 9:03 pm, Kevin Wright <[email protected]> wrote: > > What really gets my goat though... It's the pro-java/anti-scala crowd > > who are pushing the claim that "Scala is only for smart people". > > > > Myself, and the rest of the Scala evangelists on this list are going > > to great pains to point out that: no, actually, Scala is for everyone. > > > > I don't think that anyone here disagrees about how nasty SAM's are :) > > > > On 27/08/2010, Alexey Zinger <[email protected]> wrote: > > > > > > > > > Those are very noble goals, but I think there's a much easier way to > promote > > > Scala on the basis of its functional programming merits to Java > programmers. > > > > > Simply isolate a few examples of Java expressing functional style (easy > to > > > find > > > with event-driven stuff), admit that it works, and then show comparable > code > > > in > > > Scala that appears more expressive of the intent. Now the Java people > are > > > looking at another language to learn that might have some nice in-roads > for > > > certain applications or circumstances. To close the deal, showcase > > > Java-Scala > > > API interoperability and address performance. That's all you need. If > > > people > > > take up the language in a way that they eventually transition to it > fully, > > > fine, > > > if not, fine too. But hearing "Scala is for smart people, Java is for > > > everyone > > > else" or "if you're good enough, you should move to Scala and abandon > all > > > your > > > previous work" or whatever else is simply a turn-off. > > > > > Alexey > > > > > ________________________________ > > > From: Kevin Wright <[email protected]> > > > To: [email protected] > > > Sent: Fri, August 27, 2010 4:22:07 AM > > > Subject: Re: [The Java Posse] Re: So Scala is too Complex? > > > > > I'm going to take a tangent here, and open state my reasons for > defending > > > Scala > > > so strongly: > > > > > 1. The majority of Java programmers haven't even heard of Scala, let > alone > > > looked at it. Hopefully a heated debate will encourage people to think > > > "What's > > > all this fuss about..." > > > > > 2. To break the preconceptions that FP = academic, FP = hard (usually > via > > > FP=unfamiliar, unfamiliar=hard), etc. > > > > > 3. To demonstrate to people who think they can't deal with hard stuff > that, > > > actually, wee all do so in Java, every day. It's so depressing to hear > > > someone > > > say "but it's too difficult, I'm not good enough". Total nonsense, of > > > course > > > you're good enough! > > > > > 4. To point out that many quoted examples of FP being difficult are > actually > > > examples of mutability and side effects being difficult, it's a > refreshing > > > paradigm shift! > > > > > 5. To drag a lot of smart talented programmers into the beautiful world > of > > > FP, > > > kicking and screaming if necessary :) > > > I wouldn't expect world-class programmers to use inferior tools and > > > techniques, > > > any more than I'd expect an orchestra to be using violins from > wall-mart > > > > > On 27 August 2010 09:02, Reinier Zwitserloot <[email protected]> > wrote: > > > > > Ah, yes, we've come full circle. Scala fan defends poor language > > >>design choice by saying that it wouldn't have happened if you > > >>programmed purely functional. > > > > >>Newsflash, Kevin: If you want to stick to pure programming, there are > > >>far better languages than scala out there, such as Haskell or Clojure. > > >>Scala is in my opinion a lot more realistic for a large array of > > >>projects exactly because it gives you decent support for non-pure > > >>programming where its needed. > > > > >>For example, in this partition example, a pure version could have > > >>_EASILY_ been written using conslists, but I'm guessing partition uses > > >>a listbuilder instead because its significantly faster. > > > > >>On Aug 26, 11:23 pm, Kevin Wright <[email protected]> wrote: > > >>> Scala generally tries to "do the right thing" > > >>> It's a nebulous concept, of course, but it usually means "do what > Java > > >>> does" > > >>> Unless there's a good reason to state that what Java does is just > plain > > >>> wrong, or that it's seriously inconsistent with other goals of Scala > > > > >>> This particular example is interesting, insofar as it meets both > criteria > > >>> :) > > > > >>> Within functional programming, it's generally accepted that functions > > >>> should > > >>> be pure. i.e. that they should always return the same result if > given > > >>> the > > >>> same input. If nothing else, it does wonders for unit testing! > > > > >>> Constructors, OTOH, are about as far away as you can get from > functional > > >>> purity > > > > >>> Therein lies the rub! In order to accept the majority of Java > syntax, > > >>> it's > > >>> also necessary to sacrifice functional purity, and therefore the > elegance > > >>> and simple reasoning that are natural consequences of the ideal > > > > >>> So yes, the following is potentially confusing: > > > > >>> val left, right = newBuilder > > > > >>> But.. the confusion is perhaps based not so much in the concepts > behind > > >>> FP, > > >>> as it is in the inherent complexity of methods with side effects > > >>> (including > > >>> constructors). If `newBuilder` was a pure function, then it really > > >>> wouldn't > > >>> matter if `left` and `right` were assigned the same value, or the > result > > >>> of > > >>> two subsequent evocations of `newBuilder` > > > > >>> As is so often the case, the root cause of any possible > misunderstanding > > >>> here can be traced back to imperative code, and to mutability > > > > >>> On 26 August 2010 21:48, Reinier Zwitserloot <[email protected]> > wrote: > > > > >>> > Right, this is possible the worst one of all in partition. This > must > > >>> > mean that, translitering to java which we're all presumable a > little > > >>> > more familiar with, that: > > > > >>> > List<String> left, right = new ArrayList<String>(); > > > > >>> > results in 2 separate calls to the ArrayList constructor? > > > > >>> > Also, another WTF that came to me later, showing that even this > tiny > > >>> > snippet is not trivial to understand: Am I to assume that "a += b", > > >>> > where a is a list builder, does not reassign a at all, but is > instead > > >>> > syntax sugar for a.add(b)? The suggestion that in modern scala, :+= > is > > >>> > used is really not an excuse for this bad choice of operator > > >>> > overloading. The = surely suggests a will get reassigned here, when > > >>> > that doesn't happen. > > > > >>> > It's either that, or newBuilder just returns nil, and this is a > > >>> > conslist. In which case the terminology "newBuilder" is very > strange. > > > > >>> > partition is just bad code. > > > > >>> > On Aug 26, 3:48 pm, Viktor Klang <[email protected]> wrote: > > >>> > > On Thu, Aug 26, 2010 at 3:10 PM, Reinier Zwitserloot > > >>> > > <[email protected] > > >>> > >wrote: > > > > >>> > > > So, val l, r = newBuilder works because newBuilder is a > method, > > >>> > > > and > > >>> > > > this method returns a tuple? > > > > >>> > > No, that was just misinformation, it is assignment. > > > > >>> > > scala> val l,r = 5 > > >>> > > l: Int = 5 > > >>> > > r: Int = 5 > > > > >>> > > scala> l > > >>> > > res0: Int = 5 > > > > >>> > > scala> r > > >>> > > res1: Int = 5 > > > > >>> > > > Good lord. I rest my case! > > > > >>> > > I am glad that there are people like you, who are embracing Java > as a > > >>> > > language to it's full extent. > > > > >>> > > > On Aug 26, 10:03 am, Russel Winder <[email protected]> > wrote: > > >>> > > > > On Wed, 2010-08-25 at 15:56 -0700, Reinier Zwitserloot wrote: > > > > >>> > > > > [ . . . ] > > > > >>> > > > > > that this code works). If this is how scala ends up with > > >>> > > > > > shorter > > >>> > code, > > >>> > > > > > I don't want it. > > > > >>> > > > > Tuple assignment works brilliantly in Python and seems to in > > >>> > > > > Scala as > > >>> > > > > well. Tuple assignment solves so many problems that lead to > > >>> > > > > clumsy, > > >>> > > > > often unreadable and incomprehensible code in those languages > > >>> > > > > that do > > >>> > > > > not support it. You may not want it, but I do. > > > > >>> > > > > > > (if p(x) left else right) += x; > > > > >>> > > > > > In java there's a more or less long-standing hatred of > using > > >>> > > > > > assignments, which are legally expressions, as anything but > a > > >>> > > > > > statement. i.e. folks frown on this kind of thing: int x = > 5 + > > >>> > > > > > y = > > >>> > 10; > > >>> > > > > > even though it is technically legit java code. This feels > > >>> > > > > > similar, > > >>> > > > > > using the result of an if expression as the target of an > > >>> > assignment. > > >>> > > > > > For example, while its a few characters longer, I find this > > >>> > > > > > much > > >>> > more > > >>> > > > > > readable: > > > > >>> > > > > > if (p(x)) l += x; > > >>> > > > > > else r += x; > > > > >>> > > > > You may do so but I do not, I think it looks truly archaic. > And > > >>> > where > > >>> > > > > has this "hatred of using assignments. . .[as expressions]" > in > > >>> > > > > Java > > >>> > come > > >>> > > > > from, I don't see it, exactly the opposite, there is an > > >>> > > > > increasing > > >>> > use > > >>> > > > > of expression-based and value-based working. > > > > >>> > > > > > Using ifs as expression is a nice gimmick that tends to > lead, > > >>> > > > > > IMO, > > >>> > to > > >>> > > > > > hard to read code. Just like assignment-as-expression. Yet > > >>> > > > > > again, a > > > > >>> > > > > Exactly, in your opinion. In my opinion you are looking back > > >>> > > > > fondly > > >>> > to > > >>> > > > > the days of assembly language programming. There is a > crucial > > >>> > > > > difference between simplicity of expression and expressivity. > > >>> > > > > Simplicity of expression is important for readability -- > there > > >>> > > > > are > > >>> > > > > experiments happening to show this, it's not research by > > >>> > > > > expounding > > >>> > > > > opinion. Similarly there is experimentation to show that > having > > >>> > > > > the > > >>> > > > > simple expression express high-level algorithmic things > rather > > >>> > > > > than > > >>> > > > > low-level algorithmic things leads to faster code writing and > > >>> > > > > easier > > >>> > > > > maintainability. Again there is experiment, this is not just > > >>> > attempting > > >>> > > > > to create facts by writing opinion often enough that people > think > > >>> > it's > > >>> > > > > fact. The keywords to search for are "psychology of > > >>> > > > > programming", > > >>> > > > > "program comprehension", etc., etc. > > > > >>> > > > > [ . . . ] > > > > >>> > > > > > characters compared to .add(x). Big whoop. This is EXACTLY > why > > >>> > > > > > some > > >>> > > > > > people > > > > ... > > > > read more » > > -- > You received this message because you are subscribed to the Google Groups > "The Java Posse" group. > To post to this group, send email to [email protected]. > To unsubscribe from this group, send email to > [email protected]<javaposse%[email protected]> > . > For more options, visit this group at > http://groups.google.com/group/javaposse?hl=en. > > -- Kevin Wright mail/google talk: [email protected] wave: [email protected] skype: kev.lee.wright twitter: @thecoda -- You received this message because you are subscribed to the Google Groups "The Java Posse" group. To post to this group, send email to [email protected]. To unsubscribe from this group, send email to [email protected]. For more options, visit this group at http://groups.google.com/group/javaposse?hl=en.
