001/*
002 * Copyright (c) 2012-2018 Institut National des Sciences Appliquées de Lyon (INSA Lyon) and others
003 *
004 * This program and the accompanying materials are made available under the
005 * terms of the Eclipse Public License 2.0 which is available at
006 * http://www.eclipse.org/legal/epl-2.0.
007 *
008 * SPDX-License-Identifier: EPL-2.0
009 */
010
011package gololang;
012
013/**
014 * Structure having a head and a tail.
015 * <p>
016 * This interface can be used to define any recursive sequence of object,
017 * such as lists or generators. It is well suited to recursive algorithms, and
018 * thus can be seen as an alternative to the {@code Iterable} interface.
019 * <p>
020 * For example, one can compute the size of such an object with:
021 * <pre class="listing"><code class="lang-java" data-lang="java">
022 * static int size(HeadTail<?> o) {
023 *   if (o.isEmpty()) { return 0; }
024 *   return 1 + size(o.tail());
025 * }
026 * </code></pre>
027 * or in Golo:
028 * <pre class="listing"><code class="lang-golo" data-lang="golo">
029 * function size = |ht| -> match {
030 *   when ht: isEmpty() then 0
031 *   otherwhise 1 + size(ht: tail())
032 * }
033 * </code></pre>
034 * <p>
035 * Note that the {@code size} method is not provided since this interface
036 * can be implemented by infinite generators.
037 * <p>
038 * A {@code List} augmentation is provided, as well as corresponding special
039 * methods on arrays ({@code Object[]}/{@code array[]})
040 *
041 * @param <E> the type of the elements held in this structure.
042 */
043public interface HeadTail<E> extends Iterable<E> {
044
045  /**
046   * Get the head of the structure.
047   *
048   * @return the first element of the structure, or {@code null} if the structure is empty.
049   */
050  E head();
051
052  /**
053   * Get the tail of the structure.
054   * <p>
055   * To be side effect free, this method should return a deep copy of the original structure or an
056   * immutable view on it.
057   *
058   * @return a new {@code HeadTail} containing all the elements but the first, or a empty one
059   * if no elements remains.
060   */
061  HeadTail<E> tail();
062
063  /**
064   * Checks if the structure is empty or not.
065   *
066   * @return {@code true} if the structure contains no element, {@code false} otherwise.
067   */
068  boolean isEmpty();
069
070  /**
071   * Util method to wrap a {@code HeadTail} instance into an {@code Iterable}
072   *
073   * @param headTail the instance to wrap
074   * @return an iterable on the values contained in the wrapped instance
075   */
076  static <E> Iterable<E> toIterable(HeadTail<E> headTail) {
077    return () -> new HeadTailIterator<>(headTail);
078  }
079
080}