# Programmers Guide

## Similarities and Differences

The similarities come from the fundamental requirement of solving any data processing problem: First, understand the problem.

After that, in many programming environments, you use a “top-down” approach to map out the most direct line of logic to get your input transformed into the desired output. This is where the process diverges in ECL, because the tool itself requires a different way of thinking about forming the solution, and the direct route is not always the fastest. ECL requires a “bottom-up” approach to problem solving.

### “Atomic” Programming

In ECL, once you understand what the end result needs to be, you ignore the direct line from problem input to end result and instead start by breaking the issue into as many pieces as possible–the smaller the better. By creating “atomic” bits of ECL code, you’ve done all the known and easy bits of the problem. This usually gets you 80% of the way to the solution without having to do anything terribly difficult.

Once you’ve taken all the bits and made them as atomic as possible, you can then start combining them to go the other 20% of the way to produce your final solution. In other words, you start by doing the little bits that you know you can easily do, then use those bits in combination to produce increasingly complex logic that builds the solution organically.

### Growing Solutions

The basic Attribute building blocks in ECL are the Set, Boolean, Recordset, and Value Attribute types. Each of these can be made as “atomic” as needed so that they may be used in combination to produce “molecules” of more complex logic that may then be further combined to produce a complete “organism” that produces the final result.

For example, assume you have a problem that requires you to produce a set of records wherein a particular field in your output must contain one of several specified values (say, 1, 3, 4, or 7). In many programming languages, the pseudo-code to produce that output would look something like this:

`Start at top of MyFileLoop through MyFile records If MyField = 1 or MyField = 3 or MyField = 4 or MyField = 7 Include record in output set Else Throw out record and go back to top of loopend if and loop`

