Constants in EK9

The 'Constant' is described in this section, these are declarations of the built in types. They are designed to be very constrained and limited in their use. As with most of EK9; the language has a preconceived idea of how and where each construct can and should be used.

As a developer, if you want to make use of the classes or records as single global variables; you have created as some form of constant; then you must use components and use dependency injection.

While initially you may find this inconvenient, you will find over time this approach reduces software coupling. This is because it reduces the direct linkage to a specific class/record/component.

The idea of constants in EK9 is really limited to very fixed concepts/values or defaults; where only built in types can be used.

Constant Declarations

#!ek9
defines module introduction
    
  defines constant
      
    limitNumberOfRetries <- true    
    updateErrorLog <- false
    
    delimiter <- ':'
      
    author <- "Frank Jones"
      
    maxNumberOfRetries <- 10        
    minTemperatureAllowed <- -2
   
    PI <- 3.142 
   
    bitMask <- 0b01110001
    
    noon <- 12:00    
    justAfterNoon <- 12:00:01
    
    //ISO 8601 i.e P[n]Y[n]M[n]DT[n]H[n]M[n]S    
    maxRenewalDuration <- P3Y2M6DT12H15M6S
        
    twoYears <- P2Y
    twoMonths <- P2M    
    minusTwoDays <- P-2D
    
    twoHours <- PT2H    
    minusTwoHours <- PT-2H
    twoMinutes <- PT2M
    
    timeoutperiod <- 250ms
    
    newMillennium <- 2000-01-01
    
    ek9CreatedDateTime <- 2018-01-31T01:30:00-05:00
    
    maxPayment <- 300000#USD
        
    defaultColour <- #AB6F2B
    
    twoMeters <- 2m
    
    matchSteves <- /[S|s]te(?:ven?|phen)/
    
//EOF

Please look in the section on built in types for details on each of the above types, but as you can see constants can only be literals (this is by design). Constants are designed to be very simple and to be used to hold fixed final constant values.

Use of Constants

If you create another ek9 source file using the same module as the constants; you can just use the constants directly as shown below.

Same Module

#!ek9
defines module introduction
  defines function
  
    areaOfCircle()
      -> diameter as Float
      <- result as Float: PI * (diameter/2)^2
        
    circumferenceOfCircle()
      -> diameter as Float
      <- result as Float: PI * diameter
//EOF

As you can see PI can just be used directly (as you would expect).

Different Module

While not really related directly to constants the examples below give an explanation of how different modules and constructs within those modules can be accessed. But is most likely you will define a range of constants in a module and then use those throughout other modules. There are very significant advantages in doing this to reduce the proliferation and duplication of fixed values. If however you want to use PI from another module you have a couple of options; as shown below.

Option 1
#!ek9
defines module introduction.part
  defines function

    printPI()
      Stdout().println($introduction::PI)  
//EOF

The above shows how to directly reference the constant PI from the 'introduction' module; this is done from within the function 'printPI' in the 'introduction.part' module.

Option 2

If you needed to reference PI several times in your module; having to explicitly reference PI by its module would become tedious. Therefore EK9 has the concept of declaring a reference so that the constant or type can be used directly.

#!ek9
defines module introduction.part
  references
    introduction::PI
    
  defines function

    printPI()
      Stdout().println($PI)  
//EOF


TL;DR

Summary

Constants are very simple in EK9, but in general should not be overlooked. By defining a range of constants in your application you get compiler support because if you 'typo' a constant reference the EK9 compiler will spot it. If however you just use fixed values that should be the same throughout your code but 'typo' those then the compiler cannot spot that.

As always there is a balance to be found here. Some developers might consider the introduction of a constant for a fixed value that is only used once in a simple program 'over engineering'. Others might consider that values such as a 'delimiter' for file processing (as shown in the example in standard types) are a key part of the solution and as such should be 'elevated' and made more prominent.

After all, declaring a constant is not just about reuse, they are also fixed and immutable. But probably more important is the fact they are given a 'name'; hopefully a meaningful name. Designing software is also about making the solution obvious to humans, giving constants meaningful names aids this.

Balance

If you've worked on and used a range of different languages before, or worked in different industries; you may have noticed some tendencies in different developers.

In general they start off simple, but build more and more complex webs of abstractions. This sometimes gets to the point where no one can really 'see the wood for the trees'. Everything becomes a fa├žade or an interface, higher order functions use other higher order functions to create yet more higher order functions (now where was I ?).

While this is not really related directly to constants; constants are one of the starting points for the creation of abstractions. So when a developer looks at some processing - they have to jump over to that constant from where it has been used, you've just caused the developer to take another action. Be sure that is necessary, finding this balance in software development is one of the hardest things to get 'right'.

Conclusion

By using constants in a careful and thoughtful manner you will reduce the number of very simple errors and aid other developers (and yourself) in promoting those significant fixed values to a point in the code where they stand out.

Next Steps

The next section on flow control shows the basic control structures that can be used in EK9.