1

I follow this definition of "object":An object is a value exporting a procedural interface to data or behavior. Objects use procedural abstraction for information hiding, not type abstraction. Object and and their types are often recursive. Objects provide a simple and powerful form of data abstraction. They can be understood as closures, first-class modules, records of functions, or processes. Objects can also be used for procedural abstraction. from this paper

It is taught in class that data abstraction is the methodology to create barrier between "how data values are used" and "how data values are represented". It is taught that, an abstract data type(ADT) is some collection of selectors and constructors, together with some behaviour conditions (invariants).

It is compound data that needs data processing which actually enables to think about data abstraction because the user would like to use this compound data as single unit.

Building "data abstraction" and "ADT" for "rational number" using python objects

#Use
def mulRational(x, y):
    """Violate abstraction by using other than constructor and selectors"""
    return Rational(getNumer(x)*getNumer(y), getDenom(x)*getDenom(y)) #x and y are abstract data

def addRational(x, y):
    """Violate abstraction by using other than constructor and selectors"""
    nx, dx = getNumer(x), getDenom(x)
    ny, dy = getNumer(y), getDenom(y)
    return Rational(nx * dy + ny * dx, dx * dy)

def eqRational(x, y):
    """Violate abstraction by using other than constructor and selectors"""
    return getNumer(x) * getDenom(y) == getNumer(y) * getDenom(x)

def toString(x):
    """Violate abstraction by using other than constructor and selectors"""
    return '{0}/{1}'.format(getNumer(x), getDenom(x))

#Representation
# Representation is provided by constructors and selectors using tuples

#Constructor
from fractions import gcd
def Rational(n, d):
    """Construct a rational number x that represents n/d."""
    g = gcd(n, d)
    return (n // g, d // g) #this is concrete representation of a rational number


#Selector
from operator import getitem
def getNumer(x):
    """Return the numerator of rational number x."""
    return getitem(x, 0)

#Selector
def getDenom(x):
    """Return the denominator of rational number x."""
    return getitem(x, 1)

Rational number has compound data (n,d) that enables to build data abstraction, Because user would like to use this compound data as single unit.

Below implementation is done with different "representation".

#Use
def mulRational(x, y):
    """Violate abstraction by using other than constructor and selectors"""
    return pair(getitem_pair(x,0) * getitem_pair(y,0), getitem_pair(x,1) * getitem_pair(y,1))

def addRational(x, y):
    """Violate abstraction by using other than constructor and selectors"""
    nx, dx = getitem_pair(x,0), getitem_pair(x,1)
    ny, dy = getitem_pair(y,0), getitem_pair(y,1)
    return pair(nx * dy + ny * dx, dx * dy)

def eqRational(x, y):
    """Violate abstraction by using other than constructor and selectors"""
    return getitem_pair(x,0) * getitem_pair(y,1) == getitem_pair(y,0) * getitem_pair(x,1)

def toString(x):
    """Violate abstraction by using other than constructor and selectors"""
    return '{0}/{1}'.format(getitem_pair(x,0), getitem_pair(x,1))


#Representation
#Representation is provided by constructors and selectors using higher order functions

#Constructor 
def pair(x, y):
    from fractions import gcd
    g = gcd(x, y)
    """Return a functional pair"""
    def dispatch(m):  
        if m == 0:
            return x // g

        elif m == 1:
            return y // g
    return dispatch

#Selector
def getitem_pair(p, i):
    """Return the element at index of pair p"""
    return p(i)

In the above code, Constructors & selectors constitute ADT.

In the above two implementations:

There is an abstract data type that supports an invariant:

a) If we construct rational number x from numerator n and denominator d, then getNumer(x)/getDenom(x) must equal n/d.

b) If we construct rational number x from numerator n and denominator d then getitem_pair(p, 0)/getitem_pair(p, 1) must equal n/d

In the above 2 implementations we have 3 abstraction barriers:

  1. Parts of the program that work with rational numbers to perform computation use mulRational(..), addRational(..), eqRational(..) && toString(..) computation processes only.

  2. Parts of the program that implement mulRational(..) use constructor and selectors only.

  3. Parts of the program that implement constructors & selectors would use built in datatypes or built-in functions.

My question:

Is my understanding correct on designing data abstraction and ADT for rational numbers? I disagree with below three points.

