Skip to content

Stringify Lambdas and Derived Types #466

Open
@pauldhein

Description

@pauldhein

Overview

We need to convert the lambda functions and derived types to be saved as string objects in a generated AIR.json file. The reason for this change is to support the portability of GrFN objects (a lambdas Python file is path-dependent during evaluation/execution). Completing this change will remove the necessity for outputting a _lambdas.py file.

@skdebray and @cl4yton, I am adding you both to this GH issue so you can track the progress.

Task assignments

  • @pratikbhd: convert the lambda function generation to the new stringification style (see examples below)
  • @hlim1: convert the derived type generation to the new stringification style (see the example derived-type below)
  • @pauldhein: Create a secure sandbox that allows us to use eval() and exec() to load lambda functions and derived types without compromising security for future users of GrFN JSON

If anyone has any questions about their individual tasks please add a comment in this GH issue and mention me in the comment.

Lambda function examples

Examples

# Example 1 ==========================================
# Old style
def PETPT__petpt__IF_0__assign__albedo__1(msalb: Real, xhlai: Real):
    return 0.23 - ((0.23 - msalb) * np.exp(-((0.75 * xhlai))))
# New style
"lambda msalb,xhlai:(0.23-((0.23-msalb)*np.exp(-((0.75*xhlai)))))"
# ====================================================

# Example 2 ==========================================
# Old style
def PETPNO__petpno__assign__sbzcon__0():
    return 4.903e-09
# New style
"lambda :4.903e-09"
# ====================================================

# Example 3 ==========================================
# Old style
def PETPT__petpt__IF_0__decision__albedo__2(
    COND_0, albedo_0: Real, albedo_1: Real
):
    return albedo_0 if COND_0 else albedo_1
# New style
"lambda COND_0,albedo_0,albedo_1:albedo_0 if COND_0 else albedo_1"
# ====================================================

# Example 4 ==========================================
# Old style
def some_fake_lambda(x, y, z):
    return x+y, y+z, x+z
# New style
"lambda x,y,z:(x+y,y+z,x+z)"
# ====================================================

Important notes

  • Use minimal spacing when creating these strings as I have shown above
  • Type identifiers are going to be dropped in this representation (extra : are illegal in lambda expressions)
  • Parentheses must be used if we ever end up returning more than a single object from a lambda expression

Derived-type example

In this section I am providing an example of a derived type from Fortran. @hlim1 I am going to show what the current derived-type class code should look like in the current form, and then I will show how to stringify that.

Original Fortran

type soiltype
  integer nlayr
  character (len=10) slno
  character(len=12), dimension(nl) :: texture
  character*50 sldesc, taxon
  logical, dimension(nl) :: coarse
  real ales, dmod
  real, dimension(nl) :: alphavg
end type soiltype

Current python output

@dataclass
class soiltype:
    nlayr: int
    slno: str
    texture: List[str]
    sldesc: str
    taxon: str
    coarse: List[bool]
    ales: float
    dmod: float
    alphavg: List[float]

Stringified form

"@dataclass\nclass soiltype:\n\tnlayr:int\n\tslno:str\n\ttexture:List[str]\n\tsldesc:str\n\ttaxon:str\n\tcoarse:List[bool]\n\tales:float\n\tdmod:float\n\talphavg:List[float]"

Important notes

  • The List annotation is imported from the python types module and it needs to be capitalized
  • No spaces are necessary between the colon and the type annotation
  • The following sequence is needed before each new data member: \n\t
  • A newline character is added after @dataclass and a space is necessary after the class keyword

Metadata

Metadata

Labels

enhancementNew feature or request

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions