Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.
Bug 369949 - I'd like to see closures work with SAM classes
Summary: I'd like to see closures work with SAM classes
Status: CLOSED FIXED
Alias: None
Product: Xtend
Classification: Tools
Component: Core (show other bugs)
Version: 2.2.0   Edit
Hardware: All All
: P3 enhancement (vote)
Target Milestone: M6   Edit
Assignee: Project Inbox CLA
QA Contact:
URL:
Whiteboard:
Keywords:
: 389597 (view as bug list)
Depends on: 376037
Blocks:
  Show dependency tree
 
Reported: 2012-01-27 10:40 EST by William R. Burdick Jr. CLA
Modified: 2017-10-31 11:17 EDT (History)
6 users (show)

See Also:
sven.efftinge: kepler+


Attachments
Change to allow xtend closures to coerce to SAM classes (1.80 KB, patch)
2012-01-27 10:44 EST, William R. Burdick Jr. CLA
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description William R. Burdick Jr. CLA 2012-01-27 10:40:46 EST
Build Identifier: 

My motivation is really to get xtend closures working seamlessly with FJ's functions, which, unfortunately, are abstract classes, instead of interfaces. 

I have a patch that seems to work for FJ functions.

Reproducible: Always

Steps to Reproduce:
After the enhancement, this should print false:


import fj.F

class Test {
	def static void main(String[] args) {
		val F<Integer, Integer, ?> f = [x, y | x + y > 1]

		println(f.f(1, 0))
	}
}
Comment 1 William R. Burdick Jr. CLA 2012-01-27 10:44:35 EST
Created attachment 210193 [details]
Change to allow xtend closures to coerce to SAM classes

I tried to keep the changes minimal and follow the coding philosophy of the project as best I could.
Comment 2 Sebastian Zarnekow CLA 2012-01-30 03:08:35 EST
We'd have to rethink the implementation of the interpreter in order to allow closures for SAM classes.
Comment 3 Sebastian Zarnekow CLA 2012-01-30 03:09:06 EST
(In reply to comment #2)
> We'd have to rethink the implementation of the interpreter in order to allow
> closures for SAM classes.

Well we could do this for Xtend only and stick with interfaces for the general expression lib.
Comment 4 Sven Efftinge CLA 2012-02-29 06:23:30 EST
After internal discussion we agreed on doing it in Xbase but having it limited to interfaces by default. Languages need explicitly enable support for abstract classes, by overriding a small template method.

Also we want to have a validation rule, which replaces the generic type conformance checks telling the user, that the expected type 'Foo' is not a functional type.
Comment 5 Moritz Eysholdt CLA 2012-03-22 05:44:48 EDT
Thoughtworks' technology radar motivated me to have a look at Functional Java. Then I remembered this ticket...
Here's the SAM: http://functionaljava.googlecode.com/svn/artifacts/3.0/javadoc/fj/F.html
Comment 6 Ben Hutchison CLA 2012-07-01 07:35:00 EDT
I'd love to see this change make it into Xtend. Im currently doing a GWT + FJ project and it would be great to combine XTend's lambda syntax with FJ. 

Kudos to Bill for his patch too! Not a trivial undertaking for a user. If this patch still works against latest Xtend, and its pretty easy to build, I might just patch my Xtend to get this working...
Comment 7 Sven Efftinge CLA 2012-09-14 08:28:38 EDT
*** Bug 389597 has been marked as a duplicate of this bug. ***
Comment 8 Dénes Harmath CLA 2012-10-27 07:43:04 EDT
+1 Guava also has some SAMs, e.g. CacheLoader or AbstractIterator.
Comment 9 Sebastian Zarnekow CLA 2013-01-22 10:54:35 EST
Implemented first draft of sam support for abstract classes.

Allows to implement the sample abstract iterator from guava 

   public static Iterator skipNulls(final Iterator in) {
     return new AbstractIterator() {
       protected String computeNext() {
         while (in.hasNext()) {
           String s = in.next();
           if (s != null) {
             return s;
           }
         }
         return endOfData();
       }
     };
   }}

can be implemented like this:

def <T> Iterator<T> skipNulls(Iterator<T> iter) {
	val AbstractIterator<T> result = [|
		while(iter.hasNext) {
			val elem = iter.next
			if (elem != null)
				return elem
		}
		return self.endOfData
	]
	return result
}

or it could even be implemented like this if elvis would be evaluated lazily:

def <T> Iterator<T> skipNulls(Iterator<T> it) {
	val AbstractIterator<T> result = [|
		iter.findFirst [ it != null ] ?: self.endOfData
	]
	return result
}

where self is the pointer to 'this' closure type, e.g. it allows to invoke endOfData. Note that it is not necessary to have a #super for the closure type since only a single abstract method can be implemented like that (which does not have a super implementation) and all other members can be reached by self.<member>

Will be released together with the new type system.

Remaining issues shall be tracked in individual tickets.
Comment 10 Eclipse Webmaster CLA 2017-10-31 11:06:03 EDT
Requested via bug 522520.

-M.
Comment 11 Eclipse Webmaster CLA 2017-10-31 11:17:17 EDT
Requested via bug 522520.

-M.