The difference is that maud does most of the work compile-time, so `html! { div { "foo" } }` compiles into literal "<div>foo</div>" hardcoded in the program, without allocating intermediate HTMLTagBuilder objects.
I perused the documentation and I can tell a lot of thought went into this. I appreciate the simplicity and applaud all efforts to make Go a serious contender in the full-stack web framework space!
https://docs.goplaid.dev completely embrace low-JS in the Go world, you can write pretty complex UI interactions without write a single line of JavaScript, but only Go code.
It also integrate heavy duty UI component library like Vuetify, So you can use it easily in Go code.
Yup, if your jobs are i/o heavy the cpu time is wasted waiting if you execute them in a strictly sequential way. With your worker pool the cpu intensive part of the jobs is instead being executed concurrently GOMAXPROCS jobs at a time.
You can do a type assertion (not cast - these are different concepts) from interface{} to another type. You cannot do a type assertion on []interface{}; you have to iterate over each element and assert individually.
I agree with GP - the built-in primitives for synchronization, along with sync from the stdlib, are much cleaner once you know how to use them, and they're more idiomatic.
I guess it is a parallel queue, It saves the trouble to worry about goroutines and channels and synchronizations, encapsulated the logic that talked in http://blog.golang.org/pipelines last part. To make use of that pattern easier.
I have quite a few use cases myself:
1. Say there is a article on the web, that contains dozens of images embed in the html. Which I want to crawl the article, and Also the images, and put the image into S3 for faster serve. I can use the fanout concurrency pattern to put upload all the images simultaneously to S3 to make it faster.
2. Say I have 20 mysql node sharded data, I want to fetch top 50 latest created data from all of them, and sort it to and show it to user after.