Google App Engine (GAE) uses a document centric database model (Big Table). Therefore, before digging into the details of how to integrate it with Babel-17, I decided first to implement lenses for Babel-17. A complete implementation is checked into the repository, and it will come out as part of Babel-17 v3.1 . I am pretty excited about applying it to GAE and the standard library of Babel-17.
So a lens in Babel-17 is a value of type lens_
, and there is a new keyword lens which is used to create lenses from scratch. The old record update syntax has become part of how lenses work. I will update the Babel-17 spec within the next few days, for now to get a sneak preview of how lenses in Babel-17 work, check out this unit test module for lenses:
module lang.unittest.spec.lenses val u = {a = 1, b = {i = 2, j = 3}} val v = u val l = lens x => x.b.i #assert l u == u.(l) == 2 #assert typeof l == (: lens_) u.(l) = 5 #assert u == {a = 1, b = {i = 5, j = 3}} #assert v == {a = 1, b = {i = 2, j = 3}} v.b.j = 42 v.(l) = 6 v.a = v.a + 10 #assert v == {a = 11, b = {i = 6, j = 42}} v.b.j = v.b.i v.b.i ^= 2 v.b.j =^ 2 #assert v.b == { i = 6^2, j = 2^6 } l = lens x => x v.(l) = 77 #assert v == 77 typedef mymap (c : map) = object def lookup k = c k def lookup_putback_ k = x => mymap (c + (k, x)) def get k = if c.containsKey(k) then Some (c k) else None end def get_putback_ k = (case Some x => mymap (c + (k, x)) case None => mymap (c - k)) def this:map = c end val c = { 1 -> 2, 2 -> 3, 3 -> 4, 4 -> 1 } val m = mymap c #assert m.get 3 == Some 4 m.get 3 = Some 10 #assert m == {1 -> 2, 2 -> 3, 3 -> 10, 4 -> 1} m.get 3 = None #assert m == {1 -> 2, 2 -> 3, 4 -> 1} #catch DomainError try: m.lookup 10 m.lookup 10 = 24 #assert m.lookup 10 == 24 val f = lens x => x.b val g = lens x => x.i u.(f*g) = 13 #assert u.b.i == 13 #assert u.(f*g) == 13 val h = lens x => x.(f).(g) #assert u.(h) == 13 u.(h) = 79 #assert u.b.i == 79 u.(f).(g) = 80 #assert u.b.i == 80 #catch ApplyError try: u.(2) #catch DomainError try: begin u.(2) = 18 end #catch 2 try: begin u.(exception 2) = 18 end val fst = lens ((x, y) => x, (x, y) => z => (z, y)) val snd = lens ((x, y) => y, (x, y) => z => (x, z)) val x = (1, 2) x.(fst) = 10 #assert x == (10, 2) x.(snd) = 13 #assert x == (10, 13) val x = 10 x += 2 #assert x == 12 x div= 2 #assert x == 6 x =div 18 #assert x == 3 val x = true x xor= true #assert not x end
Leave a Reply