@@ -42,8 +42,7 @@ julia> obj = (a=1, b=2); lens=@optic _.a; val = 100;
4242
4343julia> set(obj, lens, val)
4444(a = 100, b = 2)
45- ```
46- See also [`modify`](@ref).
45+ ``` See also [`modify`](@ref).
4746"""
4847function set end
4948
@@ -346,15 +345,7 @@ Here `f` has signature `f(::Value, ::State) -> Tuple{NewValue, NewState}`.
346345"""
347346function modify_stateful end
348347
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}
358349 _modify_stateful_inner (T)
359350end
360351
@@ -363,29 +354,29 @@ function _modify_stateful_inner(::Type{<:Tuple{O,S}}) where {O,S}
363354 modifications = []
364355 vals = Expr (:tuple )
365356 fns = fieldnames (O)
366- local st1 = :state0
367- local st2 = :state1
368357 for (i, fn) in enumerate (fns)
369358 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
374365 else
375- :(( $ v, $ st2) = f (obj, StaticSymbol {$(QuoteNode(fn))} (), props, $ st1))
366+ :state
376367 end
368+ ms = :(($ v, state) = f (getfield (props, $ (QuoteNode (fn))), $ st))
377369 push! (modifications, ms)
378370 push! (vals. args, v)
379371 end
380372 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)
389380end
390381
391382maybesetproperties (state, obj, patch) = setproperties (obj, patch)
@@ -426,15 +417,10 @@ Query(; select=Any, descend=x -> true, optic=Properties()) = Query(select, desce
426417
427418OpticStyle (:: Type{<:AbstractQuery} ) = SetBased ()
428419
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}
437421 vals:: V
422+ obj:: O
423+ fn:: FN
438424end
439425struct GetAllState{V}
440426 vals:: V
@@ -445,57 +431,69 @@ struct SetAllState{C,V,I}
445431 itr:: I
446432end
447433
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 )
451440
452441(q:: Query )(obj) = getall (obj, q)
453442
454- function getall (obj, q)
443+ getall (obj, q) = _getall (obj, q). vals
444+ function _getall (obj, q:: Q ) where Q<: Query
455445 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
459451 end
460- return final_state. vals
452+ final_state
461453end
462454
463- function setall (obj, q, vals)
455+ function setall (obj, q:: Q , vals) where Q <: Query
464456 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
469463 end
470464 return final_obj
471465end
472466
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
478474 end
479475 return final_state. vals
480476end
481477
482478modify (f, obj, q:: Query ) = setall (obj, q, map (f, getall (obj, q)))
483479
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
494492 end
495493 end
496494end
497495
498- maybesetproperties (state:: GetAllState , obj, patch) = obj
496+ maybesetproperties (state:: GetStates , obj, patch) = obj
499497maybesetproperties (state:: SetAllState , obj, patch) =
500498 maybesetproperties (state. change, state, obj, patch)
501499maybesetproperties (:: Changed , state:: SetAllState , obj, patch) = setproperties (obj, patch)
@@ -516,8 +514,8 @@ anychanged(::Changed, ::Changed) = Changed()
516514inner (optic) = optic
517515inner (optic:: ComposedOptic ) = optic. inner
518516
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)
521519outer (optic:: ComposedOptic , o, state:: SetAllState ) = set (o, optic. outer, state. vals[state. itr])
522520outer (optic, o, state:: SetAllState ) = state. vals[state. itr]
523521
@@ -532,7 +530,7 @@ function (l::PropertyLens{field})(obj) where {field}
532530end
533531
534532@inline function set (obj, l:: PropertyLens{field} , val) where {field}
535- patch = (;field => val)
533+ patch = (; field => val)
536534 setproperties (obj, patch)
537535end
538536
0 commit comments