/candyland

Immutable Data Structures for python, for better OOP Programming and Safer Multi-threading.

Primary LanguagePythonGNU General Public License v3.0GPL-3.0

Candyland Sativa

candyland

Immutable Data Structures for python.

Why Should Objects Be Immutable?

This is an incomplete list of arguments in favor of immutability:

  • immutable objects are simpler to construct, test, and use
  • truly immutable objects are always thread-safe
  • they help to avoid temporal coupling
  • their usage is side-effect free (no defensive copies)
  • identity mutability problem is avoided
  • they always have failure atomicity
  • they are much easier to cache
  • they prevent NULL references, which are bad

(Taken from Yegor Bugayenko's blog.)

Currently Supported Data Structures

Upcoming:

  1. Queue
  2. Stack
  3. List
  4. KeyValuePair (Who needs a key-value pair in python? )
  5. Set
  6. PriorityQueue
  7. LinkedList
  8. SortedList
  9. AVLTree
  10. BinarySearchTree
  11. RedBlackTree
  12. Heap
  13. HashTable
  14. Dictionary
  15. BinaryTree

Usage

Stack

from immutable.abstract import Stack
s = Stack(1, 2, 3)  # Can also: s = Stack() or s = Stack([1, 2, 3])
print s.push(7).head()  # Prints 7
print s.pop().head()  # Prints 2
print s.count()  # Prints 3

Queue

from immutable.abstract import Queue
q = Queue(1, 2, 3)
print q.enqueue(7).head()  # Prints 1
print q.pop().head()  # Prints 1
print q.count()  # Prints 3

List

from immutable.abstact import List
l = List(1, 2, 3)
print 2 in l 
print l.reverse().append(3).remove(2).extend([1, 2]).pop(1).sort().insert(1, 3).count(3)

Dictionary

from immutable.abstract import Dictionary
d = Dictionary({1:2, 4:5})
d + Dictionary([(1, 2), (3, 4)]).append(4, 5).pop(1) + Dictionary.from_keys([1, 2], 0)

Set

from immutable.abstract import Set
print 1 in (Set(1, 2, 3) & Set(3, 4, 5) | [1, 2, 0] - [3, 4]).add(9).update(List(3,3)).pop().remove(2)

BinaryTree

from immutable.trees import BinaryTree
tree = BinaryTree(BinaryTree(BinaryTree(None, None, 2),
                                     BinaryTree(BinaryTree(None,
                                                           None,
                                                           5),
                                                None,
                                                6),
                                     4),
                          BinaryTree(BinaryTree(None,
                                                None,
                                                10),
                                     BinaryTree(BinaryTree(None, None, 15),
                                                BinaryTree(None, None, 18),
                                                16),
                                     13),
                          8) 
print tree, repr(tree), 13 in tree, 3.14 in tree, list(tree), iter(tree), tree.add(1).add(2).remove(3).remove(4) 

for x in BinaryTree.make([1, 2, 3, -1, 4, 7, 9, 14, 8, -23]):
  print x

Heap

from immutable.trees import Heap

h1 = Heap.make([1, 2, 3, 4, 5, 6, 10, 14, 11, 0, -2], min)  
h2 = Heap([1, 2, 3], max)
h3 = Heap([1, 2, 3])
# second parameter is an optional comparator, default is max.

print h1.add(1).pop(3).pop(4).add(20).head()

AVLTree

from immutable.trees import AVLTree
tree = AVLTree(1, None, None)
print 2 in tree.add(1).add(2).pop(4)
for x in AVLTree.make([1, 2, 3, -1, 4, 7, 9, 14, 8, -23]):
  print x

         

candyland's True Immutability stems from it's ability to equate based on an object's state and not by it's reference.