Workdays transformation to a new language platform Developing

















































- Slides: 49
Workday's transformation to a new language platform Developing a full-fledged programming language with MPS
Safe Harbor Statement This presentation may contain forward-looking statements for which there are risks, uncertainties, and assumptions. If the risks materialize or assumptions prove incorrect, Workday’s business results and directions could differ materially from results implied by the forward-looking statements. Forward-looking statements include any statements regarding strategies or plans for future operations; any statements concerning new features, enhancements or upgrades to our existing applications or plans for future applications; and any statements of belief. Further information on risks that could affect Workday’s results is included in our filings with the Securities and Exchange Commission which are available on the Workday investor relations webpage: www. workday. com/company/investor_relations. php Workday assumes no obligation for and does not intend to update any forward-looking statements. Any unreleased services, features, functionality or enhancements referenced in any Workday document, roadmap, blog, our website, press release or public statement that are not currently available are subject to change at Workday’s discretion and may not be delivered as planned or at all. Customers who purchase Workday, Inc. services should make their purchase decisions upon services, features, and functions that are currently available.
Bircan Copur Antonio Gliubich Alexey Yashin Software Development Engineer Workday Confidential
Agenda What is Workday & Overview of our legacy code YP – As a platform and a language developed with MPS Updating instances in an immutable world Handling translations in YP Implementing generics with MPS Workday Confidential
Workday ● Established 2005 ● Provides business apps: ● Human Capital Management, Payroll, ● Financial Management, Analytics, ● Student, Learning, Recruiting … ● Saa. S, in the cloud ● multi-tenant-per server ● Lots of satisfied customers ● Airbnb, Adobe, Amazon, Siemens, Wal-Mart
Applications Development ● Defining business logic as metadata ● Customers define: ● Workers, Organizations, Compensation Plans, … ● Developers define: ● Classes, Methods, Tasks & Pages, … ● Xpress. O is a bootstrapped language ● ● “Steve Morgan” is an instance of the Worker class. The “Worker” class is an instance of the “Class” class. ● Learn Xpress. O in a 6 -week “boot camp” ● Lots of room for improvement of developer experience here
What Exactly is Xpress. O? (XO) ● Editable through web forms, mostly ● Like this “GRA - Get Referenced Attribute Method”
What Exactly is Xpress. O? (XO)
Introduction to YP What is it? • YP is a new evaluation runtime for our Xpress. O language • YP is a new compiler for our Xpress. O language. • YP is a language and IDE for developers. (t. YPe)
Introduction to YP What is it? Workday Confidential
Updating instances in an immutable world Challenges • YP assumes immutability! ‒ Expression based ‒ Local variables cannot be changed ‒ Functions are transparent, do not have side effects ‒ Can rearrange code for more efficient execution
Separating Procedures and Functions Procedures Functions may not call Procedures
Derived PUs Derived Instance apply Actual Instance let worker. Builder = new Worker { name = “Logan Mc. Neil” team = “YP EMEA” } apply worker. Builder • Still part of the program flow – has side effects • Still means we lose immutability
Solution • NO apply-ing whatsoever! ‒ YP separates update “instructions” from update “execution” ‒ Allow creating instructions for updates only ‒ Pass those instructions around in functions without any side effects ‒ Whoever is invoking the function is responsible for applying § UI task, REST API, etc.
The New Way
Syntax
Token • To represent an entity that does not exist yet: ‒ token<Workdog>() • To represent an entity that exists: ‒ workdog. Instance. get. Token() • Has type Token<Workdog>
Create/Delete/Set Update • To create an entity: ‒ create workdog. Token • To delete an entity: ‒ delete workdog. Token • To update attribute and relationship values ‒ set workdog. Token. name = “Snoopy” ‒ set workdog. Token. has. Snapshot = snapshot. Instance
Binding Updates Together Sequence Update (create workdog. Token). then(set workdog. Token. name = “Snoopy”). then(set workdog. Token. snapshot = snapshot. Instance) or with some syntactic sugar: update { create workdog. Token set workdog. Token. name = “Snoopy” set workdog. Token. snapshot = snapshot. Instance }
Binding Updates Together Chain Update update { create breed. Token set breed. Token. breed. Name = “Dalmatian” }. chain((breed) => { create workdog. Token set workdog. Token. name = “Spots the ” +breed. name })
Binding Updates Together Update each worker. has. Workdog. update. Each((workdog) => { let workdog. Token = workdog. get. Token() set workdog. Token. name = worker. name +”’s ” +workdog. name })
Unit Testing YP Updates • Testing updates in XO is… unpleasant - you cannot unit test them! • We can run update instructions in tests against mock data and verify them • Totally offline! No object model/real data is needed for testing!
Developer Feedback • “Early Adopter“s are using YP for a few months now • Some initial confusion around the concept of “Token“s • Overall very positive reception • Unit testing is a real improvement Workday Confidential
Handling Translations in YP
Localization vs Translation Localization • Date, time, number formats • Contact information • Weights, measurements • Translations • …
Coding vs Spoken Languages
Translation Process code + code translations
Translation Process with XO • Translation Tools are written in XO: translators (contractors) access Workday UI to enter translations • Translations are basically code changes (metadata changes, exactly as any code change made by developers via Workday UI) • Changes get “merged” into master by internal resources master WD UI XO Metadata (code + Metadata translations) WD UI XO WD UI Translation Metadata metadata
Translations with YP - Prototypes • Created several prototypes ‒ Tried to envision the same approach with YP, storing translations in YP AST ‒ Enriched our test language to specify a language tranlsatable. Text { expression = "Hi [name]!" translations = { de_DE : "Hallo [name]!" it_IT : "Ciao [name]!" } } let welcome. Message = "Hi" + this. get. Name() + "!" { translations = { de_DE : "Hallo" + this. get. Name() + "!" it_IT : "Ciao" + this. get. Name() + "!" } } test Translations { … case german { let result = person. get. Welcome. Message("Joe"). translate() assert result == "Hallo Joe!" : : result } de_DE }
Translation Process with Prototypes • Tried to envision the overall Translation Process using those YP prototypes t. Ype YP YP AST (code + YP AST translations) t. Ype YP ver control YP AST translations t. Ype
Prototypes Evaluation ‒ Translators would have to use t. Ype or we would need some import process to add translations to the AST ‒ No plans to change the process or translation tools ‒ Larger AST ‒ Risk to break AST ‒ AST Versions could be out of sync t. Ype YP YP AST (code + YP AST translations) t. Ype YP ver control YP AST translations t. Ype
A Different Approach • Translations outside YP AST • Generic interface to load translations Code YP compiler Translations + Xpress. O external Tools … loader runtime
Translatable Text Definition in YP • New type for strings to be translated • Allows to uniquely identify what needs to be translated • Handles both strings and text expressions (e. g. “Hello [name]!”) Translations code YP + translatable. Text WLCM_MSG = "Hi [name]!" Xpress. O external Tools …
Translations in YP • Not included in the AST • Just strings keyed by language code and definition • Retrieved with a generic interface, from XO metadata, files, etc. • Translations are retrieved and stored at deployment and available at runtime code YP Translations + Xpress. O external Tools … WLCM_MSG, de_DE, "Hallo [name]!” WLCM_MSG, it_IT, “Ciao [name]!”
MPS for YP Translations • Prototyping • Concepts to define and easily identify a translatable vs non-translatable text • Human-readable identifier • Parsing of text expressions let t = translatable. Text WLCM_MSG = "Hi [name]!” • Syntax to resolve the translation let text = t. translate(“de_DE”)
Implementing Generics for YP
Motivation: Why do we need generics? In Java generics enable types (classes and interfaces) to be parameters when defining classes, interfaces and methods. Which means: • • ability to write generic algorithms stronger type checks at compile time
Problem We wanted: • to allow the application developers to create libraries of generic algorithms (e. g. for collections) and to add type parameters in their YP code. • to make YP similar to Java or C# in terms of generics and object oriented features which those have.
Solution Approach Given that a major part of YP is implemented in MPS we decided to use the MPS inference rules and type system language features to add support for generics in YP language.
Generics from the perspective of app dev • • you can have simple type parameters (something like <A>) optionally you can define bounds, as well (e. g. <A extends Base>) Which challenges does it have?
Implementation details / challenges function <A, B> f(a 1: A, a 2: A, b: B): A f(1, 2, “text”) f(1, ”wrong”, ”text”) fails Since a 1 and a 2 are referencing the same type parameter definition, they should be assigned the same runtime type variable.
Runtime type variables function <A, B> f(a 1: A, a 2: A, b: B): A val x: number = f(1, 2, ”text”) • • • Introduce runtime type vars for each type parameter definition Traverse parameter types and expand generics Establish inferences with subtyping between assignments and parameter types
Type Inference For each type parameter definition in the referenced parameterized type: • If type argument is concrete (e. g. text or number) → do nothing with the type • Otherwise, create a type var (Runtime. Type. Variable) and infer on bounds. When typevar is concrete, assign it to the type parameter definition
Type Inference: Code sample var T; // runtime type variable // Apply inference on bounds foreach bound in type. Param. Def. bounds { infer type. Param. Def : <<=: bound; } type. Param. Def = T; // Solve inequalities by establishing the constraints against T when concrete (T as type. Arg) { // If type system solver succeeds with T, // that is, it can come up with a concrete type. Param. Def = type. Arg; }
Type Inference The block when concrete is asynchronous which means type. Param. Def will be assigned to a concrete type at some point in the future (if the resolution will ever happen). Type system is trying to find a solution that satisfies all inequalities (according to subtyping rules). • If solving succeeds: runtime type variable gets assigned a concrete type (e. g. number, text) • If solving fails: runtime type variable just remains as it is (e. g. g 4)
Type Inference The mapping between type parameters and their runtime type variables would look like this: {A -> y 26, B -> t 38, X -> d 7} And when the corresponding when concrete blocks get executed (and the inequalities solving is done) we end up with something like: {y 26 -> number, t 38 -> text}
Checking rule Once the types are concrete we might want to show a custom error message to the user if the types don’t match by checking them in a checking rule. if (!is. Subtype(arg. Type : <=: param. Type)) error
Evaluation Where are generics mostly used in YP? util library Since the YP application developers very often rely on the data structures like these, the generics functions are used very intensively by almost any YP-based project.
• Type inference and runtime type vars • Generics in YP • Usages in the early adoption projects

















































