@@ -42,8 +42,7 @@ julia> obj = (a=1, b=2); lens=@optic _.a; val = 100;
42
42
43
43
julia> set(obj, lens, val)
44
44
(a = 100, b = 2)
45
- ```
46
- See also [`modify`](@ref).
45
+ ``` See also [`modify`](@ref).
47
46
"""
48
47
function set end
49
48
@@ -346,15 +345,7 @@ Here `f` has signature `f(::Value, ::State) -> Tuple{NewValue, NewState}`.
346
345
"""
347
346
function modify_stateful end
348
347
349
- @inline function modify_stateful (f, (obj, state), optic:: Properties )
350
- let f= f, obj= obj, state= state
351
- modify_stateful_context ((obj, state), optic) do _, fn, pr, st
352
- f (getfield (pr, known (fn)), st)
353
- end
354
- end
355
- end
356
-
357
- @generated function modify_stateful_context (f, (obj, state1):: T , optic:: Properties ) where T
348
+ @generated function modify_stateful (f:: F , (obj, state):: T , optic:: Properties ) where {T,F}
358
349
_modify_stateful_inner (T)
359
350
end
360
351
@@ -363,29 +354,29 @@ function _modify_stateful_inner(::Type{<:Tuple{O,S}}) where {O,S}
363
354
modifications = []
364
355
vals = Expr (:tuple )
365
356
fns = fieldnames (O)
366
- local st1 = :state0
367
- local st2 = :state1
368
357
for (i, fn) in enumerate (fns)
369
358
v = Symbol (" val$i " )
370
- st1 = Symbol (" state$i " )
371
- st2 = Symbol (" state$(i+ 1 ) " )
372
- ms = if O <: Tuple
373
- :(($ v, $ st2) = f (obj, StaticInt {$(QuoteNode(fn))} (), props, $ st1))
359
+ st = if S <: ContextState
360
+ if O <: Tuple
361
+ :(ContextState (state. vals, obj, StaticInt {$(QuoteNode(fn))} ()))
362
+ else
363
+ :(ContextState (state. vals, obj, StaticSymbol {$(QuoteNode(fn))} ()))
364
+ end
374
365
else
375
- :(( $ v, $ st2) = f (obj, StaticSymbol {$(QuoteNode(fn))} (), props, $ st1))
366
+ :state
376
367
end
368
+ ms = :(($ v, state) = f (getfield (props, $ (QuoteNode (fn))), $ st))
377
369
push! (modifications, ms)
378
370
push! (vals. args, v)
379
371
end
380
372
patch = O <: Tuple ? vals : :(NamedTuple {$fns} ($ vals))
381
- Expr (:block ,
382
- :(props = getproperties (obj)),
383
- modifications... ,
384
- :(patch = $ patch),
385
- :(new_obj = maybesetproperties ($ st2, obj, patch)),
386
- :(new_state = maybesetstate ($ st2, obj, patch)),
387
- :(return (setproperties (obj, patch), $ st2)),
388
- )
373
+ start = :(props = getproperties (obj))
374
+ rest = MacroTools. @q begin
375
+ patch = $ patch
376
+ new_obj = maybesetproperties (state, obj, patch)
377
+ return (new_obj, state)
378
+ end
379
+ Expr (:block , start, modifications... , rest)
389
380
end
390
381
391
382
maybesetproperties (state, obj, patch) = setproperties (obj, patch)
@@ -426,15 +417,10 @@ Query(; select=Any, descend=x -> true, optic=Properties()) = Query(select, desce
426
417
427
418
OpticStyle (:: Type{<:AbstractQuery} ) = SetBased ()
428
419
429
- struct Context{Select,Descend,Optic<: Union{ComposedOptic,Properties} } <: AbstractQuery
430
- select_condition:: Select
431
- descent_condition:: Descend
432
- optic:: Optic
433
- end
434
-
435
-
436
- struct ContextState{V}
420
+ struct ContextState{V,O,FN}
437
421
vals:: V
422
+ obj:: O
423
+ fn:: FN
438
424
end
439
425
struct GetAllState{V}
440
426
vals:: V
@@ -445,57 +431,69 @@ struct SetAllState{C,V,I}
445
431
itr:: I
446
432
end
447
433
448
- pop (x) = first (x), Base. tail (x)
449
- push (x, val) = (x... , val)
450
- push (x:: GetAllState , val) = GetAllState (push (x. vals, val))
434
+ const GetStates = Union{GetAllState,ContextState}
435
+
436
+ @inline pop (x) = first (x), Base. tail (x)
437
+ @inline push (x, val) = (x... , val)
438
+ @inline push (x:: GetAllState , val) = GetAllState (push (x. vals, val))
439
+ @inline push (x:: ContextState , val) = ContextState (push (x. vals, val), nothing , nothing )
451
440
452
441
(q:: Query )(obj) = getall (obj, q)
453
442
454
- function getall (obj, q)
443
+ getall (obj, q) = _getall (obj, q). vals
444
+ function _getall (obj, q:: Q ) where Q<: Query
455
445
initial_state = GetAllState (())
456
- _, final_state = modify_stateful ((obj, initial_state), q) do o, s
457
- new_state = push (s, outer (q. optic, o, s))
458
- o, new_state
446
+ _, final_state = let q= q
447
+ modify_stateful ((obj, initial_state), q) do o, s
448
+ new_state = push (s, outer (q. optic, o, s))
449
+ o, new_state
450
+ end
459
451
end
460
- return final_state. vals
452
+ final_state
461
453
end
462
454
463
- function setall (obj, q, vals)
455
+ function setall (obj, q:: Q , vals) where Q <: Query
464
456
initial_state = SetAllState (Unchanged (), vals, 1 )
465
- final_obj, _ = modify_stateful ((obj, initial_state), q) do o, s
466
- new_output = outer (q. optic, o, s)
467
- new_state = SetAllState (Changed (), s. vals, s. itr + 1 )
468
- new_output, new_state
457
+ final_obj, _ = let obj= obj, q= q, initial_state= initial_state
458
+ modify_stateful ((obj, initial_state), q) do o, s
459
+ new_output = outer (q. optic, o, s)
460
+ new_state = SetAllState (Changed (), s. vals, s. itr + 1 )
461
+ new_output, new_state
462
+ end
469
463
end
470
464
return final_obj
471
465
end
472
466
473
- function context (f, obj, q)
474
- initial_state = GetAllState (())
475
- _, final_state = modify_stateful_context ((obj, initial_state), Properties ()) do o, fn, pr, s
476
- new_state = push (s, f (o, known (fn)))
477
- o, new_state
467
+ function context (f:: F , obj, q:: Q ) where {F,Q<: Query }
468
+ initial_state = ContextState ((), nothing , nothing )
469
+ _, final_state = let f= f
470
+ modify_stateful ((obj, initial_state), q) do o, s
471
+ new_state = push (s, f (s. obj, known (s. fn)))
472
+ o, new_state
473
+ end
478
474
end
479
475
return final_state. vals
480
476
end
481
477
482
478
modify (f, obj, q:: Query ) = setall (obj, q, map (f, getall (obj, q)))
483
479
484
- @inline function modify_stateful (f:: F , (obj, state), q:: Query ) where F
485
- modify_stateful ((obj, state), inner (q. optic)) do o, s
486
- if q. select_condition (o)
487
- f (o, s)
488
- elseif q. descent_condition (o)
489
- ds = descent_state (s)
490
- o, s = modify_stateful (f:: F , (o, ds), q)
491
- o, merge_state (s, ds)
492
- else
493
- o, s
480
+ @inline function modify_stateful (f:: F , (obj, state), q:: Q ) where {F,Q<: Query }
481
+ let f= f, q= q
482
+ modify_stateful ((obj, state), inner (q. optic)) do o, s
483
+ if (q:: Q ). select_condition (o)
484
+ (f:: F )(o, s)
485
+ elseif (q:: Q ). descent_condition (o)
486
+ ds = descent_state (s)
487
+ o, ns = modify_stateful (f:: F , (o, ds), q:: Q )
488
+ o, merge_state (ds, ns)
489
+ else
490
+ o, s
491
+ end
494
492
end
495
493
end
496
494
end
497
495
498
- maybesetproperties (state:: GetAllState , obj, patch) = obj
496
+ maybesetproperties (state:: GetStates , obj, patch) = obj
499
497
maybesetproperties (state:: SetAllState , obj, patch) =
500
498
maybesetproperties (state. change, state, obj, patch)
501
499
maybesetproperties (:: Changed , state:: SetAllState , obj, patch) = setproperties (obj, patch)
@@ -516,8 +514,8 @@ anychanged(::Changed, ::Changed) = Changed()
516
514
inner (optic) = optic
517
515
inner (optic:: ComposedOptic ) = optic. inner
518
516
519
- outer (optic, o, state:: GetAllState ) = o
520
- outer (optic:: ComposedOptic , o, state:: GetAllState ) = optic. outer (o)
517
+ outer (optic, o, state:: GetStates ) = o
518
+ outer (optic:: ComposedOptic , o, state:: GetStates ) = optic. outer (o)
521
519
outer (optic:: ComposedOptic , o, state:: SetAllState ) = set (o, optic. outer, state. vals[state. itr])
522
520
outer (optic, o, state:: SetAllState ) = state. vals[state. itr]
523
521
@@ -532,7 +530,7 @@ function (l::PropertyLens{field})(obj) where {field}
532
530
end
533
531
534
532
@inline function set (obj, l:: PropertyLens{field} , val) where {field}
535
- patch = (;field => val)
533
+ patch = (; field => val)
536
534
setproperties (obj, patch)
537
535
end
538
536
0 commit comments