DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports Events Over 2 million developers have joined DZone. Join Today! Thanks for visiting DZone today,
Edit Profile Manage Email Subscriptions Moderation Admin Console How to Post to DZone Article Submission Guidelines
View Profile
Sign Out
Refcards
Trend Reports
Events
Zones
Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Partner Zones AWS Cloud
by AWS Developer Relations
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Partner Zones
AWS Cloud
by AWS Developer Relations
  1. DZone
  2. Data Engineering
  3. Big Data
  4. Data Modeling in FP Vs. OOP

Data Modeling in FP Vs. OOP

Is object-oriented programming really all that useful? Check out this post on one developer's thoughts on functional programming and OOP.

John De Goes user avatar by
John De Goes
·
Sep. 04, 18 · Opinion
Like (4)
Save
Tweet
Share
10.50K Views

Join the DZone community and get the full member experience.

Join For Free

at scalapeño this year, i argued in my keynote speech that the best and most unique parts of scala are the ones suited to functional programming, including traits (when used for type classes, modules, and sum types), case classes (when used for product types), higher-kinded types, dot method syntax (which is useful for method chaining and namespacing), and various features of scala’s type system.

in the twitter aftermath that followed, i further argued that object-oriented programming — by which i mean inheritance hierarchies (typified by the scala collections inheritance hierarchy) and subtyping (beyond its use for modeling sum types, modules, and type classes) — isn’t useful. that is, it doesn’t have any real world practical benefits over functional programming.

some claimed without supporting evidence that scala’s embrace of object-oriented programming helps working programmers solve real problems. to settle the issue once and for all (at least for some people), i issued the following public challenge:

in a world of millions of object-oriented programmers, i received a grand total of 3 responses (!).

in this blog post, i’ll look at one of the responses and show how you can solve the same problem using standard techniques from functional programming. then, every reader can decide for themselves whether oop adds anything of value to what i have defined as the good parts of the scala programming language.

data modeling

the first response to my challenge was a problem in data modeling by christopher hunt , a veteran of lightbend:

sealed abstract class event(val id: int)

final case class countersupdated(
  override val id: int,
  counter: option[int]) extends event(id)

final case class deviceidupdated(
  override val id: int,
  deviceid: int) extends event(id)


this example uses inheritance, not for type classes, modules, or sum type emulation, but to provide the following benefits:

  1. the compile-time guarantee that every event has an id of type int , which means the same thing across every event.
  2. the flexibility for each event to have its own custom payload (for example, one has a counter: option[int] , and another has a deviceid: int ).

let’s take a look at how functional programming can provide us with these same benefits, without the use of inheritance.

naive solution

in functional programming, we might choose to naively model this problem with a single sum type:

data event
  = countersupdated int (maybe int)
  | deviceidupdated int int
// in scala 2.x:
sealed trait event
case class countersupdated(
  id: int, counter: option[int]) extends event
case class deviceidupdated(
  id: int, deviceid: int) extends event

// in scala 3.x:
enum event {
  case countersupdated(id: int, counter: option[int])
  case deviceidupdated(id: int, deviceid: int)
}


while this approach provides us with the ability to vary the payload for each type of event, we don’t have the compile time guarantee that each type of event has an event id.

we could regain this guarantee with classy lenses, but we don’t need anything as fancy as that: we just need to take advantage of the full power of algebraic data types to remove the duplication in our current data model.

idiomatic solution

in any case, where we have a sum type, whose terms share a common piece of data, we can apply a refactoring: we can extract a new product type with the common data and push the sum type deeper as another term of that product.

in this case, our event id is the common piece of data, so we can extract a product type that includes both the id and a new sum type that captures differences between different events:

data event = event int payload
data payload
  = countersupdated (maybe int)
  | deviceidupdated int
// in scala 2.x:
final case class event(id: int, payload: payload)
sealed trait payload
case class countersupdated(counter: option[int]) extends payload
case class deviceidupdated(deviceid: int) extends payload

// in scala 3.x:
final case class event(id: int, payload: payload)
enum payload {
  case countersupdated(counter: option[int])
  case deviceidupdated(deviceid: int)
}


this demonstrates simple refactoring. now, let's us not just vary the payload depending on the type of event, but let's have a compile-time guarantee that all events share common data.

compared with the object-oriented solution, the new data model is the same size (smaller in scala 3.x!), has all the benefits of the object-oriented solution and does not conflate abstraction (the capability to extract an id from a type) with the data model.

the new data model is squeaky clean and contains no logic, which is better reserved for type classes because it’s far more flexible and precisely models the problem domain!

while developers can argue which approach they prefer, it’s clear the object-oriented solution has no benefits over the functional programming solution.

summary

in this post, i showed how functional programming compares to object-oriented programming. rather than use a contrived example that might skew the results in favor of functional programming, i took my example from proponents of oop.

stay tuned for other posts in this series, where i look at other challenges problems. and, if you have some small, self-contained example and wonder how to do the same thing in functional programming, please post it in the comments below!

data modeling in fp vs oop was published on august 07, 2018 by john a de goes .


you might also enjoy

  • using zio with tagless-final
  • scala wars: fp-oop vs fp
  • bifunctor io: a step away from dynamically-typed error handling
Object-oriented programming Data (computing) Data modeling

Published at DZone with permission of John De Goes, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

Popular on DZone

  • Spring Boot vs Eclipse MicroProfile: Resident Set Size (RSS) and Time to First Request (TFR) Comparative
  • The Path From APIs to Containers
  • Cloud Performance Engineering
  • Building a Real-Time App With Spring Boot, Cassandra, Pulsar, React, and Hilla

Comments

Partner Resources

X

ABOUT US

  • About DZone
  • Send feedback
  • Careers
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 600 Park Offices Drive
  • Suite 300
  • Durham, NC 27709
  • support@dzone.com
  • +1 (919) 678-0300

Let's be friends: