Bug 431213 - [xbase.lib] introduce construction methods for iterables/iterator
Summary: [xbase.lib] introduce construction methods for iterables/iterator
Status: REOPENED
Alias: None
Product: TMF
Classification: Modeling
Component: Xtext (show other bugs)
Version: 2.5.0   Edit
Hardware: PC Mac OS X
: P3 normal (vote)
Target Milestone: ---   Edit
Assignee: Project Inbox CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2014-03-26 06:35 EDT by Moritz Eysholdt CLA
Modified: 2014-07-28 04:27 EDT (History)
2 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Moritz Eysholdt CLA 2014-03-26 06:35:48 EDT
newArrayList and newHashSet are quite convenient. It would be nice if there would be a utility function that can convert a self-implemented linked list into an Iterable or Iterator.

I'm aware this scenario can easily be implemented using while-loop or a 'tradition' for-loop. However, both force me into imperative programming. Sometimes it's nice to stay functional.

Example:

----------------- Main.xtend -------------------
import static extension IterableLiterals.*

class Main {
	def static void main(String[] args) {
		val item = new MyLinkedListItem => [
			name = "first"
			next = new MyLinkedListItem => [
				name = "second"
				next = new MyLinkedListItem => [
					name = "third"
					next = new MyLinkedListItem => [
						name = "fourth"
					]
				]
			]
		]

		for (x : item.newIterable[i|i.next])
			println("imperative:" + x.name)

		println(item.newIterable[next].map["functional:" + name].join("\n"))
	}

}

class MyLinkedListItem {
	@Property String name
	@Property MyLinkedListItem next
}

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


----------------- stdout ---------------------
imperative:first
imperative:second
imperative:third
imperative:fourth
functional:first
functional:second
functional:third
functional:fourth
----------------------------------------------


------------------ IterableExtensions.java -------------
import java.util.Iterator;

import com.google.common.base.Function;

public class IterableLiterals {
	/**
	 * Returns an Iterable that will return <i> head </i> as its first 
	 * item and use the function <i> trail </i> to compute all follow-up items.
	 * 
	 * @param head
	 * @param trail
	 * @return
	 */
	public static <T> Iterable<T> newIterable(final T head, final Function<T, T> tail) {
		return new Iterable<T>() {
			@Override
			public Iterator<T> iterator() {
				return IteratorLiterals.newIterator(head, tail);
			}
		};
	}
}
------------------------------------------------------


---------------------- IteratorExtensions.java --------------
import java.util.Iterator;

import com.google.common.base.Function;

public class IteratorLiterals {
	/**
	 * Returns an Iterator that will return <i> head </i> as its first item 
	 * and use the function <i> trail </i> to compute all follow-up items.
	 * 
	 * @param head
	 * @param trail
	 * @return
	 */
	public static <T> Iterator<T> newIterator(final T head, final Function<T, T> tail) {
		return new Iterator<T>() {

			private T next = head;

			@Override
			public boolean hasNext() {
				return next != null;
			}

			@Override
			public T next() {
				T oldNext = this.next;
				this.next = tail.apply(this.next);
				return oldNext;
			}

			@Override
			public void remove() {
				throw new UnsupportedOperationException();
			}
		};
	}

}
------------------------------------------------
Comment 1 Stefan Oehme CLA 2014-07-18 07:49:33 EDT
Pushed to review

https://git.eclipse.org/r/#/c/30116/
Comment 2 Sebastian Zarnekow CLA 2014-07-18 08:07:01 EDT
I'd like to discuss the added value of this function.
Comment 3 Stefan Oehme CLA 2014-07-28 04:27:40 EDT
The potential use cases can be solved by using Guava's AbstractIterator or TreeTraverser. This has some syntactic overhead, but we currently don't see it used often enough to put a shortcut into the standard lib.

Postponed until there are better use cases for this.