``` ```
``` While in ECL, the actual code would be: SetValidValues := [1,3,4,7]; //Set DefinitionIsValidRec := MyFile.MyField IN SetValidValues; //BooleanValRecsMyFile := MyFile(IsValidRec); //filtered RecordsetOUTPUT(ValRecsMyFile); ```
``` The thought process behind writing this code is: "I know I have a set of constant values in the spec, so I can start by creating a Set attribute of the valid values... "And now that I have a Set defined, I can use that Set to create a Boolean Attribute to test whether the field I'm interested in contains one of the valid values... "And now that I have a Boolean defined, I can use that Boolean as the filter condition to produce the Recordset I need to output." The process starts with creating the Set Attribute "atom," then using it to build the Boolean "molecule," then using the Boolean to grow the "organism"--the final solution. "Ugly" ECL is Possible, Too Of course, that particular set of ECL could have been written like this (following a more top down thinking process): OUTPUT(MyFile(MyField IN [1,3,4,7])); The end result, in this case, would be the same. However, the overall usefulness of this code is drastically reduced because, in the first form, all the "atomic" bits are available for re-use elsewhere when similar problems come along. In this second form, they are not. And in all programming styles, code re-use is considered to be a good thing. Easy Optimization Most importantly, by breaking your ECL code into its smallest possible components, you allow ECL's optimizing compiler to do the best job possible of determining how to accomplish your desired result. This leads to another dichotomy between ECL and other programming languages: usually, the less code you write, the more "elegant" the solution; but in ECL, the more code you write, the better and more elegant the solution is generated for you. Remember, your Attributes are just definitions telling the compiler what to do, not how to do it. The more you break down the problem into its component pieces, the more leeway you give the optimizer to produce the fastest, most efficient executable code. ```
``` ```
``` ```
``` ```
``` ```
``` ```
``` LinkedIn Instagram GitHub YouTube Terms & Conditions Privacy Policy Cookie Policy Site Guidelines Subscribe to Newsletter Copyright © 2024 LexisNexis Risk Solutions. ```
``` // Javscript Functions // Get current time stamp in format: "8/10/2023, 03:18:14 PM" const now = new Date(); const formattedTime = now.toLocaleString("en-US", { month: "numeric", day: "numeric", year: "numeric", hour: "2-digit", minute: "2-digit", second: "2-digit", meridiem: "AM" }); // Assign layout_type value at screen size ranges const getScreenSize = () => { const width = window.innerWidth; if (width < 768) { return "mobile"; } else if (width < 1366) { return "tablet"; } else { return "desktop"; } }; // Get site_hierarchy by splitting URL sections into array const getUrlSections = () => { // Get the current URL. const currentUrl = window.location.pathname; // Split the URL into sections. const urlSections = currentUrl.split('/'); // Remove the empty section at the beginning of the array. urlSections.shift(); // If the last section is empty, remove it. if (urlSections[urlSections.length - 1] === '') { urlSections.pop(); } // Check if the first section is empty. if (urlSections.length === 0) { // Add the string 'Home' to the beginning of the array. urlSections.unshift('Home'); } // Return the array of URL sections. return urlSections; }; // Assign JS variables for dataLayer const screenSize = getScreenSize(); const siteHierarchy = getUrlSections(); // Assign PHP variables to JS variable for dataLayer const pageId = document.querySelector('[data-page-id]').dataset.pageId; const pageName = document.querySelector('[data-page-name]').dataset.pageName; const vip = document.querySelector('[data-vip]').dataset.vip; const siteSection = document.querySelector('[data-site-section]').dataset.siteSection; const contentType = document.querySelector('[data-content-type]').dataset.contentType; const contentTopic = document.querySelector('[data-content-topic]').dataset.contentTopic; // Assign values to the dataLayer window.digitalData = { "cms_page_id": pageId, "content_topic": contentTopic, "content_type": contentType, "current_time": formattedTime, "default_title": pageName, "layout_type": screenSize, "site_events": "page_view", "site_hierarchy": siteHierarchy, "site_region": navigator.language, "site_section": siteSection, "user_ip": vip, } .wp-container-core-group-is-layout-1 > :where(:not(.alignleft):not(.alignright):not(.alignfull)){max-width:1133px;margin-left:auto !important;margin-right:auto !important;}.wp-container-core-group-is-layout-1 > .alignwide{max-width:1133px;}.wp-container-core-group-is-layout-1 .alignfull{max-width:none;}.wp-container-core-group-is-layout-3 > :where(:not(.alignleft):not(.alignright):not(.alignfull)){max-width:1133px;margin-left:auto !important;margin-right:auto !important;}.wp-container-core-group-is-layout-3 > .alignwide{max-width:1133px;}.wp-container-core-group-is-layout-3 .alignfull{max-width:none;}.wp-container-core-group-is-layout-5 > :where(:not(.alignleft):not(.alignright):not(.alignfull)){max-width:1133px;margin-left:auto !important;margin-right:auto !important;}.wp-container-core-group-is-layout-5 > .alignwide{max-width:1133px;}.wp-container-core-group-is-layout-5 .alignfull{max-width:none;}.wp-container-core-group-is-layout-6 > :where(:not(.alignleft):not(.alignright):not(.alignfull)){max-width:1133px;margin-left:auto !important;margin-right:auto !important;}.wp-container-core-group-is-layout-6 > .alignwide{max-width:1133px;}.wp-container-core-group-is-layout-6 .alignfull{max-width:none;} /* <![CDATA[ */ var wordpressData = {"siteUrl":"https:\/\/hpccsystems.com","themeUrl":"https:\/\/hpccsystems.com\/wp-content\/themes\/hpcc"}; /* ]]> */ /* <![CDATA[ */ var wordpressData = {"siteUrl":"https:\/\/hpccsystems.com","themeUrl":"https:\/\/hpccsystems.com\/wp-content\/themes\/hpcc"}; /* ]]> */ /* <![CDATA[ */ var megamenu = {"timeout":"300","interval":"100"}; /* ]]> */ document.addEventListener('facetwp-refresh', function() { if ( 'events_template' == FWP.template ) { if (FWP.facets['time_since'] == 'upcoming') { FWP.facets['event_sort'] = ['date_ascending']; } else { FWP.facets['event_sort'] = ['date_descending']; } } }); (function(\$) { \$(function() { /* After FacetWP reloads, store any updates into a cookie */ \$(document).on('facetwp-loaded', function() { var date = new Date(); var facets = window.location.search; date.setTime(date.getTime()+(24*60*60*1000)); document.cookie = "facetdata="+facets+"; expires="+date.toGMTString()+"; path=/"; }); }); })(jQuery); (function(\$) { \$(function() { /* Cookie handler */ function readCookie(name) { var nameEQ = name + "="; var ca = document.cookie.split(';'); for(var i=0;i < ca.length;i++) { var c = ca[i]; while (c.charAt(0)==' ') c = c.substring(1,c.length); if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length); } return null; } var \$currHref = \$('.breadcrumb_parent').attr('href'); \$('.breadcrumb_parent').attr('href', \$currHref + readCookie('facetdata')); }); })(jQuery); ```