1) This paper says: "While objects and ADTs are fundamentally different, they are both forms of data abstraction."

2) This paper: "An abstract data type is a structure that implements a new type by hiding the representation of the type and supplying operations to manipulate its values."

3) This paper says: "Abstract data types depend upon a static type system to enforce type abstraction."

Reason,

In the above code,

Firstly, Data abstraction has it's own identity by enforcing a barrier between "representation" and "use". Each above implementation has set of "objects" that build Data abstraction and supply operations[mulRational]

Secondly, ADT is just the collection of "constructor" and "selectors" which support some invariants to validate the "representation". ADT in the above code did not implement a new type. ADT did not supply operations. ADT does not require type system.

10
  • Why have you not created a class in Python? That would be the closest match to your Java version, and you can have @property for the read-only numerator and denominator and implement the "magic methods" to allow e.g. half + third rather than addRational(half, third) (see the style guide, too).
    – jonrsharpe
    Mar 5, 2015 at 16:54
  • 1
    Then could you please make that clearer? Why add the difference between two different languages into the mix, if really you're interested in FP vs. OOP? And, if you do want to mix languages, why do you keep using Python for FP (rather than, say, an actual functional language)?
    – jonrsharpe
    Mar 5, 2015 at 16:58
  • @jonrsharpe title question is paradigm/language neutral. language/paradigm is of least concern here. For this query, if language/paradigm changes, It is just different style of implementation. For me, most important, Did I understand "How/why" aspect in title question? Mar 5, 2015 at 17:07
  • 2
    If you don't care about the language or paradigm then use one. Why clutter the question with three implementations, use two languages and mention two paradigms when you could've just used 2 implementations in the same language and not mentioned paradigms at all?
    – Doval
    Mar 5, 2015 at 17:10
  • I don't understand how that's relevant to my question.
    – Doval
    Mar 5, 2015 at 17:27

1 Answer 1

3

Let's first clear up some of your terminology.

Abstraction is a technique for managing complexity of computer systems. It works by establishing a level of complexity on which a person interacts with the system, suppressing the more complex details below the current level.

So, for example, writing a method that hides some complex functionality is an abstraction. You call the method and it performs its function, without concerning you about the details hidden in the method.

Data abstraction is just that same process applied to data, in the form of data structures.

An Abstract Data Type (ADT) is a mathematical model for a certain class of data structures that have similar behavior; or for certain data types of one or more programming languages that have similar semantics.

An abstract data type is defined only by the operations that may be performed on it and by mathematical pre-conditions and constraints on the effects (and possibly cost) of those operations.

Now then. Let's look at your assertions:

Parts of the program that work with rational numbers to perform computation use mulRational(..), addRational(..), eqRational(..) && toString(..) computation processes only

Right, so you've defined an API that provides certain operations, hiding the complexity behind method calls.

Parts of the program that create rational number use, "constructor" and parts of the program that implement more new rational operations like divideRational(..) use, "selectors" only.

That seems consistent with the idea of an ADT being defined by its operations (among other things).

Parts of the program that implement constructors & selectors would use built in datatypes or built-in functions.

I would consider that self-evident. Every programming language eventually resolves to a set of primitives upon which all other abstractions are built.

If you're getting the feeling that Abstract Data Types are merely a sophisticated form of encapsulation, you're right.

6
  • To elaborate: Abstract Data Types are one of two currently popular forms of Data Abstraction, the other one being Objects. Abstract Data Types and Objects are in some sense duals. Mar 6, 2015 at 1:11
  • @JörgWMittag Wrt your point: Abstract Data Types, as the name implies, achieve abstraction using static types, but Python is untyped (in the strict mathematical type theoretic sense) or more precisely dynamically typed, so it cannot possibly support ADTs. As per above code, "Abstract Data Type" constitutes constructor & selector that supports invariants. How do I think about "Objects" in the above code? Mar 6, 2015 at 6:44
  • @overexchange: the defining feature of object-oriented data abstraction is procedural abstraction. It's all explained fairly well in On Understanding Data Abstraction, Revisited by William R. Cook. Mar 6, 2015 at 12:13
  • @JörgWMittag As per this exercise this is how it is taught in class about "data abstraction" and "ADT". Mar 6, 2015 at 12:16
  • 2
    Yes, and as Cook explains in his paper, data abstraction is often taught wrong. Mar 6, 2015 at 12:23

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.