Meta tags:
description= Data-oriented programming focuses on modeling data as data (instead of as objects). Records for data and sealed types for alternatives let us model immutable data where illegal states are unrepresentable. Combined with pattern matching we get a safe, powerful, and maintainable approach to ad-hoc polymorphism that lets us define operations on the data without overloading it with functionality.;
Headings (most frequently used words):
oriented, programming, in, practice, data, inside, java, newscast, 29, intro, outro, ii, iii, versus, object,
Text of the page (most frequently used words):
the (64), node (63), and (53), java (44), var (39), that (38), data (38), new (38), case (33), right (25), left (24), with (23), user (23), record (22), for (21), #oriented (20), mulnode (19), programming (18), constnode (18), value (18), implements (17), get (17), name (16), string (16), differentiate (16), but (15), exp (15), double (15), pattern (14), optional (14), project (14), records (12), matching (12), this (12), sealed (12), model (12), practice (11), are (11), can (11), match (11), code (11), addnode (11), return (11), evaluate (11), finduser (11), type (10), val (10), types (10), there (9), expnode (9), interface (9), such (9), matches (9), more (8), into (8), let (8), varnode (8), negnode (8), int (8), switch (8), vars (8), class (8), matchresult (8), like (7), you (7), when (7), some (7), about (7), cost (7), our (7), brian (6), share (6), have (6), boundaries (6), from (6), where (6), want (6), object (6), its (6), one (6), also (6), use (6), make (6), say (6), method (6), without (6), each (6), check (6), public (6), should (6), inside (5), newscast (5), two (5), techniques (5), dop (5), methods (5), elsewhere (5), fuzzymatch (5), result (5), api (5), just (5), private (5), presence (5), then (5), null (5), community (5), junit (5), your (4), see (4), not (4), time (4), now (4), clear (4), patterns (4), express (4), these (4), way (4), maybe (4), what (4), none (4), final (4), alternatives (4), works (4), immutable (4), privacy (3), youtube (3), outro (3), process (3), hoc (3), often (3), outside (3), oop (3), they (3), tools (3), programs (3), smaller (3), need (3), same (3), system (3), which (3), isn (3), seen (3), principles (3), modeling (3), complex (3), libraries (3), powerful (3), versus (3), visitors (3), domain (3), much (3), better (3), turn (3), implementations (3), add (3), functionality (3), here (3), few (3), would (3), field (3), fields (3), even (3), all (3), something (3), iii (3), exactmatch (3), nomatch (3), call (3), how (3), itself (3), fuzzy (3), constructor (3), exact (3), first (3), boolean (3), ispresent (3), could (3), states (3), well (3), intro (3), watch (3), follow (3), pioneer (3), demos (3), streams (3), core (3), clean (3), license (2), rss (2), stackoverflow (2), github (2), twitch (2), discord (2), mastodon (2), bluesky (2), today (2), article (2), video (2), again (2), world (2), different (2), small (2), service (2), has (2), relatively (2), require (2), solution (2), why (2), write (2), best (2), large (2), program (2), because (2), still (2), reason (2), whole (2), entities (2), equals (2), diff (2), before (2), approach (2), was (2), polymorphism (2), apply (2), operations (2), algebraic (2), don (2), those (2), expression (2), good (2), users (2), specific (2), operation (2), example (2), variables (2), modeled (2), rank (2), processmatches (2), fuzzymatches (2), processmatch (2), processnomatch (2), list (2), create (2), while (2), might (2), checking (2), matchresulttype (2), throw (2), found (2), try (2), instead (2), flag (2), too (2), avoid (2), only (2), error (2), components (2), else (2), wrapper (2), start (2), four (2), put (2), illegal (2), unrepresentable (2), boundary (2), out (2), give (2), models (2), classes (2), behavior (2), end (2), objects (2), comments (2), openjdk (2), words (2), active (2), various (2), platforms (2), space (2), notified (2), publish (2), content (2), post (2), videos (2), talks (2), libfx (2), args (2), year (2), serialization (2), reflection (2), valhalla (2), panama (2), loom (2), leyden (2), amber (2), performance (2), ramp (2), migration (2), meta (2), maven (2), lambda (2), javafx (2), next (2), basics (2), j_ms (2), generics (2), documentation (2), deprecation (2), libs (2), collections (2), architecture (2), tags (2), javascript (2), contact, imprint, theory, read, link, description, leave, comment, friends, enemies, weeks, long, building, simpler, services, subsystems, plain, involving, may, offer, straighter, path, importantly, odds, granularities, situations, freely, mix, them, fit, gotten, within, less, internal, larger, surface, area, speaking, dealing, count, fitting, cleanly, overall, trend, increases, problems, optimal, examples, discuss, doesn, look, particularly, defining, defending, maintenance, encapsulation, compilation, compatibility, etc, dividing, parts, helps, manage, complexity, enables, modular, reasoning, ability, analyze, part, essential, creating, rich, frameworks, special, cases, had, standard, writing, clearly, flexible, built, visitation, imposes, strict, constraints, supports, crucially, composes, nested, conditions, messier, using, concise, than, visitor, math, function, thanks, power, mentioned, earlier, createinvoice, invoice, estimateresourceusage, resources, canvas, style, direction, draw, void, evaluateincluster, evaluateparallel, stands, subexpressions, parallel, machine, cluster, format, estimate, computation, resource, bill, their, computations, run, engine, lot, very, diverse, nice, little, expr, probably, last, akin, application, arithmetic, expressions, trees, inner, addition, multiplication, leaves, numbers, accidentally, once, implementation, encountered, hierarchy, browsing, javadoc, immediately, obvious, handle, encoding, readability, ease, encodings, easier, virtually, writes, requirements, careful, enum, accessors, exception, three, factory, looks, property, distinguishes, between, were, close, interest, glossing, over, step, cram, single, pretty, note, longer, offers, access, unlike, forget, contract, lifted, expressing, bad, since, mostly, functional, will, cope, instanceof, compile, needs, present, component, said, oopsie, runtimeexception, alternatively, contains, expose, potential, work, ish, requirement, enforced, potentially, lead, people, calling, getting, hit, exceptions, happen, simple, returns, sometimes, course, signal, absence, prone, frustrating, easy, domains, erroneous, simply, cannot, represented, immutability, eliminates, many, common, sources, errors, does, avoiding, allow, invalid, injecting, ensure, valid, done, validation, applies, universally, instances, received, another, source, validate, worry, changing, under, help, shallowly, requires, discipline, letting, mutability, inject, thing, choose, names, choices, search, alternative, limited, implementing, derived, quantities, formatting, nothing, formulates, term, totally, unrelated, design, keep, apart, encourages, separating, logic, acts, hinges, combination, called, adt, short, uses, language, features, shape, relates, deep, come, motivation, later, hold, until, dive, welcome, everyone, cover, recent, developments, nicolai, parlog, developer, advocate, oracle, gonna, learn, learned, days, ago, goetz, fact, most, things, his, loud, toc, table, contents, policy, cookie, remember, always, embed, focuses, combined, safe, maintainable, lets, define, overloading, 2022, slides, upcoming, past, schedule, recordings, virtual, threads, vector, structured, concurrency, lilliput, galahad, babylon, conversation, book, club, jms, newsletter, blog, posts, testing, rant, jigsaw, jdeps, impulse, default, lang, review, site, enabled, nipafx,
Text of the page (random words):
t lilliput project loom project panama project valhalla records reflection serialization streams structured concurrency switch techniques tools turn of the year var vector virtual threads recordings streams schedule code demos demos demos junit pioneer record args libfx talks my talks past upcoming slides about about me license privacy 2022 07 14 data oriented programming inside java newscast 29 video records dop pattern matching patterns techniques data oriented programming focuses on modeling data as data instead of as objects records for data and sealed types for alternatives let us model immutable data where illegal states are unrepresentable combined with pattern matching we get a safe powerful and maintainable approach to ad hoc polymorphism that lets us define operations on the data without overloading it with functionality always embed videos and give me a cookie to remember privacy policy watch on youtube data oriented programming inside java newscast 29 table of contents intro data oriented programming in practice i in practice ii in practice iii versus object oriented programming outro share follow share this post with your community i m active on various platforms watch this space or follow me there to get notified when i publish new content toc intro data oriented programming in practice i in practice ii in practice iii versus object oriented programming outro s f share this post with your community i m active on various platforms watch this space or follow me there to get notified when i publish new content intro welcome everyone to the inside java newscast where we cover recent developments in the openjdk community i m nicolai parlog java developer advocate at oracle and today we re gonna learn about data oriented programming well i learned about it a few days ago in brian goetz s article data oriented programming in java and now i want to share that with you in fact brian put most things so well that i ll often just say his words out loud so let s see what dop is all about how it uses new language features like records and pattern matching to shape our code and how it relates to oop object oriented programming that is i ll start at the deep end and come to the motivation later so hold your but objects comments until the end ok then let s dive right in data oriented programming data oriented programming is a relatively new term and by the way totally unrelated to data oriented design so keep those two apart it encourages us to model data as immutable data separating it from the domain logic that acts on it it hinges on sealed types and records the combination of which is called algebraic data types adt for short to express data and pattern matching to add behavior to it brian formulates four principles model the data the whole data and nothing but the data records should model data make each record model one thing make it clear what each record models and choose clear names for its components where there are choices to be modeled such as a search can result in no match an exact match or a few fuzzy matches model these as sealed classes and model each alternative with a record behavior in record classes should be limited to implementing derived quantities from the data itself such as formatting data is immutable if we want to model data we should not have to worry about our data changing out from under us records give us some help here as they are shallowly immutable but it still requires some discipline to avoid letting mutability inject itself into our data models validate at the boundary before injecting data into our system we should ensure that it is valid this might be done in the record constructor if the validation applies universally to all instances or by the code at the boundary that has received data from another source make illegal states unrepresentable records and sealed types make it easy to model our domains in such a way that erroneous states simply cannot be represented just as immutability eliminates many common sources of errors in programs so does avoiding modeling techniques that allow us to model invalid data so that s brian s four principles for data oriented programming in java let s put these into practice in practice i let s start with something simple say you have a method that returns a result say a user but sometimes there isn t one what should be the return type of course it could just be user and we return null to signal absence but that s error prone and frustrating public user finduser string id elsewhere var user finduser id if user null process user alternatively we could create a wrapper type that contains the user if there is one that wrapper would need to expose a method to get the potential user and a boolean flag to check its presence first maybe you ve seen a type like that it would work ok ish but the requirement to first check presence and then get isn t enforced by the api and could potentially lead to people just calling get and then getting hit by exceptions maybe you ve seen that happen too class optional t private final t value public optional t value this value value public t get if value null throw new runtimeexception else return value public boolean ispresent return value null public optional user finduser string id elsewhere var user finduser id if user ispresent process user get oopsie user get let s try something else brian said we should use sealed types to express alternatives so we make optional a sealed interface with two implementations none a record without components some a record with the present value as its only component sealed interface optional t no get record none t implements optional t record some t t value implements optional t constructor needs to null check value public optional user finduser string id elsewhere var user finduser id user get compile error no method optional get if user instanceof some user u only this works use u note that optional no longer offers a method to get a value that i can call without checking for presence first now to get access to the value i have to do a type check and unlike the check for presence i can t forget that so the api contract check presence then get was lifted into the type system by expressing the two alternatives of value and no value as types instead of a boolean flag too bad that we can t get this optional but since we can also mostly avoid ispresent then get with optional s functional api which is why i like it so much i will cope in practice ii we can apply that same pattern to a more complex example say we have an api that looks some entities up by a property say users by name and distinguishes between no match found exact match found and no exact match but there were close matches in the interest of time i m glossing over the step where i try to cram these alternatives into a single type you can see it here and it works but it s not pretty class matchresult t private final matchresulttype type private final t match private final list fuzzymatch t matches private constructor and factory methods for the three result types accessors that throw exception when no such result enum matchresulttype none one fuzzy record fuzzymatch t value int rank matchresult user finduser string name elsewhere var r finduser name be careful not to just call r match or r matches without checking r type switch r type case none processnomatch case one processmatch r match case fuzzy processmatches r matches the better solution is to once again create a sealed interface matchresult with an implementation for each case nomatch exactmatch and fuzzymatch if we encountered this return hierarchy while browsing the code or the javadoc it s immediately obvious what this method might return and how to handle its result while such a clear encoding of the return value is good for the readability of the api and for its ease of use such encodings are also often easier to write because the code virtually writes itself from the requirements sealed interface matchresult t record nomatch t implements matchresult t record exactmatch t t match implements matchresult t record fuzzymatches t list fuzzymatch t matches implements matchresult t record fuzzymatch t t value int rank matchresult user finduser string name elsewhere var r finduser name no way to accidentally call r match or r matches there are no such methods also we don t even need r switch finduser name case nomatch processnomatch case exactmatch var user processmatch user case fuzzymatches var matches processmatches matches in practice iii for the last example let s model something that s more akin to an application specific domain an arithmetic expression with variables such expressions are best modeled as trees where each inner node is an operation like addition or multiplication and the leaves are numbers or variables x² 2 x exp x 2 2 x even without sealed types and records we d probably all model that as an interface node with specific implementations for each operation and value interface node class addnode implements node with fields node left node right class mulnode implements node with fields node left node right class expnode implements node with fields node node int exp class negnode implements node with field node node class constnode double val implements node with field double val class varnode string name implements node with field string name x² 2x var expr new addnode new expnode exp new varnode x x new constnode 2 2 new mulnode new constnode 2 2 new varnode x x now say you want to evaluate such an expression it stands to reason that an evaluate method on node would be a good way to do that but maybe we also want to evaluate subexpressions in parallel on the same machine or maybe in a small cluster are that two more methods we also want to differentiate and format and estimate computation time and resource use bill users for their computations that they run on our engine that s a lot of very diverse functionality to add to our nice little node interface interface node double evaluate double evaluateparallel double evaluateincluster node differentiate string var void draw direction d style s canvas c resources estimateresourceusage invoice createinvoice user u but thanks to the power of algebraic data types and pattern matching we don t have to do that make node sealed turn the implementations into records and use pattern matching in methods outside of these types to add functionality here are a few of those that i mentioned earlier sealed interface node record addnode node left node right implements node record mulnode node left node right implements node record expnode node node int exp implements node record negnode node node implements node record constnode double val implements node record varnode string name implements node operations double evaluate node n function string double vars return switch n case addnode var left var right evaluate left vars evaluate right vars case mulnode var left var right evaluate left vars evaluate right vars case expnode var node int exp math exp evaluate node vars exp case negnode var node evaluate node vars case constnode double val val case varnode string name vars apply name node differentiate node n string v return switch n case addnode var left var right new addnode differentiate left v differentiate right v case mulnode var left var right new addnode new mulnode left differentiate right v new mulnode differentiate left v right case expnode var node int exp new mulnode new constnode exp new mulnode new expnode node exp 1 differentiate node v case negnode var node new negnode differentiate node var case constnode double val new constnode 0 case varnode string name name equals v new constnode 1 new constnode 0 double cost node n return switch n case addnode var left var right 1 cost left cost right case mulnode var left var right 2 cost left cost right case expnode var node int exp exp cost node case negnode var node cost node case constnode double val 0 case varnode string name 0 before we had records and pattern matching the standard approach to writing code like this was the visitor pattern pattern matching is clearly more concise than visitors but it s also more flexible and powerful visitors require the domain to be built for visitation and imposes strict constraints pattern matching supports much more ad hoc polymorphism crucially pattern matching composes better we can use nested patterns to express complex conditions that can be much messier to express using visitors node differentiate node n string v return switch n case addnode var left var right new addnode differentiate left v differentiate right v special cases of k node or node k case mulnode var left constnode double val k new mulnode k diff left v case mulnode constnode double val k var right new mulnode k diff right v case mulnode var left var right new addnode new mulnode left differentiate right v new mulnode differentiate left v right case expnode var node int exp new mulnode new constnode exp new mulnode new expnode node exp 1 differentiate node v case negnode var node new negnode differentiate node var case constnode double val new constnode 0 case varnode string name name equals v new constnode 1 new constnode 0 versus object oriented programming now that we ve seen the principles and some examples let s discuss why we d want to write code like that doesn t look particularly object oriented to me object oriented programming is at its best when it s defining and defending boundaries maintenance boundaries encapsulation boundaries compilation and compatibility boundaries etc dividing a large program into smaller parts with clear boundaries helps us manage complexity because it enables modular reasoning the ability to analyze one part of the program at a time but still reason about the whole it s essential when modeling complex entities and when creating rich libraries powerful frameworks and large programs but programs have gotten smaller and within a small service there is less need for internal boundaries at the same time a smaller service has a larger surface area relatively speaking so it ll require more code dealing with data from or for the outside world where we can t count on it fitting cleanly into java s type system so overall there s a trend that increases the share of problems for which oop isn t the optimal solution so when we re building simpler services or subsystems that process plain ad hoc data often involving the outside world the techniques of data oriented programming may offer us a straighter path importantly dop and oop are not at odds they are different tools for different granularities and situations we can freely mix and match them as we see fit outro and that s it for today on the inside java newscast for more theory and practice on data oriented programming in java read brian s article link in the description leave a comment like the video share it with your friends and enemies i ll see you again in two...
|