Az E programozási nyelv

Adatabsztrakció

Az E nyelv könyvtárcsomag rendszere az emakerekre épül. Az emaker egy E kódban irt fájl, ".emaker" kiterjesztéssel.

Mikor egy emakert importálunk az alkalmazásunkba, a kód végrehajtása az importáláskor történik, és az eredményt visszakapja az importáló program.

Például:

    def makeQueue() {
        var head := null
        var tail := null
        def makeCarrier(obj) :near {
            var next := null
            def carrier {
                to attach(nextCarrier) {next := nextCarrier}
                to get() {return obj}
                to next() {return next}
            }
        }
        def queue {
            to push(obj) {
                if (head == null) {
                    head := makeCarrier(obj)
                    tail := head
                } else {
                    tail.attach(makeCarrier(obj))
                    tail := tail.next()
                }
            }
            to pop() {
                def current := head
                head := head.next()
                return current.get()
            }
            to iterate(func) {
                var current := head
                var i := 0
                while (current != null) {
                    func(i, current.get())
                    current := current.next()
                    i += 1
                }
            }
        }
        return queue
    }
	

Megjegyzés: Ennek a sornak van egy érdekes karakterisztikája: az iterátor metódusnak helyesen együtt kell működnie az E for ciklusával. Az iterátor meghív egy függvényt, melynek két paraméterre van szüksége: egy kulcsra és egy objektumra. Ebben a sorban a kulcs fel van töltve a sorban lévő értékek indexeivel. Az iterátor végigmegy az adatszerkezeten felhasználva a függvényt minden elemhez.

A fenti kódot makeQueue.emaker fájlnak elnevezve egy példa az importálásra:

   # E syntax 
   
   def times2(a) {return a * 2} 
   def compute(a,b) { 
		def times2(c,d) {return (c + d) * 2} 
		# ....do computation...
		# The following line will throw an exception 
		def answer := times2(a) 
		return answer 
   } 
  

Számos módja van annak, hogy a nyelv tudtára adjuk egy emaker hozzáférhetőségét, hasonlóan ahogy a Java hozzáfér egy osztályhoz.
Betehetjük egy zip vagy egy jar állományban a jvm ext mappájába. Vagy éppen annak egy almappájába.

Az emakerekre jellemző egy fontos biztonsági tulajdonság: jogosultságok nélküli környezetben kelnek életre. Ez még szigorubb, mint a java sandbox.
Azonban ez környezet sokkal rugalmasabb, mint a sandbox, mivel lehetőségünk van a jogosultságok beállítására.

A makeQueue függvény szép példa az emaker működésére, mivel a makeQueue-nak és a soroknak nincs szükségük jogosultságokra. A jogosultságokat megkövetelő emakereknél megállapodás szerint az Authorizer sablont használjuk. Erre egy jó példa, mikor az infoWindowMakernek jogosultságra van szüksége ahhoz, hogy ablakot hozzon létre, ilyenkor belefoglaljuk egy Authorizerbe:

    # E syntax
    #emaker in file lib/ext/com/skyhunter/infoWindowMakerAuthor.emaker
    def infoWindowMakerAuthor(frameMaker) {
        def infoWindowMaker(infoText) {
            def frame := frameMaker("Information")
            def label := (infoText)
            frame.getContentPane().add(label)
            frame.pack()
            frame.show()
            return frame
        }
        return infoWindowMaker
    }
    #.....in using program....
    def makeInfoWindow :=  ()
    def infoBox := makeInfoWindow("First Bit Of Info")
    def detailedInfoBox := makeInfoWindow("Second Bit Of Info")
	

Az aprólékos olvasó bizonyára észrevette, hogy a JFrame-nek szüksége volt jogosultságokra, míg a JLabelnek nem.

Emakerek lehetnek elavult függvények is, ebben az esetben a "Func" elnevezés különbözteti meg őket a Makertől:

    # E syntax
    #emaker in file lib/ext/org/erights/computeSquareFunc.emaker
    def computeSquareFunc(number) {
        return number * number
    }

    #...in using program...
    def computeSquare := 
    def squareOfThree := computeSquare(3)
  

Mivel az emakerek jogosultságok nélkül jönnek létre, ezért mindig lehetőség van az importálásukra. A rossz hír azonban, ha független alkalmazást fejlesztünk, melyben az emakerek megbizhatóak (de legalább annyira megbízhatóak, mint az őket meghívó program), elég kényelmetlen a jogosultságok listáit engedélyezni, csak hogy csomagokra osszuk a programunkat.
Amennyiben egyszerű E kódot írunk, amely saját készítésű emakereket használ, amikben teljes mértékben megbízunk, hogy hozzáférést adjunk a rendszerhez, és nem félünk a kigunyolástol, egész egyszerűen használjuk az unsafe__uriGetter-t, mint a következő példában:

    # E sample
    def powerfulObjectMakerAuthor(unsafe__uriGetter) {
        def file := ("name")
        def swing__uriGetter := 
        def frame := ("powerful object window title")
        def powerfulObjectMaker() {
            #....define the objectMaker and the object it makes...
        }
        return powerfulObjectMaker()
    }
	

Az emakerek létrejöttekor rendelkeznek saját swing__uriGetter-rel, azonban ez a beépített swing csak a kód biztonságos részéhez fér hozzá. Ebben a példában az általunk létrehozott swing felülírja az alapértelmezett swinget, így hozzáfér unsafe kódokhoz is, mint pl a JFrame.