Monday, 20 February 2012

Basic Libretto Constructs (5 of 5). Packages

The concept of Libretto packages is still under development. In this post I show some draft ideas about them.
Packages can contain the definitions of

  • classes 
  • objects 
  • external methods 
  • external fields 

One Libretto file contains one package. Here is an example of a package:
package org/painting

private fix class Artist(name: String, surname: String)
private fix class Painting(artist: Artist, title: String) 

private object vanGogh extends Artist(“Vincent”, “van Gogh”)
private object Kandinsky extends Artist(“Wassily”, “Kandinsky”)

private fix Artist paintings: Painting {
  vanGogh -> Painting(vanGogh, “The Starry Night”)
  Kandinsky -> Painting(Kandinsky, “On White II”)
}

def getArtists = %paintings.keys()^(surname)

{
  // print artists in alphabetical order on package load
  getArtists.surname.println()
}

def String getPix = getArtists?[surname == this].paintings.title
In this package the classes of artists and paintings are introduced, and the objects for van Gogh and Kandinsky and their two famous paintings are created. All this data is private in the package, and inaccessible from outside. Only two external methods getArtists and getPix are public. The first returns the list of the artists in the alphabetical order, and the second returns the list of paintings of an artist by its name.

The data from the package org/painting can be imported into another package:
package main 
import org/painting/getPix 

“Kandinsky”.getPix  //  “On White II”
“van Gogh”.getPix  //  “The Starry Night”
“Modigliani”.getPix  //  ()
getArtists  //  ERROR: entity getArtists not found
The function getArtists can not be applied, because it is not explicitly imported. Here are examples of various import expressions allowed in Libretto:
import p/* // all members of package p
import p/x // member x of p
import p/x as a // member x of p renamed as a
import p/{x, y} // the members x and y of p
import p1/x, p2/y // ~ import p1.x; import p2.y
Import expressions are allowed at the top of a package, immediately after the package header. They can also be inserted at the beginning of any block. In this case their scope is limited to this block:
package main

def “van Gogh” getPix = “Vase with Twelve Sunflowers”

def String importedGetPix {
  import org.painting.getPix
  getPix  
}

“van Gogh”.getPix  //  “Vase with Twelve Sunflowers”
“van Gogh”.importedGetPix  //  “The Starry Night”
In the last expression the imported method getPix overshadows the package’s own method, and this is why importedGetPix returns the data stored in the package org/painting.

Local imports are especially convenient, when a large package with a big number of imported libraries is developed.

In Libretto a default empty package is predefined. If no package is declared in a file, its code is placed in the empty package. The empty package is convenient for solving small tasks. Besides, it provides an easy start in education. The empty package can not be imported.

No comments:

Post a Comment