Prefix operators on lists, strings and money

The complete source of operators_prefix.ek9, compiled by the EK9 compiler. Shown on operators.html.

#!ek9
defines module site.operators.prefix

  defines program

    Prefix()
      stdout <- Stdout()

      //Initialise values
      anInteger <- 106
      aList <- ["V1", "V2", "V3"] //Remember this is a List not an Array
      aString <- "A-to-Z"
      money <- 350.50#USD

      //Examples of use with a List of Strings
      isEmpty <- aList is empty //isEmpty will have value of false, because the list is not empty
      isNotEmpty <- aList is not empty //isNotEmpty will have value of true, because the list is not empty
      //The above could have been written as
      isNotEmpty := not aList empty //But this reads like Yoda might have said it.

      //Length example
      listLength <- length of aList //listLength will be 3
      //The above could have been written as
      listLength := length aList //The 'of' is just to add readability

      //Convert List to a String and get its length
      listAsString <- $ aList //listAsString will be ["V1", "V2", "V3"]
      lengthOfListAsString <- $ length of $ aList
      //lengthOfListAsString will be 18

      //Accessing specific items in the List safely with getOrDefault
      v1 <- aList.getOrDefault(0, "") //v1 will be "V1"
      v3 <- aList.getOrDefault(2, "") //v3 will be "V3"

      //Access by index with a safe default for out-of-range indices
      maybeAString <- aList.getOrDefault(5, "") //maybeAString will be "" - the default, as there are only 3 items
      //getOrDefault always returns a value: either the element at the index, or the provided default
      //No exceptions, no unset results - safe by design

      //But the pipeline processing is more powerful
      v2 <- cat aList | skip 1 | head 1 | collect as String //v2 will be "V2"
      //Pipeline processing is also safe by avoiding indexing
      nonExistent <- cat aList | skip 4 | head 1 | collect as String
      //nonExistent will be not set as there are only 3 Strings in the list

      //Same syntax can be used with Strings (or your own records/classes if you provide operators)
      isEmpty := aString is empty //isEmpty will have value of false, because the string has a value of "A-to-Z"
      firstChar <- #< aString //firstChar will be 'A'
      lastChar <- #> aString //lastChar will be 'Z'
      //The important point here is the same syntax works with different types like String, Integer, Money
      //Further example shown using Money
      amount <- #< money //amount will be 350.5
      currency <- #> money //currency will be USD

      //The following examples outline hash code and promotion of type
      aFloat <- #^ anInteger //aFloat will be 106.0 (i.e a floating point number)
      //With your own records and classes you can provide your own promotions

      hashCode <- #? anInteger //hashCode will be 106
      hashCode := #? aFloat //hashCode will be 1079672832

      stdout.println(`${isEmpty} ${isNotEmpty} ${listLength} ${listAsString} ${lengthOfListAsString}`)
      stdout.println(`${v1} ${v3} ${maybeAString} ${v2} ${nonExistent?}`)
      stdout.println(`${firstChar} ${lastChar} ${amount} ${currency} ${aFloat} ${hashCode}`)

Download operators_prefix.ek9

Output

false true 3 ["V1", "V2", "V3"] 18
V1 V3  V2 false
A Z 350.5 USD 106.0 1079672832