Skip to content

Commit 22b940d

Browse files
committed
Fixes for lazyseq equality
Signed-off-by: James Hamlin <jfhamlin@gmail.com>
1 parent 69c5d66 commit 22b940d

File tree

5 files changed

+66
-11
lines changed

5 files changed

+66
-11
lines changed

pkg/lang/agent.go

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,11 @@ package lang
33
import "time"
44

55
type (
6-
Agent struct{}
6+
Agent struct {
7+
meta IPersistentMap
8+
9+
watches IPersistentMap
10+
}
711

812
future struct {
913
done chan struct{}
@@ -12,6 +16,8 @@ type (
1216
)
1317

1418
var (
19+
_ ARef = (*Agent)(nil)
20+
1521
_ IBlockingDeref = (*future)(nil)
1622
_ IDeref = (*future)(nil)
1723
_ IPending = (*future)(nil)
@@ -54,6 +60,39 @@ func (f *future) IsRealized() bool {
5460
}
5561
}
5662

63+
////////////////////////////////////////////////////////////////////////////////
64+
// Agent
65+
66+
func (a *Agent) Watches() IPersistentMap {
67+
return a.watches
68+
}
69+
70+
func (a *Agent) AddWatch(key interface{}, fn IFn) IRef {
71+
a.watches = a.watches.Assoc(key, fn).(IPersistentMap)
72+
return a
73+
}
74+
75+
func (a *Agent) RemoveWatch(key interface{}) {
76+
a.watches = a.watches.Without(key)
77+
}
78+
79+
func (a *Agent) notifyWatches(oldVal, newVal interface{}) {
80+
watches := a.watches
81+
if watches == nil || watches.Count() == 0 {
82+
return
83+
}
84+
85+
for seq := watches.Seq(); seq != nil; seq = seq.Next() {
86+
entry := seq.First().(IMapEntry)
87+
key := entry.Key()
88+
fn := entry.Val().(IFn)
89+
// Call watch function with key, ref, old-state, new-state
90+
fn.Invoke(key, a, oldVal, newVal)
91+
}
92+
}
93+
94+
////////////////////////////////////////////////////////////////////////////////
95+
5796
func ShutdownAgents() {
5897
// TODO
5998
}

pkg/lang/equal.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
package lang
22

3-
import "reflect"
3+
import (
4+
"reflect"
5+
)
46

57
func Equiv(a, b any) bool {
68
return Equals(a, b)

pkg/lang/equals_test.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ func TestEquiv(t *testing.T) {
1818
{NewPersistentHashMap(), emptyMap},
1919
{NewPersistentHashMap(1, 2, 3, 4), NewMap(1, 2, 3, 4), NewMap(3, 4, 1, 2)},
2020
{NewMap(1, 2).Seq(), NewVector(NewList(1, 2)), NewList(NewVector(1, 2))},
21+
// empty lazy seqs are equal
22+
{NewLazySeq(func() interface{} { return nil }), NewLazySeq(func() interface{} { return nil })},
2123
}
2224

2325
for _, els := range equivs {

pkg/lang/interfaces.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -347,6 +347,18 @@ type (
347347
// IsCancelled() bool
348348
// IsDone() bool
349349
}
350+
351+
AReference interface {
352+
Meta() IPersistentMap
353+
AlterMeta(f IFn, args ISeq) IPersistentMap
354+
ResetMeta(meta IPersistentMap) IPersistentMap
355+
}
356+
357+
ARef interface {
358+
IRef
359+
360+
AReference
361+
}
350362
)
351363

352364
var (

pkg/lang/lazyseq.go

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -42,23 +42,23 @@ func (s *LazySeq) xxx_sequential() {}
4242

4343
func (s *LazySeq) First() interface{} {
4444
seq := s.Seq()
45-
if seq == nil {
45+
if IsNil(seq) {
4646
return nil
4747
}
4848
return seq.First()
4949
}
5050

5151
func (s *LazySeq) Next() ISeq {
5252
seq := s.Seq()
53-
if seq == nil {
53+
if IsNil(seq) {
5454
return nil
5555
}
5656
return seq.Next()
5757
}
5858

5959
func (s *LazySeq) More() ISeq {
6060
seq := s.Seq()
61-
if seq == nil {
61+
if IsNil(seq) {
6262
return emptyList
6363
}
6464
return seq.More()
@@ -74,24 +74,24 @@ func (s *LazySeq) Empty() IPersistentCollection {
7474

7575
func (s *LazySeq) Equals(o interface{}) bool {
7676
seq := s.Seq()
77-
if s != nil {
77+
if !IsNil(seq) {
7878
return Equals(seq, o)
7979
}
80-
return Seq(o) == nil
80+
return IsNil(Seq(o))
8181
}
8282

8383
func (s *LazySeq) Equiv(o interface{}) bool {
8484
seq := s.Seq()
85-
if s != nil {
85+
if !IsNil(seq) {
8686
return Equiv(seq, o)
8787
}
88-
return Seq(o) == nil
88+
return IsNil(Seq(o))
8989
}
9090

9191
func (s *LazySeq) IsRealized() bool {
9292
s.realizeMtx.RLock()
9393
defer s.realizeMtx.RUnlock()
94-
return s.fn == nil
94+
return IsNil(s.fn)
9595
}
9696

9797
func (s *LazySeq) realize() interface{} {
@@ -114,7 +114,7 @@ func (s *LazySeq) Seq() ISeq {
114114

115115
s.realize()
116116

117-
if s.sv == nil {
117+
if IsNil(s.sv) {
118118
return s.seq
119119
}
120120
ls := s.sv

0 commit comments

Comments
 (0)