@@ -551,8 +551,9 @@ _eltype(::AbstractArray{T}) where T = T
551551"""
552552 throttle(f, timeout; leading=true, trailing=false)
553553
554- Return a function that when invoked, will only be triggered at most once
555- during `timeout` seconds.
554+ Return a function that when called, will only call the given `f` at most
555+ once during `timeout` seconds. Any arguments passed to this new function
556+ are passed to `f`.
556557
557558Normally, the throttled function will run as much as it can, without ever
558559going more than once per `wait` duration; but if you'd like to disable the
@@ -561,17 +562,27 @@ the trailing edge, pass `trailing=true`.
561562
562563# Examples
563564```jldoctest
564- julia> a = Flux.throttle(() -> println("Flux"), 2);
565+ julia> noarg = Flux.throttle(() -> println("Flux"), 2);
565566
566- julia> for i = 1:4 # a called in alternate iterations
567- a()
567+ julia> for i in 1:4
568+ noarg() # println called in alternate iterations
568569 sleep(1)
569570 end
570571Flux
571572Flux
573+
574+ julia> onearg = Flux.throttle(i -> println("step = ", i), 1);
575+
576+ julia> for i in 1:10
577+ onearg(i)
578+ sleep(0.3)
579+ end
580+ step = 1
581+ step = 5
582+ step = 9
572583```
573584"""
574- function throttle (f, timeout; leading= true , trailing= false )
585+ function throttle (f, timeout:: Real ; leading= true , trailing= false )
575586 cooldown = true
576587 later = nothing
577588 result = nothing
@@ -603,6 +614,44 @@ function throttle(f, timeout; leading=true, trailing=false)
603614 end
604615end
605616
617+ """
618+ @throttle timeout expr
619+
620+ Evaluates the given expression at most once every `timeout` seconds.
621+
622+ Internally, it uses [`throttle`](@ref Flux.throttle). But instead of
623+ defining a function outside the loop, it lets you place the code inside
624+ the loop.
625+
626+ # Example
627+ ```jldoctest
628+ julia> for i in 1:20
629+ j = 100i
630+ sleep(0.2)
631+ Flux.@throttle 0.9 if iseven(i)
632+ println("i = ", i, ", and j = ", j)
633+ else
634+ println("i = ", i)
635+ end
636+ end
637+ i = 1
638+ i = 6, and j = 600
639+ i = 11
640+ i = 16, and j = 1600
641+ ```
642+ """
643+ macro throttle (timeout:: Real , ex)
644+ expr = macroexpand (__module__, ex)
645+ vars = unique (_allsymbols (expr))
646+ @gensym fast slow
647+ Base. eval (__module__, :($ fast ($ (vars... )) = $ expr))
648+ Base. eval (__module__, :(const $ slow = $ throttle ($ fast, $ timeout)))
649+ :($ slow ($ (vars... ))) |> esc
650+ end
651+
652+ _allsymbols (s:: Symbol ) = [s]
653+ _allsymbols (other) = Symbol[]
654+ _allsymbols (ex:: Expr ) = vcat (_allsymbols .(ex. args)... )
606655
607656"""
608657 modules(m)
@@ -675,7 +724,6 @@ julia> loss() = rand();
675724
676725julia> trigger = Flux.patience(() -> loss() < 1, 3);
677726
678-
679727julia> for i in 1:10
680728 @info "Epoch \$ i"
681729 trigger() && break
0 commit comments