remains the ugly code of tangled loop, routines and logic i saw and dealt 
with in the past... 

the link is *kind* *of* similar, thanks for sharing it.


Le mercredi 7 août 2019 00:16:34 UTC+2, Robert Engels a écrit :
>
> I was trying to make the point that even in languages where functional is 
> a first class citizen it can be difficult to read/maintain. What was lost 
> there is I should of started with just print the lines that have error - 
> this is trivial to accomplish functionally. Add in what is a trivial change 
> in an imperative style and the functional code gets very ugly. 
>
> Trying to do functional in Go with your proposed syntax would be very 
> difficult to maintain imo. 
>
> You might find this interesting https://github.com/robpike/filter
>
> On Aug 6, 2019, at 4:54 PM, clement auger <clement...@gmail.com 
> <javascript:>> wrote:
>
> each tools does not solve all problems with the same qualities.
>
> why take such example of sequential processing problem to try to solve it 
> using parallel / unordered processing ?
> it is same as shooting both your legs then trying to run a marathon....
>
> the question worth to be asked twice as the go language is not 
> monoparadigm, unlike some pure players.
>
>
> Le mardi 6 août 2019 14:47:15 UTC+2, Robert Engels a écrit :
>>
>> It’s the verbosity of the syntax.  I’ll admit I’m not a fan of functional 
>> programming but the cases where it seems appropriate is where the syntax 
>> and chaining is so simple and straightforward as to be easier to read than 
>> an OO or imperative style.
>>
>> Try using your library to write a purely functional routine to scan lines 
>> of a file and when contains ‘error’ print out the 3 lines before and the 3 
>> lines after. (Thanks Mario Fusco). See if the code is readable by a non 
>> author. 
>>
>> Generics might improve things here but I doubt it (should help type 
>> safety) I think a lambda syntax is required for trivial transformations in 
>> order to make the streams readable. 
>>
>>
>>
>> On Aug 6, 2019, at 3:37 AM, clement auger <clement...@gmail.com> wrote:
>>
>> Hi Robert, 
>>
>> can you kindly elaborate please ? Are you criticizing the resulting api 
>> or its internal writing ? 
>>
>> If you were meaning the lack of comments, tests etc. yes i agree (who 
>> would not?), 
>> but then, I think I can only answer that this is only a matter of 
>> additional work hours.
>>
>> If this is the resulting overall api and its impact on the manners the 
>> programmer will implement solutions, 
>> i m interested to understand better.
>>
>> thank you.
>>
>> PS: to avoid a double post, I take advantage of this answer to thank 
>> others for their encouragements.
>>
>> Le dimanche 4 août 2019 16:56:20 UTC+2, Robert Engels a écrit :
>>>
>>> Would honestly want to maintain somebody else’s code that was written in 
>>> this style?  I wouldn’t. 
>>>
>>> On Aug 4, 2019, at 9:13 AM, clement auger <clement...@gmail.com> wrote:
>>>
>>> You tell me.
>>>
>>>
>>> https://github.com/clementauger/sta
>>>
>>>
>>> sta - stream async 
>>>
>>> Implements responsive data stream pipeline.
>>>
>>> It is a reasearch and concept project not to be used in production.
>>> <https://github.com/clementauger/sta#install>Install go get -u 
>>> github.com/clementauger/sta <https://github.com/clementauger/sta#doc>Doc 
>>> godoc.org/github.com/clementauger/sta 
>>> <https://github.com/clementauger/sta#example>Example 
>>>
>>> most simple.
>>>
>>> sta.Map([]string{"a", "b", "c"}).
>>>     Map(strings.ToUpper).
>>>     Sink(fmt.Println)
>>>
>>> This example demonstrate the implementation of a pipeline that bulks by 
>>> slices of strings of length 4. It declares two parallel workers to change 
>>> the strings cases. It outputs resulting values to stdout.
>>>
>>> sta.Map([]string{"a","b"}).
>>>   Map(sta.Accumulate(make([]string, 4), time.Second)).
>>>   Map(sta.Each(strings.toUpper), sta.Each(strings.toUpper)).
>>>   Sink(fmt.Println)
>>>
>>> <https://github.com/clementauger/sta#rationale>Rationale 
>>> <https://github.com/clementauger/sta#introduction>Introduction 
>>>
>>> sta takes full advantage of the CSP channel based go capabilities to 
>>> provide a simple implementation to compose, implement and refactor 
>>> responsive data stream pipeline.
>>>
>>> A data stream pipeline is said to be responsive when it is able to react 
>>> with its downstream at any point in time in response to a variation of its 
>>> input.
>>>
>>> An implementation is said to be simple to compose, implement and 
>>> refactor a data stream pipeline if its overall result expresses the 
>>> solution with less lines of code, easier understanding, improved rewriting 
>>> capabilities and testing experience.
>>>
>>> Does this attempt reaches its goal ? yes and no...
>>> <https://github.com/clementauger/sta#concepts>Concepts 
>>>
>>> https://blog.golang.org/pipelines
>>> <https://github.com/clementauger/sta#usage>Usage 
>>>
>>> sta exposes a Map function, to create stream instances.
>>>
>>>   s := sta.Map(src)
>>>
>>> src is a value that can take a plurality of data kind.
>>>
>>>   s := sta.Map([]string{"a","b"})
>>>   s = sta.Map([]int{1,2})
>>>   s = sta.Map(make(chan string))
>>>   s = sta.Map(func(output chan string){ output<-"hello world!" })
>>>
>>> sta.Map reads the given input in a separate routine and manages for it 
>>> the required output communication channels.
>>>
>>> The generated output channels are given to downstream transforms of the 
>>> stream.
>>>
>>>   s := sta.Map([]string{"a","b"}).
>>>         Map(func(v string) int { return len(v)})
>>>
>>> stream.Map transforms a given input to an output, in a separate 
>>> routine. It generates the required communication channels and connects them 
>>> with the upstream and downstream automatically.
>>>
>>> To handle fine control of the data flow, stream.Map can handle 
>>> functions that receives the upstream channel. Those functions must return a 
>>> processor function that implements the loop over the upstream channel, and 
>>> an output channel they are writing. The output channel is closed after that 
>>> the processor function has terminated.
>>>
>>>   s := sta.Map([]string{"a","b"}).
>>>         Map(func(input chan string) (func()error, chan int) {
>>>           output := make(chan int)
>>>           processor := func()error {
>>>             for v := range input {
>>>               output<-len(v)
>>>             }
>>>           }
>>>           return processor, output
>>>         })
>>>
>>> To execute the pipeline, the developer must call for the stream.Sink 
>>> function. stream.Sink is realy just like stream.Map except that it 
>>> closes the stream by executing it.
>>>
>>>   err := sta.Map([]string{"a","b"}).
>>>         Map(strings.ToUpper).
>>>         Sink(sta.DevNull)
>>>
>>> stream.Sink writes the destination in a separate routine.
>>>
>>> The given destination value can be of kinds such as slice pointers, 
>>> channels or functions.
>>>
>>>   outSlice := []string{}
>>>   sta.Map([]string{"a","b"}).Sink(&outSlice)
>>>
>>>   outChan := make(chan string)
>>>   sta.Map([]string{"a","b"}).Sink(outChan)
>>>
>>>   outFn := func(v string){}
>>>   sta.Map([]string{"a","b"}).Sink(outFn)
>>>
>>>   outChanFn := func(v chan string) (func() error) { return 
>>> func()error{return nil}}
>>>   sta.Map([]string{"a","b"}).Sink(outChanFn)
>>>
>>> <https://github.com/clementauger/sta#merge>Merge 
>>>
>>> To merge a source, simply add more sources to the stream. Each source 
>>> runs into their own routine.
>>>
>>> It results in a simple merge operation of the output values.
>>>
>>> Sources can have different kind, but they should converge to a 
>>> compatible output type.
>>>
>>>   sta.Map(
>>>     []string{"a","b"},
>>>     []string{"c","d"},
>>>     func(output chan string) {
>>>       output<-"e"
>>>       output<-"f"
>>>     },
>>>     func(output chan string) {
>>>       output<-"e"
>>>       output<-"f"
>>>     },
>>>   )
>>>
>>> <https://github.com/clementauger/sta#parallel>Parallel 
>>>
>>> To implement parallel transforms, simply add more transform to the 
>>> targeted step. Each added transform runs into its own routine.
>>>
>>> The stream will implement automatic distribution of input data and 
>>> inline output data to downstream.
>>>
>>> sta.Map([]string{"a","b"}).
>>>   Map(strings.ToUpper, strings.ToUpper, strings.ToUpper)
>>>
>>> sta.Map([]string{"a","b"}).
>>>   Map(sta.Workers(3, strings.ToUpper)...)
>>>
>>> sta.Map([]string{"a","b"}).
>>>   Map(sta.Workers(3, func() interface{} {
>>>     // per routine scoped values goes here.
>>>     return strings.ToUpper
>>>   })...)
>>>
>>> This applies to stream.Sink aswell.
>>> <https://github.com/clementauger/sta#broadcast>Broadcast 
>>>
>>> SinkBroadcast applies to sinks, it invokes each destination with every 
>>> received value. Each destination runs into its own routine.
>>>
>>> sta.Map([]string{"a","b"}).
>>>   Map(strings.ToUpper).
>>>   Sink(sta.SinkBroadcast(sta.DevNull, sta.DevNull, sta.DevNull))
>>>
>>> <https://github.com/clementauger/sta#bulk-processing>Bulk processing 
>>>
>>> To facilitate bulk processing sta.Accumulate and sta.Each provides 
>>> automatic plumbing.
>>>
>>> sta.Accumulate is a responsive data buffer. It reads upstream and 
>>> accumulates every input into slices. When the slice exceeds a maximum 
>>> length, it is copied downstream. The given duration will ensure that if the 
>>> upstream starves, pending data is being sent to the downstream asap.
>>>
>>> sta.Each is an helper returns function that takes slices in input and 
>>> invoke given function for each value.
>>>
>>> This example demonstrate the implementation of a pipeline that bulks by 
>>> slices of strings of length 4. It declares two parallel workers to change 
>>> the strings cases. It outputs resulting values to stdout.
>>>
>>> sta.Map([]string{"a","b"}).
>>>   Map(sta.Accumulate(make([]string, 4), time.Second)).
>>>   Map(sta.Each(strings.toUpper), sta.Each(strings.toUpper)).
>>>   Sink(fmt.Println)
>>>
>>> To implement an alternative logic to handle the data flow see sta.Tick.
>>> <https://github.com/clementauger/sta#author-notes>Author notes 
>>>
>>> 1- While this defintely provides faster and somehow easier programming 
>>> capabilities of complex algorithm, the lacks of methods signature (it uses 
>>> interface{} everywhere) make it easy to missuse.
>>>
>>> 2 - Because it deals with so many various inputs, unders some 
>>> circumstances, it has to create additionnal communication channels and 
>>> routines that would not be required with human taylor made writing.
>>>
>>> 3 - I like i don t have to care anymore about closing mechanism and 
>>> slices precise management.
>>>
>>> 4 - if you want to improve that attempts, i suggest you to work backward 
>>> from idiomatic patterns to their reflective version. And more generally, 
>>> write a full paper at first.
>>>
>>> 5 - The implementation always tries to converge to a common usable form 
>>> of input to deal with the variety of user-input. sources converges to 
>>> func() 
>>> (processor func() error, out chan <O>), transforms to func(src chan 
>>> <I>) (processor func() error, out chan <O>), and sinks to func(src chan 
>>> <I>) (func() error). This was handy because i developed this lib under 
>>> few hours, but I question this decision for a better implementation.
>>>
>>> 6 - Because this is all aync, all values are returned in random order. 
>>> It should not be too hard to write a buffered accumulator that outputs 
>>> values in orders, however i have not because it requires to box all input 
>>> values so they have their input order attached to it. The added level of 
>>> complexity of the resulting api was judged unsatisfying to be pursued for 
>>> now.
>>>
>>> 7 - its reflective programming thus it is slower, unoptimized etc. you 
>>> know the song.
>>>
>>> 8 - MapBroadcast does not exist because of a lack of interest.
>>>
>>> -- 
>>> 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 golan...@googlegroups.com.
>>> To view this discussion on the web visit 
>>> https://groups.google.com/d/msgid/golang-nuts/cbcc7e32-a9fa-49e3-861f-04b00969ed49%40googlegroups.com
>>>  
>>> <https://groups.google.com/d/msgid/golang-nuts/cbcc7e32-a9fa-49e3-861f-04b00969ed49%40googlegroups.com?utm_medium=email&utm_source=footer>
>>> .
>>>
>>> -- 
>> 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 golan...@googlegroups.com.
>> To view this discussion on the web visit 
>> https://groups.google.com/d/msgid/golang-nuts/7e28b581-f3f8-4792-b170-a4f513c9f02e%40googlegroups.com
>>  
>> <https://groups.google.com/d/msgid/golang-nuts/7e28b581-f3f8-4792-b170-a4f513c9f02e%40googlegroups.com?utm_medium=email&utm_source=footer>
>> .
>>
>> -- 
> 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 golan...@googlegroups.com <javascript:>.
> To view this discussion on the web visit 
> https://groups.google.com/d/msgid/golang-nuts/887a7c1e-9afa-41d6-af7c-f9d76b71928f%40googlegroups.com
>  
> <https://groups.google.com/d/msgid/golang-nuts/887a7c1e-9afa-41d6-af7c-f9d76b71928f%40googlegroups.com?utm_medium=email&utm_source=footer>
> .
>
>

-- 
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 on the web visit 
https://groups.google.com/d/msgid/golang-nuts/a6c3a455-f5b3-4d9c-b731-d849c2198c68%40googlegroups.com.

Reply via email to