1
\$\begingroup\$

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

Below is the given exercise:

Exercise 5: Segments

Consider the problem of representing line segments in a plane. Each segment is represented as a pair of points: a starting point and an ending point. Define a constructor make-segment and selectors start-segment and end-segment that define the representation of segments in terms of points. Furthermore, a point can be represented as a pair of numbers: the x coordinate and the y coordinate. Accordingly, specify a constructor make-point and selectors x-point and y-point that define this representation. Finally, using your selectors and constructors, define a procedure midpoint-segment that takes a line segment as argument and returns its midpoint (the point whose coordinates are the average of the coordinates of the endpoints)

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". Also, an abstract data type 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.

Below code is building "data abstraction" and "ADT" for "line segments" using python objects

# Representation - start
#Constructor
def make_point(x, y):
    return (x, y)

#Selector
def x_coordinate(point):
    return point[0]

#Selector
def y_coordinate(point):
    return point[1]


#Constructor
def make_segment(point1, point2):
    return (point1, point2)

#Selector
def start_segment(lineSegment):
    return lineSegment[0]

#Selector
def end_segment(lineSegment):
    return lineSegment[1]

#Representation - end

#Use -start
def midpoint_segment(lineSegment):
    return make_point((x_coordinate(start_segment(lineSegment)) + x_coordinate(end_segment(lineSegment)))/2, (y_coordinate(start_segment(lineSegment)) + y_coordinate(end_segment(lineSegment)))/2)

#Use - end


#Driver code from user
p1 = make_point(1,2)
p2 = make_point(3, 4)
line = make_segment(p1, p2)
midpoint = midpoint_segment(line)
print(midpoint)

In the above code, constructor and selectors constitute ADT.

In the above two implementations:

  1. There is an abstract data type that supports an invariant1:

    If we construct point p from x-coordinate a and y-coordinate b, then x_coordinate(p), y_coordinate(p) must equal a, b

  2. There is an abstract data type that supports an invariant2:

    If we construct a line segment l from point p1 and point p2, then start_segment(l)______end_segment(l) must equal p1______p2

In the above implementation:

  1. Parts of the program that use line segments to perform computation use midpoint_segment.

  2. Parts of the program that implement midpoint_segment use constructor and selectors only

  3. Parts of the program that create line segments use constructor make_segment

  4. Parts of the program that implement constructor for line segment use tuple

  5. Parts of the program that implement selectors for line segments use [] for indexing tuples.

So, above implementation has set of "objects" that build "Data abstraction"

Is my understanding correct on designing data abstraction and ADT for line segments?

\$\endgroup\$
1
\$\begingroup\$

Although your question indicates that you are using a functional paradigm, you are not. You are using a procedural paradigm.

Functional programming is about declaring functions, and then passing those functions in to other places to be used as modifiers and manipulators for other processes. Terms like 'lambdas', and 'closures', 'optionals' or 'monads' are required.

Procedural programming is the act of defining a process to follow, sometimes returning a value, but "I take this data and process it following this defined routine, and I get the results I want."

Procedural programming often has functions declared, but the functions are not used as parameters to other functions.

You do not pass any functions in as parameters, you are not using a "functional paradigm". You are using a "procedural paradigm".

See Wikipedia's comparison between Functional and Procedural programming.

Your code is a very poor implementation of a Functional paradigm.

On the other hand, as a Procedural implementation, it is actually quite good, except for the get_midpoint method, which is implemented on a single line which is too long, and makes it hard to read with all the nested braces on one line.

def midpoint_segment(lineSegment):
    start = start_segment(lineSegment);
    end = end_segment(lineSegment)
    xsums = x_coordinate(start) + x_coordinate(end)
    ysums = y_coordinate(start) + y_coordinate(end)
    return make_point(xsums / 2, ysums / 2)
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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