Skip to content

[Collections] [Hooks] API enhancment #29

@lounres

Description

@lounres
  1. Fix temporary collections API and come up with a new one (like from Java API but better?).

  2. Hooks. A part of abstract algorithms works like (or precisely are) dynamic algorithms. It means there is an input data that is changing and the output should be changed along. It also means that there should be an API to simplify representation of such relationship.

    Suggestion is that there should be a Hook interface which declares API for hooking on changes viewers. In that case all the algorithms can be represented as a simple object which state depends on its arguments and, hence, can be called "views". For example,

    /**
     * @param C type that is representing data change
     * @param I type of intermediate data representation
     */
    interface Hook<C, I> {
        fun hookOn(callback: I.(change: C) -> Unit)
    }
    interface View<E> {
        val value: E
    } 
    
    // ...
    
    sealed interface ListChange<E> {
        data class Assign<E>(val index: Int, val oldElement: E, val newElement: E): ListChange<E>
        data class Insert<E>(val index: Int, val newElement: E): ListChange<E>
        data class Remove<E>(val index: Int, val oldElement: E): ListChange<E>
    }
    interface MutableListHook<E>: MutableList<E>, Hook<ListChange<E>, List<E>>
    class MutableListHookImpl<E>(private val list: MutableList<E>): MutableList<E> by list, MutableListHook<E> {
        private val hooks = mutableListOf<List<E>.(ListChange<E>) -> Unit>()
        override fun hookOn(callback: List<E>.(change: ListChange<E>) -> Unit) { hooks.add(callback) }
        private fun trigger(change: ListChange<E>) { hooks.forEach { list.it(change) } }
    
        override fun add(element: E): Boolean {
            trigger(ListChange.Insert(list.size, element))
            return list.add(element)
        }
        // ...
    }
    
    // ...
    
    class DynamicMaximumValueView<E>(hook: MutableListHook<E>, comparator: Comparator<E>): View<E> {
        private val heap = MaxHeap(hook, comparator)
        init {
            hook.hookOn {
                when (it) {
                    is ListChange.Assign -> {
                        heap.remove(it.oldElement)
                        heap.add(it.newElement)
                    }
                    is ListChange.Insert -> {
                        heap.add(it.newElement)
                    }
                    is ListChange.Remove -> {
                        heap.remove(it.oldElement)
                    }
                }
            }
        }
        override val value: E get() = heap.head
    }

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requestmodule:main:collectionsConcerns the [Collections] modulemodule:main:hooksConcerns the [Hooks] moduleto discussTopic to be discussed and/or thought over

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions