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