I just want to highlight a theoretical cliff around  `iter.Push` or `func 
processor(seq iter.Seq[V]) R` contrasted with solutions involving step and 
value callbacks (built-in <https://www.sqlite.org/lang_aggfunc.html> or 
custom <https://www.sqlite.org/c3ref/create_function.html> sqlite aggregate 
functions, also of interest: windowed variants). Aggregate functions 
expressed like the latter, or some of the pretty amazing aggregate 
algorithms, really tend towards stepwise, inductive proof over potentially 
infinite inputs. The stepwise operations have nice algebraic properties, 
(e.g. they are left- and right-associative, or at least the difference 
isn't considered essential, or sequence order is assumed a priori, etc. - 
sometimes the technique is expressing the problem with clever operations). 
Invariants about the result hold at each step (and for windowed aggregate 
functions, at inverse steps).

With this kind of setup, `func processor(R, V) R` or the step / value pair 
`func Step(V)`, `func Value() R` make a ton of sense. However, without this 
kind of setup, the same callbacks can still be used ... I think what really 
changes is that `func Value() R` shouldn't be called until the sequence has 
terminated, and if it's really necessary there's correspondingly less 
clarity about the time and space complexity needed to support `func Value() 
R`.

The concurrency of `iter.Push` is definitely interesting, and `func 
processor(seq iter.Seq[V]) R` is nice, but the combination of the two seems 
less nice (still interesting) relative to other approaches.

On Tuesday, February 25, 2025 at 1:12:06 PM UTC-8 Nuno Cruces wrote:

> Ian, just to note that your message is not at all lost. I just need to 
> look at it carefully in front of a computer, which I won't be able to do 
> today.
>
> But if it works, I agree that looks like a nicer, more general API than 
> mine proposal, which is exactly what I was hoping for, so many thanks!
>
> Regards,
> Nuno
>
> On Tue 25 Feb 2025, 20:24 Ian Lance Taylor, <ia...@golang.org> wrote:
>
>> On Tue, Feb 25, 2025 at 11:52 AM 'Brian Candler' via golang-nuts
>> <golan...@googlegroups.com> wrote:
>> >
>> > You can curry a function?
>> >
>> > On Tuesday, 25 February 2025 at 18:52:09 UTC Jason E. Aten wrote:
>> >>
>> >> Hi Ian, I'm not quite understanding -- is Push meant to take an input 
>> seq too? like
>> >>
>> >> func Push[E any](inputSeq iter.Seq[E]) (seq iter.Seq[E], yield 
>> func(E), stop func())
>> >>                  ^^^^^^^^
>> >> ?
>>
>> I'm suggesting that Push returns, conceptually, two things: an
>> iter.Seq, and a pair of functions. You hand the iter.Seq off to
>> something that expects an iter.Seq. You use the two functions to push
>> values into the iter.Seq. Just as iter.Pull gives you flexibility to
>> fetch values from the sequence however you like, iter.Push gives you
>> flexibility to push values into the sequence however you like, without
>> being tied to the lifespan of a single function. In the original
>> example, the values to push into the sequence would come from a method
>> call.
>>
>> This can all be done already with channels, of course, as shown by the
>> earlier examples.
>>
>> Ian
>>
>>
>> >> On Tuesday, February 25, 2025 at 6:15:40 PM UTC Ian Lance Taylor wrote:
>> >>>
>> >>> On Tue, Feb 25, 2025 at 6:17 AM Nuno Cruces <ncr...@gmail.com> wrote:
>> >>> >
>> >>> > I wanted a solution that doesn't necessarily involve goroutines and 
>> channels, for the same reason that iter.Pull was created: because 
>> goroutines and channels add unnecessary parallelism that has the potential 
>> to introduce data races, when what is needed is concurrency without 
>> parallelism.
>> >>>
>> >>> I think what you're presenting is an argument for
>> >>>
>> >>> package iter
>> >>>
>> >>> // Push returns an iterator, a yield function, and a stop function.
>> >>> // The iterator will return all the values passed to the yield 
>> function.
>> >>> // The iterator will stop when the stop function is called.
>> >>> // This provides a way to flexibly convert a sequence of values into 
>> a Seq.
>> >>> func Push[E any]() (seq iter.Seq[E], yield func(E), stop func())
>> >>>
>> >>> Ian
>> >
>> > --
>> > You received this message because you are subscribed to the Google 
>> Groups "golang-nuts" group.
>> > To unsubscribe from this group and stop receiving emails from it, send 
>> an email to golang-nuts...@googlegroups.com.
>> > To view this discussion visit 
>> https://groups.google.com/d/msgid/golang-nuts/b46f0864-9dfd-4c1c-b34a-dff83decae7fn%40googlegroups.com
>> .
>>
>> -- 
>>
> You received this message because you are subscribed to a topic in the 
>> Google Groups "golang-nuts" group.
>> To unsubscribe from this topic, visit 
>> https://groups.google.com/d/topic/golang-nuts/-Kmtx-sr3G8/unsubscribe.
>> To unsubscribe from this group and all its topics, send an email to 
>> golang-nuts...@googlegroups.com.
>> To view this discussion visit 
>> https://groups.google.com/d/msgid/golang-nuts/CAOyqgcWmTubCfieowziq9BgyqiJddp6sv2g%3Dm4v44FF5P-5aHg%40mail.gmail.com
>> .
>>
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion visit 
https://groups.google.com/d/msgid/golang-nuts/a0f8968a-6381-448f-aebe-0729b31ee38an%40googlegroups.com.

Reply via email to