blob: c573c1c941db721aec08b79a0686ad39196178cf [file] [log] [blame]
<!doctype html>
<html lang="en" class="no-js">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<link rel="icon" href="../../assets/images/favicon.png">
<meta name="generator" content="mkdocs-1.1.2, mkdocs-material-7.1.5">
<title>Object Language (EOL) - Epsilon</title>
<link rel="stylesheet" href="../../assets/stylesheets/main.bde7dde4.min.css">
<link rel="stylesheet" href="../../assets/stylesheets/palette.ef6f36e2.min.css">
<meta name="theme-color" content="#000000">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,400,400i,700%7CRoboto+Mono&display=fallback">
<style>:root{--md-text-font-family:"Roboto";--md-code-font-family:"Roboto Mono"}</style>
<link rel="stylesheet" href="../../assets/stylesheets/mermaid.css">
<link rel="stylesheet" href="../../assets/javascript/google-code-prettify/prettify.css">
<link rel="stylesheet" href="https://unpkg.com/mermaid@8.5.1/dist/mermaid.css">
<link rel="stylesheet" href="../../assets/stylesheets/slick.css">
<link rel="stylesheet" href="../../assets/stylesheets/slick-theme.css">
<link rel="stylesheet" href="../../assets/stylesheets/extra.css">
<script>
window.ga = window.ga || function() {
(ga.q = ga.q || []).push(arguments)
}
ga.l = +new Date
/* Setup integration and send page view */
ga("create", "UA-184785655-1", "auto")
ga("set", "anonymizeIp", true)
ga("send", "pageview")
/* Register handler to log search on blur */
document.addEventListener("DOMContentLoaded", () => {
if (document.forms.search) {
var query = document.forms.search.query
query.addEventListener("blur", function() {
if (this.value) {
var path = document.location.pathname;
ga("send", "pageview", path + "?q=" + this.value)
}
})
}
})
</script>
<script async src="https://www.google-analytics.com/analytics.js"></script>
</head>
<body dir="ltr" data-md-color-scheme="" data-md-color-primary="black" data-md-color-accent="orange">
<script>function __prefix(e){return new URL("../..",location).pathname+"."+e}function __get(e,t=localStorage){return JSON.parse(t.getItem(__prefix(e)))}</script>
<input class="md-toggle" data-md-toggle="drawer" type="checkbox" id="__drawer" autocomplete="off">
<input class="md-toggle" data-md-toggle="search" type="checkbox" id="__search" autocomplete="off">
<label class="md-overlay" for="__drawer"></label>
<div data-md-component="skip">
<a href="#the-epsilon-object-language-eol" class="md-skip">
Skip to content
</a>
</div>
<div data-md-component="announce">
</div>
<header class="md-header" data-md-component="header">
<nav class="md-header__inner md-grid" aria-label="Header">
<a href="../.." title="Epsilon" class="md-header__button md-logo" aria-label="Epsilon" data-md-component="logo">
<img src="../../assets/images/epsilon-white-background.png" alt="logo">
</a>
<label class="md-header__button md-icon" for="__drawer">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M3 6h18v2H3V6m0 5h18v2H3v-2m0 5h18v2H3v-2z"/></svg>
</label>
<div class="md-header__title" data-md-component="header-title">
<div class="md-header__ellipsis">
<div class="md-header__topic">
<span class="md-ellipsis">
Epsilon
</span>
</div>
<div class="md-header__topic" data-md-component="header-topic">
<span class="md-ellipsis">
Object Language (EOL)
</span>
</div>
</div>
</div>
<label class="md-header__button md-icon" for="__search">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M9.5 3A6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.516 6.516 0 0 1 9.5 16 6.5 6.5 0 0 1 3 9.5 6.5 6.5 0 0 1 9.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5z"/></svg>
</label>
<div class="md-search" data-md-component="search" role="dialog">
<label class="md-search__overlay" for="__search"></label>
<div class="md-search__inner" role="search">
<form class="md-search__form" name="search">
<input type="text" class="md-search__input" name="query" aria-label="Search" placeholder="Search" autocapitalize="off" autocorrect="off" autocomplete="off" spellcheck="false" data-md-component="search-query" data-md-state="active" required>
<label class="md-search__icon md-icon" for="__search">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M9.5 3A6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.516 6.516 0 0 1 9.5 16 6.5 6.5 0 0 1 3 9.5 6.5 6.5 0 0 1 9.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5z"/></svg>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M20 11v2H8l5.5 5.5-1.42 1.42L4.16 12l7.92-7.92L13.5 5.5 8 11h12z"/></svg>
</label>
<button type="reset" class="md-search__icon md-icon" aria-label="Clear" tabindex="-1">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M19 6.41 17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12 19 6.41z"/></svg>
</button>
</form>
<div class="md-search__output">
<div class="md-search__scrollwrap" data-md-scrollfix>
<div class="md-search-result" data-md-component="search-result">
<div class="md-search-result__meta">
Initializing search
</div>
<ol class="md-search-result__list"></ol>
</div>
</div>
</div>
</div>
</div>
<div class="md-header__source">
<a href="https://git.eclipse.org/c/epsilon/org.eclipse.epsilon.git/" title="Go to repository" class="md-source" data-md-component="source">
<div class="md-source__icon md-icon">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><path d="M439.55 236.05 244 40.45a28.87 28.87 0 0 0-40.81 0l-40.66 40.63 51.52 51.52c27.06-9.14 52.68 16.77 43.39 43.68l49.66 49.66c34.23-11.8 61.18 31 35.47 56.69-26.49 26.49-70.21-2.87-56-37.34L240.22 199v121.85c25.3 12.54 22.26 41.85 9.08 55a34.34 34.34 0 0 1-48.55 0c-17.57-17.6-11.07-46.91 11.25-56v-123c-20.8-8.51-24.6-30.74-18.64-45L142.57 101 8.45 235.14a28.86 28.86 0 0 0 0 40.81l195.61 195.6a28.86 28.86 0 0 0 40.8 0l194.69-194.69a28.86 28.86 0 0 0 0-40.81z"/></svg>
</div>
<div class="md-source__repository">
Git repository @ Eclipse
</div>
</a>
</div>
</nav>
</header>
<div class="md-container" data-md-component="container">
<main class="md-main" data-md-component="main">
<div class="md-main__inner md-grid">
<div class="md-sidebar md-sidebar--primary" data-md-component="sidebar" data-md-type="navigation" >
<div class="md-sidebar__scrollwrap">
<div class="md-sidebar__inner">
<nav class="md-nav md-nav--primary" aria-label="Navigation" data-md-level="0">
<label class="md-nav__title" for="__drawer">
<a href="../.." title="Epsilon" class="md-nav__button md-logo" aria-label="Epsilon" data-md-component="logo">
<img src="../../assets/images/epsilon-white-background.png" alt="logo">
</a>
Epsilon
</label>
<div class="md-nav__source">
<a href="https://git.eclipse.org/c/epsilon/org.eclipse.epsilon.git/" title="Go to repository" class="md-source" data-md-component="source">
<div class="md-source__icon md-icon">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><path d="M439.55 236.05 244 40.45a28.87 28.87 0 0 0-40.81 0l-40.66 40.63 51.52 51.52c27.06-9.14 52.68 16.77 43.39 43.68l49.66 49.66c34.23-11.8 61.18 31 35.47 56.69-26.49 26.49-70.21-2.87-56-37.34L240.22 199v121.85c25.3 12.54 22.26 41.85 9.08 55a34.34 34.34 0 0 1-48.55 0c-17.57-17.6-11.07-46.91 11.25-56v-123c-20.8-8.51-24.6-30.74-18.64-45L142.57 101 8.45 235.14a28.86 28.86 0 0 0 0 40.81l195.61 195.6a28.86 28.86 0 0 0 40.8 0l194.69-194.69a28.86 28.86 0 0 0 0-40.81z"/></svg>
</div>
<div class="md-source__repository">
Git repository @ Eclipse
</div>
</a>
</div>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../.." class="md-nav__link">
Home
</a>
</li>
<li class="md-nav__item">
<a href="../../download/" class="md-nav__link">
Download
</a>
</li>
<li class="md-nav__item">
<a href="../../getting-started/" class="md-nav__link">
Getting Started
</a>
</li>
<li class="md-nav__item">
<a href="../../live" class="md-nav__link">
Playground
</a>
</li>
<li class="md-nav__item md-nav__item--active md-nav__item--nested">
<input class="md-nav__toggle md-toggle" data-md-toggle="__nav_5" type="checkbox" id="__nav_5" checked>
<label class="md-nav__link" for="__nav_5">
Documentation
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" aria-label="Documentation" data-md-level="1">
<label class="md-nav__title" for="__nav_5">
<span class="md-nav__icon md-icon"></span>
Documentation
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../" class="md-nav__link">
Overview
</a>
</li>
<li class="md-nav__item">
<a href="../emc/" class="md-nav__link">
Model Connectivity
</a>
</li>
<li class="md-nav__item md-nav__item--active md-nav__item--nested">
<input class="md-nav__toggle md-toggle" data-md-toggle="__nav_5_3" type="checkbox" id="__nav_5_3" checked>
<label class="md-nav__link" for="__nav_5_3">
Languages
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" aria-label="Languages" data-md-level="2">
<label class="md-nav__title" for="__nav_5_3">
<span class="md-nav__icon md-icon"></span>
Languages
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item md-nav__item--active">
<input class="md-nav__toggle md-toggle" data-md-toggle="toc" type="checkbox" id="__toc">
<label class="md-nav__link md-nav__link--active" for="__toc">
Object Language (EOL)
<span class="md-nav__icon md-icon"></span>
</label>
<a href="./" class="md-nav__link md-nav__link--active">
Object Language (EOL)
</a>
<nav class="md-nav md-nav--secondary">
<label class="md-nav__title" for="__toc">Table of contents</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="#syntax" class="md-nav__link">
Syntax
</a>
</li>
<li class="md-nav__item">
<a href="#user-defined-operations" class="md-nav__link">
User-Defined Operations
</a>
<nav class="md-nav" aria-label="User-Defined Operations">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#annotations" class="md-nav__link">
Annotations
</a>
</li>
<li class="md-nav__item">
<a href="#prepost-conditions-in-user-defined-operations" class="md-nav__link">
Pre/post conditions in user-defined operations
</a>
</li>
<li class="md-nav__item">
<a href="#operation-result-caching" class="md-nav__link">
Operation Result Caching
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#types" class="md-nav__link">
Types
</a>
<nav class="md-nav" aria-label="Types">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#primitive-types" class="md-nav__link">
Primitive Types
</a>
</li>
<li class="md-nav__item">
<a href="#collections-and-maps" class="md-nav__link">
Collections and Maps
</a>
</li>
<li class="md-nav__item">
<a href="#tuples" class="md-nav__link">
Tuples
</a>
</li>
<li class="md-nav__item">
<a href="#native-types" class="md-nav__link">
Native Types
</a>
</li>
<li class="md-nav__item">
<a href="#model-element-types" class="md-nav__link">
Model Element Types
</a>
</li>
<li class="md-nav__item">
<a href="#creating-and-deleting-model-elements" class="md-nav__link">
Creating and Deleting Model Elements
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#expressions" class="md-nav__link">
Expressions
</a>
<nav class="md-nav" aria-label="Expressions">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#literal-values" class="md-nav__link">
Literal Values
</a>
</li>
<li class="md-nav__item">
<a href="#feature-navigation" class="md-nav__link">
Feature Navigation
</a>
</li>
<li class="md-nav__item">
<a href="#escaping-reserved-keywords" class="md-nav__link">
Escaping Reserved Keywords
</a>
</li>
<li class="md-nav__item">
<a href="#arithmetical-and-comparison-operators" class="md-nav__link">
Arithmetical and Comparison Operators
</a>
</li>
<li class="md-nav__item">
<a href="#logical-operators" class="md-nav__link">
Logical Operators
</a>
</li>
<li class="md-nav__item">
<a href="#ternary-operator" class="md-nav__link">
Ternary Operator
</a>
</li>
<li class="md-nav__item">
<a href="#safe-navigation-and-elvis-operator" class="md-nav__link">
Safe Navigation and Elvis Operator
</a>
</li>
<li class="md-nav__item">
<a href="#enumerations" class="md-nav__link">
Enumerations
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#statements" class="md-nav__link">
Statements
</a>
<nav class="md-nav" aria-label="Statements">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#variable-declaration-statement" class="md-nav__link">
Variable Declaration Statement
</a>
<nav class="md-nav" aria-label="Variable Declaration Statement">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#scope" class="md-nav__link">
Scope
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#assignment-statement" class="md-nav__link">
Assignment Statement
</a>
<nav class="md-nav" aria-label="Assignment Statement">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#variable-assignment" class="md-nav__link">
Variable Assignment
</a>
</li>
<li class="md-nav__item">
<a href="#native-object-property-assignment" class="md-nav__link">
Native Object Property Assignment
</a>
</li>
<li class="md-nav__item">
<a href="#model-element-property-assignment" class="md-nav__link">
Model Element Property Assignment
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#special-assignment-statement" class="md-nav__link">
Special Assignment Statement
</a>
</li>
<li class="md-nav__item">
<a href="#if-statement" class="md-nav__link">
If Statement
</a>
</li>
<li class="md-nav__item">
<a href="#switch-statement" class="md-nav__link">
Switch Statement
</a>
</li>
<li class="md-nav__item">
<a href="#while-statement" class="md-nav__link">
While Statement
</a>
</li>
<li class="md-nav__item">
<a href="#for-statement" class="md-nav__link">
For Statement
</a>
</li>
<li class="md-nav__item">
<a href="#break-breakall-and-continue-statements" class="md-nav__link">
Break, BreakAll and Continue Statements
</a>
</li>
<li class="md-nav__item">
<a href="#throw-statement" class="md-nav__link">
Throw Statement
</a>
</li>
<li class="md-nav__item">
<a href="#transaction-statement" class="md-nav__link">
Transaction Statement
</a>
</li>
<li class="md-nav__item">
<a href="#extended-properties" class="md-nav__link">
Extended Properties
</a>
</li>
<li class="md-nav__item">
<a href="#context-independent-user-input" class="md-nav__link">
Context-Independent User Input
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#additional-resources" class="md-nav__link">
Additional Resources
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="../egl/" class="md-nav__link">
Code Generation (EGL)
</a>
</li>
<li class="md-nav__item">
<a href="../evl/" class="md-nav__link">
Model Validation (EVL)
</a>
</li>
<li class="md-nav__item">
<a href="../etl/" class="md-nav__link">
Model Transformation (ETL)
</a>
</li>
<li class="md-nav__item">
<a href="../ecl/" class="md-nav__link">
Model Comparison (ECL)
</a>
</li>
<li class="md-nav__item">
<a href="../eml/" class="md-nav__link">
Model Merging (EML)
</a>
</li>
<li class="md-nav__item">
<a href="../epl/" class="md-nav__link">
Pattern Matching (EPL)
</a>
</li>
<li class="md-nav__item">
<a href="../flock/" class="md-nav__link">
Model Migration (Flock)
</a>
</li>
<li class="md-nav__item">
<a href="../emg/" class="md-nav__link">
Model Generation (EMG)
</a>
</li>
<li class="md-nav__item">
<a href="../eunit/" class="md-nav__link">
Unit Testing (EUnit)
</a>
</li>
<li class="md-nav__item">
<a href="../pinset/" class="md-nav__link">
Dataset Extraction (Pinset)
</a>
</li>
<li class="md-nav__item">
<a href="../ewl/" class="md-nav__link">
Wizard Language (EWL)
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle" data-md-toggle="__nav_5_4" type="checkbox" id="__nav_5_4" >
<label class="md-nav__link" for="__nav_5_4">
Tools
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" aria-label="Tools" data-md-level="2">
<label class="md-nav__title" for="__nav_5_4">
<span class="md-nav__icon md-icon"></span>
Tools
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../picto/" class="md-nav__link">
Picto
</a>
</li>
<li class="md-nav__item">
<a href="../flexmi/" class="md-nav__link">
Flexmi
</a>
</li>
<li class="md-nav__item">
<a href="../eugenia/" class="md-nav__link">
Eugenia
</a>
</li>
<li class="md-nav__item">
<a href="../exeed/" class="md-nav__link">
Exeed
</a>
</li>
<li class="md-nav__item">
<a href="../modelink/" class="md-nav__link">
Modelink
</a>
</li>
<li class="md-nav__item">
<a href="../hutn/" class="md-nav__link">
HUTN
</a>
</li>
<li class="md-nav__item">
<a href="../workflow/" class="md-nav__link">
Workflow (Ant tasks)
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="../articles/" class="md-nav__link">
Articles
</a>
</li>
<li class="md-nav__item">
<a href="../../examples/" class="md-nav__link">
Examples
</a>
</li>
<li class="md-nav__item">
<a href="https://www.youtube.com/epsilondevs" class="md-nav__link">
Screencasts
</a>
</li>
<li class="md-nav__item">
<a href="https://www.youtube.com/playlist?list=PLRwHao6Ue0YUecg7vEUQTrtySIWwrd_mI" class="md-nav__link">
Lectures
</a>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle" data-md-toggle="__nav_5_9" type="checkbox" id="__nav_5_9" >
<label class="md-nav__link" for="__nav_5_9">
Javadoc
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" aria-label="Javadoc" data-md-level="2">
<label class="md-nav__title" for="__nav_5_9">
<span class="md-nav__icon md-icon"></span>
Javadoc
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="https://download.eclipse.org/epsilon/stable-javadoc/" class="md-nav__link">
Stable
</a>
</li>
<li class="md-nav__item">
<a href="https://download.eclipse.org/epsilon/interim-javadoc/" class="md-nav__link">
Interim
</a>
</li>
</ul>
</nav>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle" data-md-toggle="__nav_6" type="checkbox" id="__nav_6" >
<label class="md-nav__link" for="__nav_6">
Issues
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" aria-label="Issues" data-md-level="1">
<label class="md-nav__title" for="__nav_6">
<span class="md-nav__icon md-icon"></span>
Issues
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="https://bugs.eclipse.org/bugs/enter_bug.cgi?product=epsilon" class="md-nav__link">
Report a new issue
</a>
</li>
<li class="md-nav__item">
<a href="https://bugs.eclipse.org/bugs/buglist.cgi?product=epsilon&cmdtype=doit&order=Reuse+same+sort+as+last+time&bug_status=UNCONFIRMED&bug_status=NEW&bug_status=ASSIGNED&bug_status=REOPENED&bug_severity=blocker&bug_severity=critical&bug_severity=major&bug_severity=normal&bug_severity=minor&bug_severity=trivial" class="md-nav__link">
View open bugs
</a>
</li>
<li class="md-nav__item">
<a href="https://bugs.eclipse.org/bugs/buglist.cgi?product=epsilon&cmdtype=doit&order=Reuse+same+sort+as+last+time&bug_status=UNCONFIRMED&bug_status=NEW&bug_status=ASSIGNED&bug_status=REOPENED&bug_severity=enhancement" class="md-nav__link">
View enhancement requests
</a>
</li>
<li class="md-nav__item">
<a href="https://bugs.eclipse.org/bugs/buglist.cgi?bug_status=RESOLVED&list_id=17694438&product=epsilon&query_format=advanced" class="md-nav__link">
View issues resolved since the last stable release
</a>
</li>
<li class="md-nav__item">
<a href="https://bugs.eclipse.org/bugs/buglist.cgi?product=epsilon&cmdtype=doit&order=Reuse+same+sort+as+last+time" class="md-nav__link">
View all issues
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle" data-md-toggle="__nav_7" type="checkbox" id="__nav_7" >
<label class="md-nav__link" for="__nav_7">
Community
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" aria-label="Community" data-md-level="1">
<label class="md-nav__title" for="__nav_7">
<span class="md-nav__icon md-icon"></span>
Community
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle" data-md-toggle="__nav_7_1" type="checkbox" id="__nav_7_1" >
<label class="md-nav__link" for="__nav_7_1">
Who is using Epsilon?
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" aria-label="Who is using Epsilon?" data-md-level="2">
<label class="md-nav__title" for="__nav_7_1">
<span class="md-nav__icon md-icon"></span>
Who is using Epsilon?
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../../users/" class="md-nav__link">
Industry
</a>
</li>
<li class="md-nav__item">
<a href="../../users/education/" class="md-nav__link">
Education
</a>
</li>
<li class="md-nav__item">
<a href="../../users/open-source/" class="md-nav__link">
Open-source Projects
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="https://projects.eclipse.org/projects/modeling.epsilon/who" class="md-nav__link">
Who is developing Epsilon?
</a>
</li>
<li class="md-nav__item">
<a href="https://www.eclipse.org/forums/index.php/f/22/" class="md-nav__link">
Forum
</a>
</li>
<li class="md-nav__item">
<a href="../../professional-services" class="md-nav__link">
Professional Services
</a>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle" data-md-toggle="__nav_7_5" type="checkbox" id="__nav_7_5" >
<label class="md-nav__link" for="__nav_7_5">
Social Media
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" aria-label="Social Media" data-md-level="2">
<label class="md-nav__title" for="__nav_7_5">
<span class="md-nav__icon md-icon"></span>
Social Media
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="https://twitter.com/eclipseepsilon" class="md-nav__link">
Twitter
</a>
</li>
<li class="md-nav__item">
<a href="https://youtube.com/epsilondevs" class="md-nav__link">
YouTube
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="../../labs/" class="md-nav__link">
Epsilon Labs
</a>
</li>
<li class="md-nav__item">
<a href="../../faq/" class="md-nav__link">
Frequently Asked Questions
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="../../branding/" class="md-nav__link">
Branding
</a>
</li>
</ul>
</nav>
</div>
</div>
</div>
<div class="md-sidebar md-sidebar--secondary" data-md-component="sidebar" data-md-type="toc" >
<div class="md-sidebar__scrollwrap">
<div class="md-sidebar__inner">
<nav class="md-nav md-nav--secondary">
<label class="md-nav__title" for="__toc">Table of contents</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="#syntax" class="md-nav__link">
Syntax
</a>
</li>
<li class="md-nav__item">
<a href="#user-defined-operations" class="md-nav__link">
User-Defined Operations
</a>
<nav class="md-nav" aria-label="User-Defined Operations">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#annotations" class="md-nav__link">
Annotations
</a>
</li>
<li class="md-nav__item">
<a href="#prepost-conditions-in-user-defined-operations" class="md-nav__link">
Pre/post conditions in user-defined operations
</a>
</li>
<li class="md-nav__item">
<a href="#operation-result-caching" class="md-nav__link">
Operation Result Caching
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#types" class="md-nav__link">
Types
</a>
<nav class="md-nav" aria-label="Types">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#primitive-types" class="md-nav__link">
Primitive Types
</a>
</li>
<li class="md-nav__item">
<a href="#collections-and-maps" class="md-nav__link">
Collections and Maps
</a>
</li>
<li class="md-nav__item">
<a href="#tuples" class="md-nav__link">
Tuples
</a>
</li>
<li class="md-nav__item">
<a href="#native-types" class="md-nav__link">
Native Types
</a>
</li>
<li class="md-nav__item">
<a href="#model-element-types" class="md-nav__link">
Model Element Types
</a>
</li>
<li class="md-nav__item">
<a href="#creating-and-deleting-model-elements" class="md-nav__link">
Creating and Deleting Model Elements
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#expressions" class="md-nav__link">
Expressions
</a>
<nav class="md-nav" aria-label="Expressions">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#literal-values" class="md-nav__link">
Literal Values
</a>
</li>
<li class="md-nav__item">
<a href="#feature-navigation" class="md-nav__link">
Feature Navigation
</a>
</li>
<li class="md-nav__item">
<a href="#escaping-reserved-keywords" class="md-nav__link">
Escaping Reserved Keywords
</a>
</li>
<li class="md-nav__item">
<a href="#arithmetical-and-comparison-operators" class="md-nav__link">
Arithmetical and Comparison Operators
</a>
</li>
<li class="md-nav__item">
<a href="#logical-operators" class="md-nav__link">
Logical Operators
</a>
</li>
<li class="md-nav__item">
<a href="#ternary-operator" class="md-nav__link">
Ternary Operator
</a>
</li>
<li class="md-nav__item">
<a href="#safe-navigation-and-elvis-operator" class="md-nav__link">
Safe Navigation and Elvis Operator
</a>
</li>
<li class="md-nav__item">
<a href="#enumerations" class="md-nav__link">
Enumerations
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#statements" class="md-nav__link">
Statements
</a>
<nav class="md-nav" aria-label="Statements">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#variable-declaration-statement" class="md-nav__link">
Variable Declaration Statement
</a>
<nav class="md-nav" aria-label="Variable Declaration Statement">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#scope" class="md-nav__link">
Scope
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#assignment-statement" class="md-nav__link">
Assignment Statement
</a>
<nav class="md-nav" aria-label="Assignment Statement">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#variable-assignment" class="md-nav__link">
Variable Assignment
</a>
</li>
<li class="md-nav__item">
<a href="#native-object-property-assignment" class="md-nav__link">
Native Object Property Assignment
</a>
</li>
<li class="md-nav__item">
<a href="#model-element-property-assignment" class="md-nav__link">
Model Element Property Assignment
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#special-assignment-statement" class="md-nav__link">
Special Assignment Statement
</a>
</li>
<li class="md-nav__item">
<a href="#if-statement" class="md-nav__link">
If Statement
</a>
</li>
<li class="md-nav__item">
<a href="#switch-statement" class="md-nav__link">
Switch Statement
</a>
</li>
<li class="md-nav__item">
<a href="#while-statement" class="md-nav__link">
While Statement
</a>
</li>
<li class="md-nav__item">
<a href="#for-statement" class="md-nav__link">
For Statement
</a>
</li>
<li class="md-nav__item">
<a href="#break-breakall-and-continue-statements" class="md-nav__link">
Break, BreakAll and Continue Statements
</a>
</li>
<li class="md-nav__item">
<a href="#throw-statement" class="md-nav__link">
Throw Statement
</a>
</li>
<li class="md-nav__item">
<a href="#transaction-statement" class="md-nav__link">
Transaction Statement
</a>
</li>
<li class="md-nav__item">
<a href="#extended-properties" class="md-nav__link">
Extended Properties
</a>
</li>
<li class="md-nav__item">
<a href="#context-independent-user-input" class="md-nav__link">
Context-Independent User Input
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#additional-resources" class="md-nav__link">
Additional Resources
</a>
</li>
</ul>
</nav>
</div>
</div>
</div>
<div class="md-content" data-md-component="content">
<article class="md-content__inner md-typeset">
<h1 id="the-epsilon-object-language-eol">The Epsilon Object Language (EOL)<a class="headerlink" href="#the-epsilon-object-language-eol" title="Permanent link">&para;</a></h1>
<p>EOL is the core expression language of Epsilon, and the foundation for task-specific languages for tasks such as <a href="../evl">model-validation</a>, <a href="../egl">model-to-text transformation</a>, <a href="../etl">model-to-model transformation</a> and <a href="../flock">model migration</a>. EOL can also be used as a general-purpose standalone model management language for automating tasks that do not fall into the patterns targeted by task-specific languages.</p>
<div class="admonition tip">
<p class="admonition-title">Try EOL online</p>
<p>You can run and fiddle with an EOL program that queries a project scheduling model in the <a href="../../live/?eol">online Epsilon Playground</a>.</p>
</div>
<h2 id="syntax">Syntax<a class="headerlink" href="#syntax" title="Permanent link">&para;</a></h2>
<p>EOL programs are organized in <code>modules</code>. Each module defines a <code>body</code> and a number of <code>operations</code>. The body is a block of statements that are evaluated when the module is executed<sup id="fnref:1"><a class="footnote-ref" href="#fn:1">1</a></sup>. Each operation defines the kind of objects on which it is applicable (<code>context</code>), a <code>name</code>, a set of <code>parameters</code> and optionally a <code>return type</code>. Modules can also import other modules using <code>import</code> statements and access their operations, as shown in the listing below.</p>
<pre class="prettyprint lang-eol"><code>// file imported.eol
operation hello() {
"Hello world!".println();
}
// file importer.eol
// We can use relative/absolute paths or platform:/ URIs
import "imported.eol";
hello(); // main body
// ... more operations could be placed here ...</code></pre>
<div class="mermaid mermaid-100">classDiagram
class EolModule {
+main:StatementBlock
}
class ImportStatement {
+imported:EolModule
}
class Operation {
+name: String
+context: EolType
+parameters: Parameter[*]
+returnType: EolType
}
class ExecutableAnnotation {
+expression: Expression
}
class SimpleAnnotation {
+values: String[*]
}
EolModule -- ImportStatement: *
EolModule -- Operation: operations *
Operation -- Annotation: annotations *
Operation -- StatementBlock: body
EolModule -- StatementBlock: main
StatementBlock -- Statement: statements *
Annotation &lt;|-- ExecutableAnnotation
Annotation &lt;|-- SimpleAnnotation</div>
<h2 id="user-defined-operations">User-Defined Operations<a class="headerlink" href="#user-defined-operations" title="Permanent link">&para;</a></h2>
<p>In mainstream object oriented languages such as Java and C++, operations are defined inside classes and can be invoked on instances of those classes. EOL on the other hand is not object-oriented in the sense that it does not define classes itself, but nevertheless needs to manage objects of types defined externally to it (e.g. in metamodels). By defining the context-type of an operation explicitly, the operation can be called on instances of the type as if it was natively defined by the type.</p>
<p>For example, consider the code excerpts displayed in the listings below. In the first listing, the operations <code>add1</code> and <code>add2</code> are defined in the context of the built-in <code>Integer</code> type, which is specified before their names. Therefore, they can be invoked in line 1 using the <code>1.add1().add2()</code> expression: the context (the integer <code>1</code>) will be assigned to the special variable <code>self</code>. On the other hand, in the second listing where no context is defined, they have to be invoked in a nested manner which follows an in-to-out direction instead of the left to right direction used by the former excerpt. As complex model queries often involve invoking multiple properties and operations, this technique is particularly beneficial to the overall readability of the code.</p>
<pre class="prettyprint lang-eol"><code>1.add1().add2().println();
operation Integer add1() : Integer {
return self + 1;
}
operation Integer add2() : Integer {
return self + 2;
}</code></pre>
<pre class="prettyprint lang-eol"><code>add2(add1(1)).println();
operation add1(base : Integer) : Integer {
return base + 1;
}
operation add2(base : Integer) : Integer {
return base + 2;
}</code></pre>
<p>EOL supports polymorphic operations using a runtime dispatch mechanism. Multiple operations with the same name and parameters can be defined, each defining a distinct context type. For example, in the listing below, the statement in line 1 invokes the test operation defined in line 4, while the statement in line 2 invokes the test operation defined in line 8.</p>
<pre class="prettyprint lang-eol"><code>"1".test();
1.test();
operation String test() {
(self + " is a string").println();
}
operation Integer test() {
(self + "is an integer").println();
}</code></pre>
<h3 id="annotations">Annotations<a class="headerlink" href="#annotations" title="Permanent link">&para;</a></h3>
<p>EOL supports two types of annotations: simple and executable. A simple annotation specifies a name and a set of String values while an executable annotation specifies a name and an expression. The concrete syntaxes of simple and executable annotations are displayed in the listing below.</p>
<pre class="prettyprint lang-eol"><code>// Simple annotation
@name value(,value)
// Executable annotation
$name expression</code></pre>
<p>Several examples for simple annotations are shown the listing below. Examples for executable annotations will be given in the following sections.</p>
<pre class="prettyprint lang-eol"><code>@colors red
@colors red, blue
@colors red, blue, green</code></pre>
<p>In stand-alone EOL, annotations are supported only in the context of operations, however as discussed in the sequel, task-specific languages also make use of annotations in their constructs, each with task-specific semantics. EOL operations support three particular annotations: the <code>pre</code> and <code>post</code> executable annotations for specifying pre and post-conditions, and the <code>cached</code> simple annotation, which are discussed below.</p>
<h3 id="prepost-conditions-in-user-defined-operations">Pre/post conditions in user-defined operations<a class="headerlink" href="#prepost-conditions-in-user-defined-operations" title="Permanent link">&para;</a></h3>
<p>A number of <code>pre</code> and <code>post</code> executable annotations can be attached to EOL operations to specify the pre- and post-conditions of the operation. When an operation is invoked, before its body is evaluated, the expressions of the <code>pre</code> annotations are evaluated. If all of them return <code>true</code>, the body of the operation is executed, otherwise, an error is raised. Similarly, once the body of the operation has been executed, the expressions of the <code>post</code> annotations of the operation are executed to ensure that the operation has had the desired effects. <code>Pre</code> and <code>post</code> annotations can access all the variables in the parent scope, as well as the parameters of the operation and the object on which the operation is invoked (through the <code>self</code> variable). Moreover, in <code>post</code> annotations, the returned value of the operation is accessible through the built-in <code>_result</code> variable. An example of using pre and post conditions in EOL appears below.</p>
<pre class="prettyprint lang-eol"><code>1.add(2);
1.add(-1);
$pre i &gt; 0
$post _result &gt; self
operation Integer add(i : Integer) : Integer {
return self + i;
}</code></pre>
<p>In line 4 the <code>add</code> operation defines a pre-condition stating that the parameter <code>i</code> must be a positive number. In line 5, the operation defines that result of the operation (<code>_result</code>) must be greater than the number on which it was invoked (<code>self</code>). Thus, when executed in the context of the statement in line 1 the operation succeeds, while when executed in the context of the statement in line 2, the pre-condition is not satisfied and an error is raised.</p>
<h3 id="operation-result-caching">Operation Result Caching<a class="headerlink" href="#operation-result-caching" title="Permanent link">&para;</a></h3>
<p>EOL supports caching the results of parameter-less operations using the <code>@cached</code> simple annotation. In the following example, the Fibonacci number of a given Integer is calculated using the <code>fibonacci</code> recursive operation displayed in the listing below. Since the <code>fibonacci</code> operation is declared as <code>cached</code>, it is only executed once for each distinct Integer and subsequent calls on the same target return the cached result. Therefore, when invoked in line 1, the body of the operation is called 16 times. By contrast, if no <code>@cached</code> annotation was specified, the body of the operation would be called recursively 1973 times. This feature is particularly useful for performing queries on large models and caching their results without needing to introduce explicit variables that store the cached results.</p>
<p>It is worth noting that caching works <code>by reference</code>, which means that all clients of a cached method for a given context will receive the same returned object. As such, if the first client modifies the returned object in some way (e.g. sets a property in the case of an object or adds an element in the case of the collection), subsequent clients of the method for the same context will receive the modified object/collection.</p>
<pre class="prettyprint lang-eol"><code>15.fibonacci().println();
@cached
operation Integer fibonacci() : Integer {
if (self = 1 or self = 0) {
return 1;
}
else {
return (self-1).fibonacci() + (self-2).fibonacci();
}
}</code></pre>
<h2 id="types">Types<a class="headerlink" href="#types" title="Permanent link">&para;</a></h2>
<p>As is the case for most programming languages, EOL defines a built-in system of types, illustrated in the figure below. The <code>Any</code> type, inspired by the <code>OclAny</code> type of OCL, is the basis of all types in EOL including Collection types.</p>
<div class="mermaid mermaid-100">classDiagram
class ModelElementType {
-model: String
-type: String
}
class Native {
-implementation: String
}
ModelElementType --|&gt; Any
Any &lt;|-- Native
Any &lt;|-- Collection
Any &lt;|-- Map
Collection &lt;|-- Bag
Collection &lt;|-- Set
Collection &lt;|-- OrderedSet
Collection &lt;|-- Sequence
PrimitiveType --|&gt; Any
PrimitiveType &lt;|-- Integer
PrimitiveType &lt;|-- String
PrimitiveType &lt;|-- Boolean
PrimitiveType &lt;|-- Real
</div>
<!--![Overview of the type system of
EOL](images/EOLTypes.png)-->
<p>The operations supported by
instances of the Any type are outlined in the table below<sup id="fnref:2"><a class="footnote-ref" href="#fn:2">2</a></sup>.</p>
<table>
<thead>
<tr>
<th>Signature</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>asBag() : Bag</td>
<td>Returns a new Bag containing the object</td>
</tr>
<tr>
<td>asBoolean() : Boolean</td>
<td>Returns a Boolean based on the string representation of the object. If the string representation is not of an acceptable format, an error is raised</td>
</tr>
<tr>
<td>asInteger() : Integer</td>
<td>Returns an Integer based on the string representation of the object. If the string representation is not of an acceptable format, an error is raised</td>
</tr>
<tr>
<td>asOrderedSet() : OrderedSet</td>
<td>Returns a new OrderedSet containing the object</td>
</tr>
<tr>
<td>asReal() : Real</td>
<td>Returns a Real based on the string representation of the object. If the string representation is not of an acceptable format, an error is raised</td>
</tr>
<tr>
<td>asDouble() : Double</td>
<td>Returns a Java Double based on the string representation of the object. If the string representation is not of an acceptable format, an error is raised</td>
</tr>
<tr>
<td>asFloat() : Float</td>
<td>Returns a Java Float based on the string representation of the object. If the string representation is not of an acceptable format, an error is raised</td>
</tr>
<tr>
<td>asSequence() : Sequence</td>
<td>Returns a new Sequence containing the object</td>
</tr>
<tr>
<td>asSet() : Set</td>
<td>Returns a new Set containing the object</td>
</tr>
<tr>
<td>asString() : String</td>
<td>Returns a string representation of the object</td>
</tr>
<tr>
<td>err([prefix : String]) : Any</td>
<td>Prints a string representation of the object on which it is invoked to the error stream prefixed with the optional <code>prefix</code> string and returns the object on which it was invoked. In this way, the <code>err</code> operation can be used for debugging purposes in a non-invasive manner</td>
</tr>
<tr>
<td>errln([prefix : String]) : Any</td>
<td>Has the same effects as the <code>err</code> operation but also produces a new line in the output stream.</td>
</tr>
<tr>
<td>format([pattern : String]) : String</td>
<td>Uses the provided pattern to form a String representation of the object on which the method is invoked. The pattern argument must conform to the format string syntax defined by Java<sup id="fnref:3"><a class="footnote-ref" href="#fn:3">3</a></sup>.</td>
</tr>
<tr>
<td>hasProperty(name : String) : Boolean</td>
<td>Returns true if the object has a property with the specified name or false otherwise</td>
</tr>
<tr>
<td>ifUndefined(alt : Any) : Any</td>
<td>If the object is undefined, it returns alt else it returns the object</td>
</tr>
<tr>
<td>isDefined() : Boolean</td>
<td>Returns true if the object is defined and false otherwise</td>
</tr>
<tr>
<td>isKindOf(type : Type) : Boolean</td>
<td>Returns true if the object is of the given type or one of its subtypes and false otherwise</td>
</tr>
<tr>
<td>isTypeOf(type : Type) : Boolean</td>
<td>Returns true if the object is of the given type and false otherwise</td>
</tr>
<tr>
<td>isUndefined() : Boolean</td>
<td>Returns true if the object is undefined and false otherwise</td>
</tr>
<tr>
<td>owningModel() : Model</td>
<td>Returns the model that contains this object or an undefined value otherwise</td>
</tr>
<tr>
<td>print([prefix : String]) : Any</td>
<td>Prints a string representation of the object on which it is invoked to the regular output stream, prefixed with the optional <code>prefix</code> string and returns the object on which it was invoked. In this way, the <code>print</code> operation can be used for debugging purposes in a non-invasive manner</td>
</tr>
<tr>
<td>println([prefix : String]) : Any</td>
<td>Has the same effects as the <code>print</code> operation but also produces a new line in the output stream.</td>
</tr>
<tr>
<td>type() : Type</td>
<td>Returns the <a href="#types">type</a> of the object.</td>
</tr>
</tbody>
</table>
<h3 id="primitive-types">Primitive Types<a class="headerlink" href="#primitive-types" title="Permanent link">&para;</a></h3>
<p>EOL provides four primitive types: String, Integer, Real and Boolean. The String type represents a finite sequence of characters and supports the following operations which can be invoked on its instances.</p>
<table>
<thead>
<tr>
<th>Signature</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>characterAt(index : Integer) : String</td>
<td>Returns the character in the specified index</td>
</tr>
<tr>
<td>concat(str : String) : String</td>
<td>Returns a concatenated form of the string with the <code>str</code> parameter</td>
</tr>
<tr>
<td>endsWith(str : String) : Boolean</td>
<td>Returns true iff the string ends with <code>str</code></td>
</tr>
<tr>
<td>escapeXml() : String</td>
<td>Returns a new string with escaped XML-reserved characters</td>
</tr>
<tr>
<td>firstToLowerCase() : String</td>
<td>Returns a new string the first character of which has been converted to lower case</td>
</tr>
<tr>
<td>ftlc() : String</td>
<td>Alias for <code>firstToLowerCase()</code></td>
</tr>
<tr>
<td>firstToUpperCase() : String</td>
<td>Returns a new string, the first character of which has been converted to upper case</td>
</tr>
<tr>
<td>ftuc : String</td>
<td>Alias for <code>firstToUpperCase()</code></td>
</tr>
<tr>
<td>isInteger() : Boolean</td>
<td>Returns true iff the string is an integer</td>
</tr>
<tr>
<td>isReal() : Boolean</td>
<td>Returns true iff the string is a real number</td>
</tr>
<tr>
<td>isSubstringOf(str : String) : Boolean</td>
<td>Returns true iff the string the operation is invoked on is a substring of <code>str</code></td>
</tr>
<tr>
<td>length() : Integer</td>
<td>Returns the number of characters in the string</td>
</tr>
<tr>
<td>matches(reg : String) : Boolean</td>
<td>Returns true if there are occurrences of the regular expression <code>reg</code> in the string</td>
</tr>
<tr>
<td>pad(length : Integer, padding : String, right : Boolean) : String</td>
<td>Pads the string up to the specified length with specified padding (e.g. <code>"foo".pad(5, "*", true)</code> returns <code>"foo**"</code>)</td>
</tr>
<tr>
<td>replace(source : String, target : String) : String</td>
<td>Returns a new string in which all instances of <code>source</code> have been replaced with instances of <code>target</code></td>
</tr>
<tr>
<td>split(reg : String) : Sequence(String)</td>
<td>Splits the string using as a delimiter the provided regular expression, <code>reg</code>, and returns a sequence containing the parts</td>
</tr>
<tr>
<td>startsWith(str : String) : Boolean</td>
<td>Returns true iff the string starts with <code>str</code></td>
</tr>
<tr>
<td>substring(index : Integer) : String</td>
<td>Returns a sub-string of the string starting from the specified <code>index</code> and extending to the end of the original string</td>
</tr>
<tr>
<td>substring(startIndex : Integer, endIndex : Integer) : String</td>
<td>Returns a sub-string of the string starting from the specified <code>startIndex</code> and ending at <code>endIndex</code></td>
</tr>
<tr>
<td>toCharSequence() : Sequence(String)</td>
<td>Returns a sequence containing all the characters of the string</td>
</tr>
<tr>
<td>toLowerCase() : String</td>
<td>Returns a new string where all the characters have been converted to lower case</td>
</tr>
<tr>
<td>toUpperCase() : String</td>
<td>Returns a new string where all the characters have been converted to upper case</td>
</tr>
<tr>
<td>trim() : String</td>
<td>Returns a trimmed copy of the string</td>
</tr>
</tbody>
</table>
<p>The Real type represents real numbers and provides the following operations.</p>
<table>
<thead>
<tr>
<th>Signature</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>abs() : Real</td>
<td>Returns the absolute value of the real</td>
</tr>
<tr>
<td>ceiling() : Integer</td>
<td>Returns the nearest Integer that is greater than the real</td>
</tr>
<tr>
<td>floor() : Integer</td>
<td>Returns the nearest Integer that is less than the real</td>
</tr>
<tr>
<td>log() : Real</td>
<td>Returns the natural logarithm of the real</td>
</tr>
<tr>
<td>log10() : Real</td>
<td>Returns the 10-based logarithm of the real</td>
</tr>
<tr>
<td>max(other : Real) : Real</td>
<td>Returns the maximum of the two reals</td>
</tr>
<tr>
<td>min(other : Real) : Real</td>
<td>Returns the minimum of the two reals</td>
</tr>
<tr>
<td>pow(exponent : Real) : Real</td>
<td>Returns the real to the power of exponent</td>
</tr>
<tr>
<td>round() : Integer</td>
<td>Rounds the real to the nearest Integer</td>
</tr>
</tbody>
</table>
<p>The Integer type represents natural numbers and negatives and extends the Real primitive type. It also defines the following operations:</p>
<table>
<thead>
<tr>
<th>Signature</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>iota(end : Integer, step : Integer) : Sequence(Integer)</td>
<td>Returns a sequence of integers up to <code>end</code> using the specified step (e.g. 1.iota(10,2) returns Sequence{1,3,5,7,9})</td>
</tr>
<tr>
<td>mod(divisor : Integer) : Integer</td>
<td>Returns the remainder of dividing the integer by the divisor</td>
</tr>
<tr>
<td>to(other : Integer) : Sequence(Integer)</td>
<td>Returns a sequence of integers (e.g. 1.to(5) returns Sequence{1,2,3,4,5})</td>
</tr>
<tr>
<td>toBinary() : String</td>
<td>Returns the binary representation of the integer (e.g. 6.toBinary() returns "110")</td>
</tr>
<tr>
<td>toHex() : String</td>
<td>Returns the hexadecimal representation of the integer (e.g. 42.toBinary() returns "2a")</td>
</tr>
</tbody>
</table>
<p>Finally, the Boolean type represents true/false states and provides no additional operations to those provided by the base Any type.</p>
<h3 id="collections-and-maps">Collections and Maps<a class="headerlink" href="#collections-and-maps" title="Permanent link">&para;</a></h3>
<p>EOL provides four types of collections and a Map type. The <code>Bag</code> type represents non-unique, unordered collections and implements the <code>java.util.Collection</code> interface, the Sequence type represents non-unique, ordered collections and implements the <code>java.util.List</code> interface, the Set type represents unique and unordered collections and implements the <code>java.util.Set</code> interface, the OrderedSet represents unique and ordered collections. Since version 2.0, there are also two concurrent collection types, which can safely be modified from multiple threads. These are <code>ConcurrentBag</code> and <code>ConcurrentSet</code>, which are thread-safe variants of the <code>Bag</code> and <code>Set</code> types respectively.</p>
<p>All collection types inherit from the abstract <code>Collection</code> type. Apart from simple operations, EOL also supports logic operations on collections. The following operations (along with any operations declared on the <code>java.util.Collection</code> interface) apply to all types of collections:</p>
<table>
<thead>
<tr>
<th>Signature</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>add(item : Any) : Boolean</td>
<td>Adds an item to the collection. If the collection is a set, addition of duplicate items has no effect. Returns true if the collection increased in size: this is always the case for bags and sequences, and for sets and ordered sets it is true if the element was not part of the collection before.</td>
</tr>
<tr>
<td>addAll(col : Collection) : Boolean</td>
<td>Adds all the items of the <code>col</code> argument to the collection. If the collection is a set, it only adds items that do not already exist in the collection. Returns true if this collection changed as a result of the call</td>
</tr>
<tr>
<td>asBag()</td>
<td>Returns a Bag that contains the same elements as the collection.</td>
</tr>
<tr>
<td>asOrderedSet()</td>
<td>Returns a duplicate-free OrderedSet that contains the same elements as the collection.</td>
</tr>
<tr>
<td>asSequence()</td>
<td>Returns a Sequence that contains the same elements as the collection.</td>
</tr>
<tr>
<td>asSet()</td>
<td>Returns a duplicate-free Set that contains the same elements as the collection.</td>
</tr>
<tr>
<td>clear()</td>
<td>Empties the collection</td>
</tr>
<tr>
<td>clone() : Collection</td>
<td>Returns a new collection of the same type containing the same items with the original collection</td>
</tr>
<tr>
<td>concat() : String</td>
<td>Returns the string created by converting each element of the collection to a string</td>
</tr>
<tr>
<td>concat(separator : String) : String</td>
<td>Returns the string created by converting each element of the collection to a string, using the given argument as a separator</td>
</tr>
<tr>
<td>count(item : Any) : Integer</td>
<td>Returns the number of times the item exists in the collection</td>
</tr>
<tr>
<td>excludes(item : Any) : Boolean</td>
<td>Returns true if the collection excludes the <code>item</code></td>
</tr>
<tr>
<td>excludesAll(col : Collection) : Boolean</td>
<td>Returns true if the collection excludes all the items of collection col</td>
</tr>
<tr>
<td>excluding(item : Any) : Collection</td>
<td>Returns a new collection that excludes the item -- unlike the remove() operation that removes the <code>item</code> from the collection itself</td>
</tr>
<tr>
<td>excludingAll(col : Collection) : Collection</td>
<td>Returns a new collection that excludes all the elements of the col collection</td>
</tr>
<tr>
<td>flatten() : Collection</td>
<td>Recursively flattens all items that are of collection type and returns a new collection where no item is a collection itself</td>
</tr>
<tr>
<td>includes(item : Any) : Boolean</td>
<td>Returns true if the collection includes the <code>item</code></td>
</tr>
<tr>
<td>includesAll(col : Collection) : Boolean</td>
<td>Returns true if the collection includes all the items of collection <code>col</code></td>
</tr>
<tr>
<td>including(item : Any) : Collection</td>
<td>Returns a new collection that also contains the <code>item</code> -- unlike the add() operation that adds the <code>item</code> to the collection itself</td>
</tr>
<tr>
<td>includingAll(col : Collection) : Collection</td>
<td>Returns a new collection that is a union of the two collections. The type of the returned collection (i.e. Bag, Sequence, Set, OrderedSet) is same as the type of the collection on which the operation is invoked</td>
</tr>
<tr>
<td>isEmpty() : Boolean</td>
<td>Returns true if the collection does not contain any elements and false otherwise</td>
</tr>
<tr>
<td>min() : Real</td>
<td>Returns the minimum of all reals/integers in the collection, or 0 if it is empty</td>
</tr>
<tr>
<td>min(default : Real) : Real</td>
<td>Returns the minimum of all reals/integers in the collection, or the default value if it is empty</td>
</tr>
<tr>
<td>max() : Real</td>
<td>Returns the maximum of all reals/integers in the collection, or 0 if it is empty</td>
</tr>
<tr>
<td>max(default : Real) : Real</td>
<td>Returns the maximum of all reals/integers in the collection, or the default value if it is empty</td>
</tr>
<tr>
<td>notEmpty() : Boolean</td>
<td>Returns true if the collection contains any elements and false otherwise</td>
</tr>
<tr>
<td>powerset() : Set</td>
<td>Returns the set of all subsets of the collection</td>
</tr>
<tr>
<td>product() : Real</td>
<td>Returns the product of all reals/integers in the collection</td>
</tr>
<tr>
<td>random() : Any</td>
<td>Returns a random item from the collection</td>
</tr>
<tr>
<td>remove(item : Any) : Boolean</td>
<td>Removes an <code>item</code> from the collection. Returns true if the collection contained the specified element</td>
</tr>
<tr>
<td>removeAll(col : Collection) : Boolean</td>
<td>Removes all the items of <code>col</code> from the collection. Returns true if the collection changed as a result of the call</td>
</tr>
<tr>
<td>size() : Integer</td>
<td>Returns the number of items the collection contains</td>
</tr>
<tr>
<td>sum() : Real</td>
<td>Returns the sum of all reals/integers in the collection</td>
</tr>
</tbody>
</table>
<p>The following operations apply to ordered collection types (i.e. Sequence and OrderedSet):</p>
<table>
<thead>
<tr>
<th>Signature</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>at(index : Integer) : Any</td>
<td>Returns the item of the collection at the specified index</td>
</tr>
<tr>
<td>first() : Any</td>
<td>Returns the first item of the collection</td>
</tr>
<tr>
<td>fourth() : Any</td>
<td>Returns the fourth item of the collection</td>
</tr>
<tr>
<td>indexOf(item : Any) : Integer</td>
<td>Returns the index of the item in the collection or -1 if it does not exist</td>
</tr>
<tr>
<td>invert() : Collection</td>
<td>Returns an inverted copy of the collection</td>
</tr>
<tr>
<td>last() : Any</td>
<td>Returns the last item of the collection</td>
</tr>
<tr>
<td>removeAt(index : Integer) : Any</td>
<td>Removes and returns the item at the specified index.</td>
</tr>
<tr>
<td>second() : Any</td>
<td>Returns the second item of the collection</td>
</tr>
<tr>
<td>third() : Any</td>
<td>Returns the third item of the collection</td>
</tr>
</tbody>
</table>
<p>Also, EOL collections support the following first-order operations. Apart from <code>aggregate</code> and <code>closure</code>, all of these operations have a parallel variant which can take advantage of multiple cores to improve performance. All computations contained in these operations are assumed to be free from side-effects (i.e. do not mutate global variables).</p>
<p>Aside from the following built-in first-order operations which are evaluated eagerly, all Collection types in the Java implementation of EOL support Streams. This allows for chains of queries and transformations on collections to be evaluated more efficiently. A stream can be obtained by calling the <code>stream()</code> method on the collection. The API is defined by the Java standard library<sup id="fnref:4"><a class="footnote-ref" href="#fn:4">4</a></sup>.</p>
<table>
<thead>
<tr>
<th>Signature</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>atLeastNMatch(iterator : Type | condition, n : Integer) : Boolean</td>
<td>Returns true if there are <code>n</code> or more items in the collection that satisfy the condition</td>
</tr>
<tr>
<td>atMostNMatch(iterator : Type | condition, n : Integer) : Boolean</td>
<td>Returns true if there are <code>n</code> or fewer items in the collection that satisfy the condition</td>
</tr>
<tr>
<td>aggregate(iterator : Type | keyExpression, valueExpression) : Map</td>
<td>Returns a map containing key-value pairs produced by evaluating the key and value expressions on each item of the collection that is of the specified type</td>
</tr>
<tr>
<td>closure(iterator : Type | expression) : Collection</td>
<td>Returns a collection containing the results of evaluating the transitive closure of the results produced by the expression on each item of the collection that is of the specified type. For example, if <code>t</code> is a tree model element, <code>t.closure(it|it.children)</code> will return all its descendants</td>
</tr>
<tr>
<td>collect(iterator : Type | expression) : Collection</td>
<td>Returns a collection containing the results of evaluating the expression on each item of the collection that is of the specified type</td>
</tr>
<tr>
<td>count(iterator : Type | condition) : Integer</td>
<td>Returns the number of elements in the collection that satisfy the condition</td>
</tr>
<tr>
<td>exists(iterator : Type | condition) : Boolean</td>
<td>Returns true if there exists at least one item in the collection that satisfies the condition</td>
</tr>
<tr>
<td>forAll(iterator : Type | condition) : Boolean</td>
<td>Returns true if all items in the collection satisfy the condition</td>
</tr>
<tr>
<td>mapBy(iterator : Type | expression) : Map</td>
<td>Returns a map containing the results of the expression <a href="https://www.eclipse.org/epsilon/live/?14131930">as keys and the respective items of the collection as values</a>.</td>
</tr>
<tr>
<td>nMatch(iterator : Type | condition, n : Integer) : Boolean</td>
<td>Returns true if there are exactly <code>n</code> items in the collection that satisfy the condition</td>
</tr>
<tr>
<td>none(iterator : Type | condition) : Boolean</td>
<td>Returns true if there are no items in the collection that satisfy the condition</td>
</tr>
<tr>
<td>one(iterator : Type | condition) : Boolean</td>
<td>Returns true if there exists exactly one item in the collection that satisfies the condition</td>
</tr>
<tr>
<td>reject(iterator : Type | condition) : Collection</td>
<td>Returns a sub-collection containing only items of the specified type that do not satisfy the condition</td>
</tr>
<tr>
<td>rejectOne(iterator : Type | condition) : Collection</td>
<td>Returns a sub-collection containing all elements except the first element which does not satisfy the condition</td>
</tr>
<tr>
<td>select(iterator : Type | condition) : Collection</td>
<td>Returns a sub-collection containing only items of the specified type that satisfy the condition</td>
</tr>
<tr>
<td>selectByKind(Type) : Collection</td>
<td>Returns a sub-collection containing only items of the specified type and subtypes</td>
</tr>
<tr>
<td>selectByType(Type) : Collection</td>
<td>Returns a sub-collection containing only items of the specified type only</td>
</tr>
<tr>
<td>selectOne(iterator : Type | condition) : Any</td>
<td>Returns any element that satisfies the condition</td>
</tr>
<tr>
<td>sortBy(iterator: Type | expression) : Collection</td>
<td>Returns a copy of the collection sorted by the results of evaluating the expression on each item of the collection that conforms to the iterator type. The expression should return either an Integer, a String or an object that is an instance of Comparable. The ordering is calculated as follows: for integers, smaller to greater; for Strings, as defined by the compareTo method of Java strings; for Comparable objects, according to the semantics of the type's compareTo method implementation.</td>
</tr>
</tbody>
</table>
<p>The Map type (which implements the <code>java.util.Map</code> interface) represents a Set of key-value pairs in which the keys are unique. Since version 2.0, there is also a thread-safe <code>ConcurrentMap</code> type, which implements the <code>java.util.concurrent.ConcurrentMap</code> interface. The following operations are supported:</p>
<table>
<thead>
<tr>
<th>Signature</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>clear()</td>
<td>Clears the map</td>
</tr>
<tr>
<td>containsKey(key : Any) : Boolean</td>
<td>Returns true if the map contains the specified key</td>
</tr>
<tr>
<td>containsValue(value : Any) : Boolean</td>
<td>Returns true if this map maps one or more keys to the specified value.</td>
</tr>
<tr>
<td>get(key : Any) : Any</td>
<td>Returns the value for the specified key</td>
</tr>
<tr>
<td>isEmpty() : Boolean</td>
<td>Returns true if the map contains no key-value mappings.</td>
</tr>
<tr>
<td>keySet() : Set</td>
<td>Returns the keys of the map</td>
</tr>
<tr>
<td>put(key : Any, value : Any)</td>
<td>Adds the key-value pair to the map. If the map already contains the same key, the value is overwritten</td>
</tr>
<tr>
<td>putAll(map : Map)</td>
<td>Copies all of the mappings from the specified map to this map.</td>
</tr>
<tr>
<td>remove(key : Any) : Any</td>
<td>Removes the mapping for the specified key from this map if present. Returns the previous value associated with key.</td>
</tr>
<tr>
<td>size() : Integer</td>
<td>Returns the number of key-value mappings in this map.</td>
</tr>
<tr>
<td>values() : Bag</td>
<td>Returns the values of the map</td>
</tr>
</tbody>
</table>
<h3 id="tuples">Tuples<a class="headerlink" href="#tuples" title="Permanent link">&para;</a></h3>
<p>Since version 2.2, EOL supports Tuples, which can be used to compose arbitrary data structures on-the-fly. A <code>Tuple</code> in EOL behaves like a <code>Map&lt;String, Object&gt;</code>, except that the values of the map can be accessed using literal property call expressions. There are three ways to instantiate a tuple, as shown below.</p>
<pre class="prettyprint lang-eol"><code>// After construction
var alice = new Tuple;
alice.name = "Alice";
alice.age = 32;
// During construction
var bob = new Tuple(name = "Bob", age = 28);
// Map Literal
var charlie = Tuple{"name" = "Charlie", "age" = 36};</code></pre>
<p>If a non-existent property on a Tuple is accessed, an exception is thrown.</p>
<pre class="prettyprint lang-eol"><code>var p = new Tuple(name = "Alice", age = 32);
p.name.substring(0, 3); // "Ali"
p.age; // 32
p.occupation.isDefined(); // false
p.occupation.toUpperCase(); // Property 'occupation' not found</code></pre>
<h3 id="native-types">Native Types<a class="headerlink" href="#native-types" title="Permanent link">&para;</a></h3>
<p>As discussed earlier, while the purpose of EOL is to provide significant expressive power to enable users to manage models at a high level of abstraction, it is not intended to be a general-purpose programming language. Therefore, there may be cases where users need to implement some functionality that is either not efficiently supported by the EOL runtime (e.g. complex mathematical computations) or that EOL does not support at all (e.g. developing user interfaces, accessing databases). To overcome this problem, EOL enables users to create objects of the underlying programming environment by using <code>native</code> types. A native type specifies an <code>implementation</code> property that indicates the unique identifier for an underlying platform type. For instance, in a Java implementation of EOL the user can instantiate and use a Java class via its class identifier. Thus, the EOL excerpt in the listing below creates a Java window (Swing JFrame) and uses its methods to change its title and dimensions and make it visible.</p>
<pre class="prettyprint lang-eol"><code>var frame = new Native("javax.swing.JFrame");
frame.title = "Opened with EOL";
frame.setBounds(100,100,300,200);
frame.visible = true;</code></pre>
<p>To pass arguments to the constructor of a native type, a parameter list must be added, such as that in the listing below. </p>
<pre class="prettyprint lang-eol"><code>var file = new Native("java.io.File")("myfile.txt");
file.absolutePath.println();</code></pre>
<p>Static types can also be referenced in EOL and stored in a variable for convenience, as shown below.</p>
<pre class="prettyprint lang-eol"><code>var Collectors = Native("java.util.stream.Collectors");</code></pre>
<h3 id="model-element-types">Model Element Types<a class="headerlink" href="#model-element-types" title="Permanent link">&para;</a></h3>
<p>A model element type represents a meta-level classifier for model elements. Epsilon intentionally refrains from defining more details about the meaning of a model element type, to be able to support diverse modelling technologies where a type has different semantics. For instance an Ecore EClass, an XSD complex type and a Java class can all be regarded as model element types according to the implementation of the underlying modelling framework.</p>
<div class="admonition info">
<p class="admonition-title">Info</p>
<p>As EOL is decoupled from modelling technologies (e.g. EMF, Simulink), through <a href="../emc">Epsilon's Model Connectivity Layer</a>, we refrain from referring to specific modelling technologies in this section as much as possible.</p>
</div>
<p>In case of multiple models, as well as the name of the type, the name of the model is also required to resolve a particular type since different models may contain elements of homonymous but different model element types. In case a model defines more than one type with the same name (e.g. in different packages), a fully qualified type name must be provided.</p>
<p>In terms of concrete syntax, inspired by <a href="https://eclipse.org/atl">ATL</a>, the <code>!</code> character is used to separate the name of the type from the name of the model it is defined in. For instance, <code>Ma!A</code> represents the type <code>A</code> of model <code>Ma</code>. Also, to support modelling technologies that provide hierarchical grouping of types (e.g. using packages) the <code>::</code> notation is used to separate between packages and classes. A model element type supports the following operations:</p>
<table>
<thead>
<tr>
<th>Signature</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>all() : Set</td>
<td>Alias for allOfKind() (for syntax-compactness purposes)</td>
</tr>
<tr>
<td>allInstances() : Set</td>
<td>Alias for allOfKind() (for compatibility with OCL)</td>
</tr>
<tr>
<td>allOfKind() : Set</td>
<td>Returns all the elements in the model that are instances either of the type itself or of one of its subtypes</td>
</tr>
<tr>
<td>allOfType() : Set</td>
<td>Returns all the elements in the model that are instances of the type</td>
</tr>
<tr>
<td>createInstance() : Any</td>
<td>Creates an instance of the type in the model. The same can be achieved using the <code>new</code> operator (see below)</td>
</tr>
<tr>
<td>isInstantiable() : Boolean</td>
<td>Returns true if the type is instantiable (i.e. non-abstract)</td>
</tr>
</tbody>
</table>
<p>As an example of the concrete syntax, the listing below retrieves all the instances of the Class type (including instances of its subtypes) defined in the Core package of the UML 1.4 metamodel that are contained in the model named
UML14.</p>
<div class="highlight"><pre><span></span><code>UML14!Core::Foundation::Class.allInstances();
</code></pre></div>
<h3 id="creating-and-deleting-model-elements">Creating and Deleting Model Elements<a class="headerlink" href="#creating-and-deleting-model-elements" title="Permanent link">&para;</a></h3>
<p>EOL provides the <code>new</code> and <code>delete</code> operators for creating and deleting model elements as shown below. The <code>new</code> operator is an alias for the <code>createInstance()</code> method above, and can also be used to create instances of primitive and <a href="#native-types">native types</a> (i.e Java classes).</p>
<pre class="prettyprint lang-eol"><code>var t : new Tree; // Creates a new instance of type Tree
var p : new Source!Person; // Creates a new Person in model Source
delete t; // Deletes the element created in line 1</code></pre>
<h2 id="expressions">Expressions<a class="headerlink" href="#expressions" title="Permanent link">&para;</a></h2>
<h3 id="literal-values">Literal Values<a class="headerlink" href="#literal-values" title="Permanent link">&para;</a></h3>
<p>EOL provides special syntax constructs to create instances of each of
the built-in types:</p>
<ul>
<li>Integer literals are defined by using one or more decimal digits (such as <code>42</code> or <code>999</code>). Optionally, long integers (with the same precision as a Java <code>Long</code>) can be produced by adding a "l" suffix, such as <code>42l</code>.</li>
<li>
<p>Real literals are defined by:</p>
<ul>
<li>Adding a decimal separator and non-empty fractional part to the
integer part, such as <code>42.0</code> or <code>3.14</code>. Please note that <code>.2</code>
and <code>2.</code> are <code>not</code> valid literals.</li>
<li>Adding a floating point suffix: "f" and "F" denote single
precision, and "d" and "D" denote double precision. For example,
<code>2f</code> or <code>3D</code>.</li>
<li>Adding an exponent, such as <code>2e+1</code> (equal to <code>2e1</code>) or <code>2e-1</code>.</li>
<li>Using any combination of the above options.</li>
</ul>
</li>
<li>
<p>String literals are sequences of characters delimited by single (<code>'hi'</code>) or double (<code>"hi"</code>) quotes. Quotes inside the string can be escaped by using a backslash, such as in <code>'A\'s'</code> or <code>"A\"s"</code>. Literal backslashes need to be escaped as well, such as in <code>'A\\B'</code>. Special escape sequences are also provided: <code>\n</code> for a newline, <code>\t</code> for a horizontal tab and <code>\r</code> for a carriage return, among others.</p>
</li>
<li>
<p>Boolean literals use the <code>true</code> reserved keyword for the true Boolean value, and <code>false</code> reserved keyword for the false Boolean value.</p>
</li>
<li>
<p>Sequence and most other collections (except <code>Map</code>s) also have literals. Their format is <code>T {e}</code>, where <code>T</code> is the name of the type and <code>e</code> are zero or more elements, separated by commas. For instance, <code>Sequence{}</code> is the empty sequence, and <code>Set {1, 2, 3}</code> is the set of numbers between 1 and 3.</p>
</li>
<li>
<p>Map literals are similar to the sequential collection literals, but their elements are of the form <code>key = value</code>. For instance, <code>Map{"a" = 1, "b" = 2}</code> is a map which has two keys, "a" and "b", which map to the integer values 1 and 2, respectively.</p>
<p>Please note that, when defining an element such as <code>1 = 2 = 3</code>, the
key would be <code>1</code> and the value would be the result of evaluating <code>2
= 3</code> (false). If you would like to use the result of the expression
<code>1 = 2</code> as key, you will need to enclose it in parenthesis, such as
in <code>(1 = 2) = 3</code>.</p>
</li>
</ul>
<h3 id="feature-navigation">Feature Navigation<a class="headerlink" href="#feature-navigation" title="Permanent link">&para;</a></h3>
<p>Since EOL needs to manage models defined using object oriented modelling technologies, it provides expressions to navigate properties and invoke simple and declarative operations on objects.</p>
<p>In terms of concrete syntax, <code>.</code> is used as a uniform operator to access a property of an object and to invoke an operation on it. The <code>-&gt;</code> operator, which is used in OCL to invoke first-order logic operations on sets, has been also preserved for syntax compatibility reasons. In EOL, every operation can be invoked both using the <code>.</code> or the <code>-&gt;</code> operators, with a slightly different semantics to enable overriding the built-in operations. If the <code>.</code> operator is used, precedence is given to the user-defined operations, otherwise precedence is given to the built-in operations. For instance, the Any type defines a println() method that prints the string representation of an object to the standard output stream. In the listing below, the user has defined another parameterless println() operation in the context of Any. Therefore the call to <code>println()</code> in line 1 will be dispatched to the user-defined <code>println()</code> operation defined in line 3. In its body the operation uses the <code>-&gt;</code> operator to invoke the built-in <code>println()</code> operation (line 4).</p>
<pre class="prettyprint lang-eol"><code>"Something".println();
operation Any println() : Any {
("Printing : " + self)-&gt;println();
}</code></pre>
<div class="admonition info">
<p class="admonition-title">Navigating to the parent/children of model elements</p>
<p>EOL does not provide a technology-independent way of navigating to the parent/children of a model element. If you need to do this, you should use any methods provided by the underlying modelling platform. For example, as all elements of EMF models are instances of the <a href="https://download.eclipse.org/modeling/emf/emf/javadoc/2.5.0/org/eclipse/emf/ecore/EObject.html">EObject</a> Java class, the <code>me.eContainer()</code> and <code>me.eContents()</code> method calls in EMF return the parent and children of element <code>me</code> respectively.</p>
</div>
<h3 id="escaping-reserved-keywords">Escaping Reserved Keywords<a class="headerlink" href="#escaping-reserved-keywords" title="Permanent link">&para;</a></h3>
<p>Due to the variable nature of (meta-)models and the various domain-specific languages of Epsilon (including EOL itself), feature navigation calls may clash with reserved keywords, leading to a parsing error. Back-ticks can be used to escape such keywords. For example, if a model element contains a feature called <code>operation</code>, then this can be navigated as shown in the listing below.</p>
<pre class="prettyprint lang-eol"><code>var op = modelElement.`operation`;</code></pre>
<h3 id="arithmetical-and-comparison-operators">Arithmetical and Comparison Operators<a class="headerlink" href="#arithmetical-and-comparison-operators" title="Permanent link">&para;</a></h3>
<p>EOL provides common operators for performing arithmetical computations and comparisons illustrated in the following two tables respectively.</p>
<table>
<thead>
<tr>
<th>Operator</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>+</td>
<td>Adds reals/integers and concatenates strings</td>
</tr>
<tr>
<td>-</td>
<td>Subtracts reals/integers</td>
</tr>
<tr>
<td>- (unary).</td>
<td>Returns the negative of a real/integer</td>
</tr>
<tr>
<td>*</td>
<td>Multiplies reals/integers</td>
</tr>
<tr>
<td>/</td>
<td>Divides reals/integers</td>
</tr>
<tr>
<td>+=</td>
<td>Adds the r-value to the l-value</td>
</tr>
<tr>
<td>-=</td>
<td>Subtracts the r-value from the l-value</td>
</tr>
<tr>
<td>*=</td>
<td>Multiplies the l-value by the r-value</td>
</tr>
<tr>
<td>/=</td>
<td>Divides the l-value by the r-value</td>
</tr>
<tr>
<td>++</td>
<td>Increments the integer by one</td>
</tr>
<tr>
<td>--</td>
<td>Decrements the integer by one</td>
</tr>
</tbody>
</table>
<table>
<thead>
<tr>
<th>Operator</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>=</td>
<td>Returns true if the left hand side equals the right hand side. In the case of primitive types (String, Boolean, Integer, Real) the operator compares the values; in the case of objects it returns true if the two expressions evaluate to the same object</td>
</tr>
<tr>
<td>==</td>
<td>Same as =</td>
</tr>
<tr>
<td>&lt;&gt;</td>
<td>Is the logical negation of the (=) operator</td>
</tr>
<tr>
<td>!=</td>
<td>Same as &lt;&gt;</td>
</tr>
<tr>
<td>&gt;</td>
<td>For reals/integers returns true if the left hand side is greater than the right hand side number</td>
</tr>
<tr>
<td>&lt;</td>
<td>For reals/integers returns true if the left hand side is less than the right hand side number</td>
</tr>
<tr>
<td>&gt;=</td>
<td>For reals/integers returns true if the left hand side is greater or equal to the right hand side number</td>
</tr>
<tr>
<td>&lt;=</td>
<td>For reals/integers returns true if the left hand side is less or equal to then right hand side number</td>
</tr>
</tbody>
</table>
<h3 id="logical-operators">Logical Operators<a class="headerlink" href="#logical-operators" title="Permanent link">&para;</a></h3>
<p>EOL provides common operators for performing logical computations illustrated in the table below. Logical operations apply only to instances of the Boolean primitive type.</p>
<div class="admonition warning">
<p class="admonition-title">Operator Precedence</p>
<p>All logical operators in EOL have the same priority. This is in contrast to other languages like Java where e.g. <code>and</code> has a higher priority than <code>or</code>. As a result, while <code>true || true &amp;&amp; false</code> returns <code>true</code> in Java, the equivalent <code>true or true and false</code> expression in EOL returns <code>false</code>. Default priorities can be overridden using brackets (<code>true or (true and false)</code> in this case.)</p>
</div>
<table>
<thead>
<tr>
<th>Operator</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>and</td>
<td>Returns the logical conjunction of the two expressions</td>
</tr>
<tr>
<td>or</td>
<td>Returns the logical disjunction of the two expressions</td>
</tr>
<tr>
<td>not</td>
<td>Returns the logical negation of the expression</td>
</tr>
<tr>
<td>implies</td>
<td>Returns the logical implication of the two expressions (see below)</td>
</tr>
<tr>
<td>xor</td>
<td>Returns true if only one of the involved expressions evaluates to true and false otherwise</td>
</tr>
</tbody>
</table>
<p>The truth table for the <code>implies</code> logical operator is below.</p>
<table>
<thead>
<tr>
<th>Left</th>
<th>Right</th>
<th>Result</th>
</tr>
</thead>
<tbody>
<tr>
<td>true</td>
<td>true</td>
<td>true</td>
</tr>
<tr>
<td>true</td>
<td>false</td>
<td>false</td>
</tr>
<tr>
<td>false</td>
<td>true</td>
<td>true</td>
</tr>
<tr>
<td>false</td>
<td>false</td>
<td>true</td>
</tr>
</tbody>
</table>
<h3 id="ternary-operator">Ternary Operator<a class="headerlink" href="#ternary-operator" title="Permanent link">&para;</a></h3>
<p>As of version 2.0, EOL has a ternary operator which is a concise way of using if/else as an expression. The semantics and syntax are similar to Java, but can be used anywhere as an expression, not only in variable assignments or return statements. The listing below shows some examples of this<sup id="fnref:5"><a class="footnote-ref" href="#fn:5">5</a></sup>. Note that is also possible to use the <code>else</code> keyword in place of the colon for separating the true and false expressions for greater clarity. As one would expect, the branches are evaluated lazily: only one of the branches is executed and returned as the result of the expression depending on the value of the Boolean expression before the question mark.</p>
<pre class="prettyprint lang-eol"><code>var result = 2+2==4 ? "Yes" else "No";
return ((result == "Yes" ? 1 : 0) * 2 == 2).mod(2) == 0;</code></pre>
<h3 id="safe-navigation-and-elvis-operator">Safe Navigation and Elvis Operator<a class="headerlink" href="#safe-navigation-and-elvis-operator" title="Permanent link">&para;</a></h3>
<p>As of version 2.1, EOL supports <a href="https://en.wikipedia.org/wiki/Safe_navigation_operator">safe null navigation</a> <code>?.</code>, which makes it more concise to chain feature call expressions without resorting to defensive <code>null</code> / <code>isDefined()</code> checks. In the following example, the variable <code>result</code> will be <code>null</code>, and the program won't crash since the safe navigation operator is used.</p>
<pre class="prettyprint lang-eol"><code>var a = null;
var result = a?.someProperty?.anotherProperty;</code></pre>
<p>The null variant of the <a href="https://en.wikipedia.org/wiki/Elvis_operator#Object_reference_variant">"Elvis operator"</a> can also be used to simplify null check ternary expressions, as shown in the example below.</p>
<p><pre class="prettyprint lang-eol"><code>var a = null;
var b = "result";
var c = a != null ? a : b;
var d = a ?: b;
assert(c == d);</code></pre>
As with the ternary operator, the Elvis operator can also be used anywhere an expression is expected, not just in assignments.</p>
<p>As of Epsilon 2.2, there is also the <code>?=</code> shortcut assignment operator. This is useful for reassigning a variable if it is null.
In other words, <code>a ?= b</code> is equivalent to <code>if (a == null) a = b;</code>.</p>
<pre class="prettyprint lang-eol"><code>var a = null;
var b = "result";
a ?= b;
assert(a == b);</code></pre>
<h3 id="enumerations">Enumerations<a class="headerlink" href="#enumerations" title="Permanent link">&para;</a></h3>
<p>EOL provides the # operator for accessing enumeration literals. For example, the VisibilityEnum#vk_public expression returns the value of the literal <code>vk_public</code> of the <code>VisibilityEnum</code> enumeration. For EMF metamodels, <code>VisibilityEnum#vk_public.instance</code> can also be used.</p>
<h2 id="statements">Statements<a class="headerlink" href="#statements" title="Permanent link">&para;</a></h2>
<h3 id="variable-declaration-statement">Variable Declaration Statement<a class="headerlink" href="#variable-declaration-statement" title="Permanent link">&para;</a></h3>
<p>A variable declaration statement declares the name and (optionally) the type and initial value of a variable in an EOL program. If no type is explicitly declared, the variable is assumed to be of type <code>Any</code>. For variables of primitive type, declaration automatically creates an instance of the type with the default values presented in the table below. For non-primitive types the user has to explicitly assign the value of the variable either by using the <code>new</code> keyword or by providing an initial value expression. If neither is done the value of the variable is undefined. Variables in EOL are strongly-typed. Therefore a variable can only be assigned values that conform to its type (or a sub-type of it).</p>
<table>
<thead>
<tr>
<th>Type</th>
<th>Default value</th>
</tr>
</thead>
<tbody>
<tr>
<td>Integer</td>
<td>0</td>
</tr>
<tr>
<td>Boolean</td>
<td>false</td>
</tr>
<tr>
<td>String</td>
<td>""</td>
</tr>
<tr>
<td>Real</td>
<td>0.0</td>
</tr>
</tbody>
</table>
<h5 id="scope">Scope<a class="headerlink" href="#scope" title="Permanent link">&para;</a></h5>
<p>The scope of variables in EOL is generally limited to the block of statements where they are defined, including any nested blocks. Nevertheless, as discussed in the sequel, there are cases in task-specific languages that build atop EOL where the scope of variables is expanded to other non-nested blocks as well. EOL also allows variable shadowing; that is to define a variable with the same name in a nested block that overrides a variable defined in an outer block.</p>
<p>The listing below provides an example of declaring and using variables. </p>
<ul>
<li>Line 1 defines a variable named <code>i</code> of type <code>Integer</code> and assigns it an initial value of <code>5</code>. </li>
<li>Line 2 defines a variable named <code>c</code> of type <code>Class</code> (from model Uml) and creates a new instance of the type in the model (by using the <code>new</code> keyword). </li>
<li>The commented out assignment statement of line 3 would raise a runtime error since it would attempt to assign a <code>String</code> value to an <code>Integer</code> variable. </li>
<li>The condition of line 4 returns true since the <code>c</code> variable has been initialized before. </li>
<li>Line 5 defines a new variable also named <code>i</code> that is of type <code>String</code> and which overrides the <code>Integer</code> variable declared in line 1. </li>
<li>Therefore the assignment statement of line 6 is legitimate as it assigns a string value to a variable of type String. </li>
<li>Finally, as the program has exited the scope of the <code>if</code> statement, the assignment statement of line 7 is also legitimate as it refers to the <code>i</code> variable defined in line 1.</li>
</ul>
<pre class="prettyprint lang-eol"><code>var i : Integer = 5;
var c : new Uml!Class;
//i = "somevalue";
if (c.isDefined()) {
var i : String;
i = "somevalue";
}
i = 3;</code></pre>
<h3 id="assignment-statement">Assignment Statement<a class="headerlink" href="#assignment-statement" title="Permanent link">&para;</a></h3>
<p>The assignment statement is used to update the values of variables and properties of native objects and model elements.</p>
<h5 id="variable-assignment">Variable Assignment<a class="headerlink" href="#variable-assignment" title="Permanent link">&para;</a></h5>
<p>When the left hand side of an assignment statement is a variable, the value of the variable is updated to the object to which the right hand side evaluates to. If the type of the right hand side is not compatible (kind-of relationship) with the type of the variable, the assignment is illegal and a runtime error is raised. Assignment to objects of primitive types is performed by value while assignment to instances of non-primitive values is performed by reference. For example, in the listing below, in line 1 the value of the a variable is set to a new Class in the Uml model. In line 2, a new untyped variable b is declared and its value is assigned to a. In line 3 the name of the class is updated to Customer and thus, line 4 prints Customer to the standard output stream.</p>
<pre class="prettyprint lang-eol"><code>var a : new Uml!Class;
var b = a;
a.name = "Customer";
b.name.println();</code></pre>
<p>On the other hand, in the listing below, in line 1 the a String variable is declared. In line 2 an untyped variable b is declared. In line 3, the value of a is changed to Customer (which is an instance of the primitive <code>String</code> type). This has no effect on b and thus line 4 prints an empty string to the standard output stream.</p>
<pre class="prettyprint lang-eol"><code>var a : String;
var b = a;
a = "Customer";
b.println();</code></pre>
<h5 id="native-object-property-assignment">Native Object Property Assignment<a class="headerlink" href="#native-object-property-assignment" title="Permanent link">&para;</a></h5>
<p>When the left hand side of the assignment is a property of a native object, deciding on the legality and providing the semantics of the assignment is delegated to the execution engine. For example, in a Java-based execution engine, given that x is a native object, the statement <code>x.y = a</code> may be interpreted as <code>x.setY(a)</code> or if x is an instance of a map <code>x.put("y",a)</code>. By contrast, in a C# implementation, it can be interpreted as <code>x.y = a</code> since the language natively supports properties in classes.</p>
<h5 id="model-element-property-assignment">Model Element Property Assignment<a class="headerlink" href="#model-element-property-assignment" title="Permanent link">&para;</a></h5>
<p>When the left hand side of the assignment is a property of a model element, the model that owns the particular model element (accessible using the <code>ModelRepository.getOwningModel()</code> operation) is responsible for implementing the semantics of the assignment using its <a href="../emc">associated</a> <code>propertyGetter</code>. For example, if x is a model element, the statement <code>x.y = a</code> may be interpreted using the Java code of the first listing below if x belongs to an EMF-based model or using the Java code of the second listing if it belongs to an MDR-based model.</p>
<div class="highlight"><pre><span></span><code><span class="n">EStructuralFeature</span> <span class="n">feature</span> <span class="o">=</span> <span class="n">x</span><span class="p">.</span><span class="na">eClass</span><span class="p">().</span><span class="na">getEStructuralFeature</span><span class="p">(</span><span class="s">&quot;y&quot;</span><span class="p">);</span>
<span class="n">x</span><span class="p">.</span><span class="na">eSet</span><span class="p">(</span><span class="n">feature</span><span class="p">,</span> <span class="n">a</span><span class="p">);</span>
</code></pre></div>
<div class="highlight"><pre><span></span><code><span class="n">StructuralFeature</span> <span class="n">feature</span> <span class="o">=</span> <span class="n">findStructuralFeature</span><span class="p">(</span><span class="n">x</span><span class="p">.</span><span class="na">refClass</span><span class="p">(),</span> <span class="s">&quot;y&quot;</span><span class="p">);</span>
<span class="n">x</span><span class="p">.</span><span class="na">refSetValue</span><span class="p">(</span><span class="n">feature</span><span class="p">,</span> <span class="n">a</span><span class="p">);</span>
</code></pre></div>
<h3 id="special-assignment-statement">Special Assignment Statement<a class="headerlink" href="#special-assignment-statement" title="Permanent link">&para;</a></h3>
<p>In task-specific languages, an assignment operator with task-specific semantics is often required. Therefore, EOL provides an additional assignment operator. In standalone EOL, the operator has the same semantics with the primary assignment operator discussed above, however task-specific languages can redefine its semantics to implement custom assignment behaviour. For example, consider the simple model-to-model transformation of the listing below where a simple object oriented model is transformed to a simple database model using an ETL transformation.</p>
<pre class="prettyprint lang-etl"><code>rule Class2Table
transform c : OO!Class
to t : DB!Table {
t.name = c.name;
}
rule Attribute2Column
transform a : OO!Attribute
to c : DB!Column {
c.name = a.name;
//c.owningTable = a.owningClass;
c.owningTable ::= a.owningClass;
}</code></pre>
<p>The <code>Class2Table</code> rule transforms a <code>Class</code> of the OO model into a <code>Table</code> in the DB model and sets the name of the table to be the same as the name of the class. Rule <code>Atribute2Column</code> transforms an <code>Attribute</code> from the OO model into a <code>Column</code> in the DB model. Except for setting its name (line 12), it also needs to define that the column belongs to the table which corresponds to the class that defines the source attribute. The commented-out assignment statement of line 13 cannot be used for this purpose since it would illegally attempt to assign the owningTable feature of the column to a model element of an inappropriate type (<code>OO!Class</code>). However, the special assignment operator in ETL has <a href="../etl/#overriding-the-semantics-of-the-eol-specialassignmentoperator">language-specific semantics</a>, and thus in line 14 it assigns to the <code>owningTable</code> feature not the class that owns the attribute but its corresponding table (calculated using the <code>Class2Table</code> rule) in the DB model.</p>
<h3 id="if-statement">If Statement<a class="headerlink" href="#if-statement" title="Permanent link">&para;</a></h3>
<p>As in most programming languages, an if statement consists of a condition, a block of statements that is executed if the condition is satisfied and (optionally) a block of statements that is executed otherwise. As an example, in the listing below, if variable a holds a value that is greater than 0 the statement of line 3 is executed, otherwise the statement of line 5 is executed.</p>
<pre class="prettyprint lang-eol"><code>if (a &gt; 0) {
"A is greater than 0".println();
}
else { "A is less equal than 0".println(); }</code></pre>
<h3 id="switch-statement">Switch Statement<a class="headerlink" href="#switch-statement" title="Permanent link">&para;</a></h3>
<p>A switch statement consists of an expression and a set of cases, and can be used to implement multi-branching. Unlike Java/C, switch in EOL doesn't by default fall through to the next case after a successful one. Therefore, it is not necessary to add a <code>break</code> statement after each case. To enable falling through to all subsequent cases you can use the <code>continue</code> statement. Also, unlike Java/C, the switch expression can return anything (not only integers). As an example, when executed, the code in the listing below prints <code>2</code> while the code in the following listing prints <code>2,3,default</code>.</p>
<pre class="prettyprint lang-eol"><code>var i = "2";
switch (i) {
case "1" : "1".println();
case "2" : "2".println();
case "3" : "3".println();
default : "default".println();
}</code></pre>
<pre class="prettyprint lang-eol"><code>var i = "2";
switch (i) {
case "1" : "1".println();
case "2" : "2".println(); continue;
case "3" : "3".println();
default : "default".println();
}</code></pre>
<h3 id="while-statement">While Statement<a class="headerlink" href="#while-statement" title="Permanent link">&para;</a></h3>
<p>A while statement consists of a condition and a block of statements which are executed as long as the condition is satisfied. For example, in the listing below, the body of the while statement is executed 5 times printing the numbers 0 to 4 to the output console. Inside the body of a <code>while</code> statement, the built-in read-only <code>loopCount</code> integer variable holds the number of times the innermost loop has been executed so far (including the current iteration). Right after entering the loop for the first time and before running the first statement in its body, <code>loopCount</code> is set to 1, and it is incremented after each following iteration.</p>
<pre class="prettyprint lang-eol"><code>var i : Integer = 0;
while (i &lt; 5) {
// both lines print the same thing
i.println();
(loopCount - 1).println();
// increment the counter
i = i+1;
}</code></pre>
<h3 id="for-statement">For Statement<a class="headerlink" href="#for-statement" title="Permanent link">&para;</a></h3>
<p>In EOL, for statements are used to iterate the contents of collections. A for statement defines a typed iterator and an iterated collection as well as a block of statements that is executed for every item in the collection that has a kind-of relationship with the type defined by the iterator. As with the majority of programming languages, modifying a collection while iterating it raises a runtime error. To avoid this situation, users can use the clone() built-in operation of the <a href="#collections-and-maps">Collection</a> type.</p>
<pre class="prettyprint lang-eol"><code>var col : Sequence = Sequence{"a", 1, 2, 2.5, "b"};
for (r : Real in col) {
r.print();
if (hasMore){",".print();}
}</code></pre>
<p>Inside the body of a <code>for</code> statement, two built-in read-only variables are visible: the <code>loopCount</code> integer variable and the <code>hasMore</code> boolean variable. <code>hasMore</code> is used to determine if there are more items if the collection for which the loop will be executed. For example, in the listing below the <code>col</code> heterogeneous <code>Sequence</code> is defined that contains two strings (<code>a</code> and <code>b</code>), two integers (<code>1</code>,<code>2</code>) and one real (<code>2.5</code>). The for loop of line 2 only iterates through the items of the collection that are of kind Real and therefore prints <code>1,2,2.5</code> to the standard output stream.</p>
<h3 id="break-breakall-and-continue-statements">Break, BreakAll and Continue Statements<a class="headerlink" href="#break-breakall-and-continue-statements" title="Permanent link">&para;</a></h3>
<p>To exit from for and while loops on demand, EOL provides the break and breakAll statements. The break statement exits the innermost loop while the breakAll statement exits all outer loops as well. On the other hand, to skip a particular loop and proceed with the next one, EOL provides the continue statement. For example, the program in the listing below, prints <code>2,1 3,1</code> to the standard output stream.</p>
<pre class="prettyprint lang-eol"><code>for (i in Sequence{1..3}) {
if (i = 1) {continue;}
for (j in Sequence{1..4}) {
if (j = 2) {break;}
if (j = 3) {breakAll;}
(i + "," + j).println();
}
}</code></pre>
<h3 id="throw-statement">Throw Statement<a class="headerlink" href="#throw-statement" title="Permanent link">&para;</a></h3>
<p>EOL provides the throw statement for throwing a value as an Java exception. This is especially useful when invoking EOL scripts from Java code: by catching and processing the exception, the Java code may be able to automatically handle the problem without requiring user input. Any value can be thrown, as shown in the listing below where we throw a number and a string.</p>
<pre class="prettyprint lang-eol"><code>throw 42;
throw "Error!";</code></pre>
<h3 id="transaction-statement">Transaction Statement<a class="headerlink" href="#transaction-statement" title="Permanent link">&para;</a></h3>
<p>The underlying <a href="../emc">EMC layer</a> provides support for transactions in models. To utilize this feature EOL provides the transaction statement. A transaction statement (optionally) defines the models that participate in the transaction. If no models are defined, it is assumed that all the models that are accessible from the enclosing program participate. When the statement is executed, a transaction is started on each participating model. If no errors are raised during the execution of the contained statements, any changes made to model elements are committed. On the other hand, if an error is raised the transaction is rolled back and any changes made to the models in the context of the transaction are undone. The user can also use the abort statement to explicitly exit a transaction and roll-back any changes done in its context. In the listing below, an example of using this feature in a simulation problem is illustrated.</p>
<pre class="prettyprint lang-eol"><code>var system : System.allInstances.first();
for (i in Sequence {1..100}) {
transaction {
var failedProcessors : Set;
while (failedProcessors.size() &lt; 10) {
failedProcessors.add(system.processors.random());
}
for (processor in failedProcessors) {
processor.failed = true;
processor.moveTasksElsewhere();
}
system.evaluateAvailability();
abort;
}
}</code></pre>
<p>In this problem, a system consists of a number of processors. A processor manages some tasks and can fail at any time. The EOL program in the listing above performs 100 simulation steps, in every one of which 10 random processors from the model (lines 7-11) are marked as failed by setting their <code>failed</code> property to true (line 14). Then, the tasks that the failed processors manage are moved to other processors (line 15). Finally the availability of the system in this state is evaluated.</p>
<p>After a simulation step, the state of the model has been drastically changed since processors have failed and tasks have been relocated. To be able to restore the model to its original state after every simulation step, each step is executed in the context of a transaction which is explicitly aborted (line 20) after evaluating the availability of the system. Therefore after each simulation step the model is restored to its original state for the next step to be executed.</p>
<h3 id="extended-properties">Extended Properties<a class="headerlink" href="#extended-properties" title="Permanent link">&para;</a></h3>
<p>Quite often, during a model management operation it is necessary to associate model elements with information that is not supported by the metamodel they conform to. For instance, the EOL program in the listing below calculates the depth of each Tree element in a model that conforms to the Tree metamodel displayed below.</p>
<div class="mermaid mermaid-30">classDiagram
class Tree {
+label: String
+parent: Tree
+children: Tree[*]
}
Tree -- Tree </div>
<p>As the Tree metamodel doesn't support a <code>depth</code> property in the Tree metaclass, each Tree has to be associated with its calculated depth using the <code>depths</code> map defined in line 1. Another approach would be to extend the Tree metamodel to support the desired <code>depth</code> property; however, applying this technique every time an additional property is needed for some model management operation would quickly pollute the metamodel with properties of secondary importance.</p>
<pre class="prettyprint lang-eol"><code>var depths = new Map;
for (n in Tree.allInstances.select(t|not t.parent.isDefined())) {
n.setDepth(0);
}
for (n in Tree.allInstances) {
(n.name + " " + depths.get(n)).println();
}
operation Tree setDepth(depth : Integer) {
depths.put(self,depth);
for (c in self.children) {
c.setDepth(depth + 1);
}
}</code></pre>
<p>To simplify the code required in such cases, EOL provides the concept of <em>extended properties</em>. In terms of concrete syntax, an extended property is a normal property, the name of which starts with the tilde character (<code>~</code>). With regards to its execution semantics, the first time the value of an extended property of an object is assigned, the property is created and associated with the object. Then, the property can be accessed as a normal property. If an extended property is accessed before it is assigned, it returns <code>null</code>. The listing below demonstrates using a <code>~depth</code> extended property to eliminate the need for using the <code>depths</code> map in the listing that follows it.</p>
<pre class="prettyprint lang-eol"><code>for (n in Tree.allInstances.select(t|not t.parent.isDefined())) {
n.setDepth(0);
}
for (n in Tree.allInstances) {
(n.name + " " + n.~depth).println();
}
operation Tree setDepth(depth : Integer) {
self.~depth = depth;
for (c in self.children) {
c.setDepth(depth + 1);
}
}</code></pre>
<h3 id="context-independent-user-input">Context-Independent User Input<a class="headerlink" href="#context-independent-user-input" title="Permanent link">&para;</a></h3>
<p>A common assumption in model management languages is that model management tasks are only executed in a batch-manner without human intervention. However, as demonstrated in the sequel, it is often useful for the user to provide feedback that can precisely drive the execution of a model management operation.</p>
<p>Model management operations can be executed in a number of runtime environments in each of which a different user-input method is more appropriate. For instance when executed in the context of an IDE (such as Eclipse) visual dialogs are preferable, while when executed in the context of a server or from within an ANT workflow, a command-line user input interface is deemed more suitable. To abstract away from the different runtime environments and enable the user to specify user interaction statements uniformly and regardless of the runtime context, EOL provides the <code>IUserInput</code> interface that can be realized in different ways according to the execution environment and attached to the runtime context via the <code>IEolContext.setUserInput(IUserInput userInput)</code> method. The <code>IUserInput</code> specifies the methods presented in the table below.</p>
<table>
<thead>
<tr>
<th>Signature</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>inform(message : String)</td>
<td>Displays the specified message to the user</td>
</tr>
<tr>
<td>confirm(message : String, [default : Boolean]) : Boolean</td>
<td>Prompts the user to confirm if the condition described by the message holds</td>
</tr>
<tr>
<td>prompt(message : String, [default : String]) : String</td>
<td>Prompts the user for a string in response to the message</td>
</tr>
<tr>
<td>promptInteger(message : String, [default : Integer]) : Integer</td>
<td>Prompts the user for an Integer</td>
</tr>
<tr>
<td>promptReal(message : String, [default : Real]) : Real</td>
<td>Prompts the user for a Real</td>
</tr>
<tr>
<td>choose(message : String, options : Sequence, [default : Any]) : Any</td>
<td>Prompts the user to select one of the options</td>
</tr>
<tr>
<td>chooseMany(message : String, options : Sequence, [default : Sequence]) : Sequence</td>
<td>Prompts the user to select one or more of the options</td>
</tr>
</tbody>
</table>
<p>As displayed above, all the methods of the <code>IUserInput</code> interface accept
a <code>default</code> parameter. The purpose of this parameter is dual. First, it
enables the designer of the model management program to prompt the user
with the most likely value as a default choice and secondly it enables a
concrete implementation of the interface
(<code>UnattendedExecutionUserInput</code>) which returns the default values
without prompting the user at all and thus, can be used for unattended
execution of interactive Epsilon programs. The figures below demonstrate the interfaces through
which input is required by the user when the exemplar
<code>System.user.promptInteger("Please enter a number", 1);</code> statement is
executed using an Eclipse-based and a command-line-based <code>IUserInput</code>
implementation respectively.</p>
<p><img alt="Example of an Eclipse-based IUserInput
implementation" src="../images/EclipseUserInput.png" /></p>
<p><img alt="Example of a command-line-based IUserInput
implementation" src="../images/ConsoleUserInput.png" /></p>
<p>User-input facilities have been found to be particularly useful in all model management tasks. Such facilities are essential for performing operations on live models such as model validation and model refactoring but can also be useful in model comparison where marginal matching decisions can be delegated to the user and model transformation where the user can interactively specify the elements that will be transformed into corresponding elements in the target model.</p>
<h2 id="additional-resources">Additional Resources<a class="headerlink" href="#additional-resources" title="Permanent link">&para;</a></h2>
<p>Additional resources about EOL are available <a href="../articles/#epsilon-object-language">here</a>.</p>
<div class="footnote">
<hr />
<ol>
<li id="fn:1">
<p>Although the EOL parser permits loose statements (e.g. not contained in operations) between/after operations, these are ignored at runtime.&#160;<a class="footnote-backref" href="#fnref:1" title="Jump back to footnote 1 in the text">&#8617;</a></p>
</li>
<li id="fn:2">
<p>Parameters within square brackets are optional&#160;<a class="footnote-backref" href="#fnref:2" title="Jump back to footnote 2 in the text">&#8617;</a></p>
</li>
<li id="fn:3">
<p><a href="http://download.oracle.com/javase/8/docs/api/java/util/Formatter.html#syntax">http://download.oracle.com/javase/8/docs/api/java/util/Formatter.html#syntax</a>&#160;<a class="footnote-backref" href="#fnref:3" title="Jump back to footnote 3 in the text">&#8617;</a></p>
</li>
<li id="fn:4">
<p><a href="https://docs.oracle.com/javase/8/docs/api/java/util/stream/Stream.html">https://docs.oracle.com/javase/8/docs/api/java/util/stream/Stream.html</a>&#160;<a class="footnote-backref" href="#fnref:4" title="Jump back to footnote 4 in the text">&#8617;</a></p>
</li>
<li id="fn:5">
<p>For further examples of ternary operator, see <a href="https://git.eclipse.org/c/epsilon/org.eclipse.epsilon.git/tree/tests/org.eclipse.epsilon.eol.engine.test.acceptance/src/org/eclipse/epsilon/eol/engine/test/acceptance/TernaryTests.eol">https://git.eclipse.org/c/epsilon/org.eclipse.epsilon.git/tree/tests/org.eclipse.epsilon.eol.engine.test.acceptance/src/org/eclipse/epsilon/eol/engine/test/acceptance/TernaryTests.eol</a>&#160;<a class="footnote-backref" href="#fnref:5" title="Jump back to footnote 5 in the text">&#8617;</a></p>
</li>
</ol>
</div>
</article>
</div>
</div>
</main>
<footer class="md-footer">
<div class="md-footer-nav">
<nav class="md-footer-nav__inner md-grid">
<a href="../emc/" title="Model Connectivity" class="md-flex md-footer-nav__link md-footer-nav__link--prev" rel="prev">
<div class="md-flex__cell md-flex__cell--shrink">
<i class="md-icon md-icon--arrow-back md-footer-nav__button"></i>
</div>
<div class="md-flex__cell md-flex__cell--stretch md-footer-nav__title">
<span class="md-flex__ellipsis">
<span class="md-footer-nav__direction">
Previous
</span>
Model Connectivity
</span>
</div>
</a>
<a href="../egl/" title="Code Generation (EGL)" class="md-flex md-footer-nav__link md-footer-nav__link--next" rel="next">
<div class="md-flex__cell md-flex__cell--stretch md-footer-nav__title">
<span class="md-flex__ellipsis">
<span class="md-footer-nav__direction">
Next
</span>
Code Generation (EGL)
</span>
</div>
<div class="md-flex__cell md-flex__cell--shrink">
<i class="md-icon md-icon--arrow-forward md-footer-nav__button"></i>
</div>
</a>
</nav>
</div>
<div class="md-footer-meta md-typeset">
<div class="md-footer-meta__inner md-grid">
<div class="md-footer-copyright">
<div class="md-footer-copyright__highlight">
Copyright © Eclipse Foundation, Inc. All Rights Reserved.
</div>
powered by
<a href="https://www.mkdocs.org">MkDocs</a>
and
<a href="https://squidfunk.github.io/mkdocs-material/">Material for MkDocs</a>
</div>
<div class="md-footer-copyright epsilon-eclipse-links">
<ul>
<li><a href="https://www.eclipse.org/legal/privacy.php">Privacy Policy</a></li>
<li><a href="https://www.eclipse.org/legal/termsofuse.php">Terms of Use</a></li>
<li><a href="https://www.eclipse.org/legal/copyright.php">Copyright Agent</a></li>
</ul>
</div>
<div class="md-footer-social">
<a href="https://twitter.com/eclipseepsilon" target="_blank" rel="noopener" title="twitter.com" class="md-footer-social__link">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path d="M459.37 151.716c.325 4.548.325 9.097.325 13.645 0 138.72-105.583 298.558-298.558 298.558-59.452 0-114.68-17.219-161.137-47.106 8.447.974 16.568 1.299 25.34 1.299 49.055 0 94.213-16.568 130.274-44.832-46.132-.975-84.792-31.188-98.112-72.772 6.498.974 12.995 1.624 19.818 1.624 9.421 0 18.843-1.3 27.614-3.573-48.081-9.747-84.143-51.98-84.143-102.985v-1.299c13.969 7.797 30.214 12.67 47.431 13.319-28.264-18.843-46.781-51.005-46.781-87.391 0-19.492 5.197-37.36 14.294-52.954 51.655 63.675 129.3 105.258 216.365 109.807-1.624-7.797-2.599-15.918-2.599-24.04 0-57.828 46.782-104.934 104.934-104.934 30.213 0 57.502 12.67 76.67 33.137 23.715-4.548 46.456-13.32 66.599-25.34-7.798 24.366-24.366 44.833-46.132 57.827 21.117-2.273 41.584-8.122 60.426-16.243-14.292 20.791-32.161 39.308-52.628 54.253z"/></svg>
</a>
<a href="https://youtube.com/epsilondevs" target="_blank" rel="noopener" title="youtube.com" class="md-footer-social__link">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512"><path d="M549.655 124.083c-6.281-23.65-24.787-42.276-48.284-48.597C458.781 64 288 64 288 64S117.22 64 74.629 75.486c-23.497 6.322-42.003 24.947-48.284 48.597-11.412 42.867-11.412 132.305-11.412 132.305s0 89.438 11.412 132.305c6.281 23.65 24.787 41.5 48.284 47.821C117.22 448 288 448 288 448s170.78 0 213.371-11.486c23.497-6.321 42.003-24.171 48.284-47.821 11.412-42.867 11.412-132.305 11.412-132.305s0-89.438-11.412-132.305zm-317.51 213.508V175.185l142.739 81.205-142.739 81.201z"/></svg>
</a>
</div>
</div>
</div>
</footer>
</div>
<div class="md-dialog" data-md-component="dialog">
<div class="md-dialog__inner md-typeset"></div>
</div>
<script id="__config" type="application/json">{"base": "../..", "features": [], "translations": {"clipboard.copy": "Copy to clipboard", "clipboard.copied": "Copied to clipboard", "search.config.lang": "en", "search.config.pipeline": "trimmer, stopWordFilter", "search.config.separator": "[\\s\\-]+", "search.placeholder": "Search", "search.result.placeholder": "Type to start searching", "search.result.none": "No matching documents", "search.result.one": "1 matching document", "search.result.other": "# matching documents", "search.result.more.one": "1 more on this page", "search.result.more.other": "# more on this page", "search.result.term.missing": "Missing"}, "search": "../../assets/javascripts/workers/search.d351de03.min.js", "version": null}</script>
<script src="../../assets/javascripts/bundle.a1609d9a.min.js"></script>
<script src="https://unpkg.com/mermaid@8.5.1/dist/mermaid.min.js"></script>
<script src="../../assets/javascript/mermaid.js"></script>
<script src="../../assets/javascript/jquery.js"></script>
<script src="../../assets/javascript/slick.min.js"></script>
<script src="../../assets/javascript/google-code-prettify/prettify.js"></script>
<script src="../../assets/javascript/google-code-prettify/lang-emfatic.js"></script>
<script src="../../assets/javascript/google-code-prettify/lang-epsilon.js"></script>
<script src="../../assets/javascript/google-code-prettify/prettyprint.js"></script>
<script src="../../assets/javascript/extra.js"></script>
<script src="https://w.appzi.io/w.js?token=jlv6W"></script>
</body>
</html>