Jay Taylor's notes
back to listing indexMonoids for Gophers • /r/golang
[web search]- gadgets
- -sports
- -gaming
- -pics
- -worldnews
- -videos
- -AskReddit
- -aww
- -Music
- -funny
- -news
- -movies
- -blog
- -books
- -history
- -food
- -philosophy
- -television
- -Jokes
- -Art
- -DIY
- -space
- -Documentaries
- -Fitness
- -askscience
- -nottheonion
- -todayilearned
- -personalfinance
- -gifs
- -listentothis
- -IAmA
- -announcements
- -TwoXChromosomes
- -creepy
- -nosleep
- -GetMotivated
- -WritingPrompts
- -LifeProTips
- -EarthPorn
- -explainlikeimfive
- -Showerthoughts
- -photoshopbattles
- -mildlyinteresting
- -tifu
- -OldSchoolCool
- -UpliftingNews
- -InternetIsBeautiful
- -science
golang
unsubscribe18,204 readers~64 users here now
Please follow the Go Community Code of Conduct while posting here. In short:
- Treat everyone with respect and kindness.
- Be thoughtful in how you communicate.
- Don’t be destructive or inflammatory.
- If you encounter an issue, please mail conduct@golang.org.
Documentation
Community
- Go Nuts Mailing List
- Go questions in Stackoverflow
- Go in Google+
- #go-nuts in irc.freenode.org
- Resources for new Go programmers
Other Resources
Monoids for Gophers (medium.com)
submitted 1 month ago by groveriffic
[–]natefinch 4 points 1 month ago*
You didn't really explain what the benefit of using this pattern is. You say it can help with parallelization, but didn't actually show an example. I think this would make the article a lot more compelling, because right now you've added complexity without actually doing anything with it.
If you had code creating goroutines and fanning out the work and then consolidating it, then I think it would be more clear why you'd actually do this.
Also, there was no description of why the identity is important. The only time you use the identity is to prove the identity works, which is not really useful in explaining what it's for :)
[–]zoomzoom83 2 points 1 month ago
Because a monoid is associative, you can safely break the problem down into smaller pieces, map an operation on the across multiple threads, and then reduce back to a final result without worrying about order of execution or race conditions.
Identity is the "zero value" (i.e. '0' for addition, "" for string concatenation, [] for list concatenation etc. By asserting that your type has a sane zero value, you're able to ensure there's a starting point for a reduce operation.
Anything meeting this criteria (can be added associatively and has a zero value) is already a monoid, and you likely use then day to day already (ever concatenated a string?) - so this isn't adding any complexity, it's just formalising laws and giving a name to the it.
I think you ought to be careful to draw a distinction between what monoids are and can do, and what monoids can do for Go. Due to the lack of generic types and pretty much any other effective mechanism for doing anything like that efficiently (i.e., reflection can work but will eat your performance for breakfast on most monoid combination operations which tend to be very simple), it's not that useful of a programming abstraction for Go.
While monoids are also in theory good for parallelization, it's also worth pointing out that as they lack any mechanism for generically splitting them into even pieces (because all they have is the identity and combination operator), you generally need something more to actually take advantage of the parallelization possibilities. For instance, for an array, it would be nice to be able to chunk it up, and for a linked list, you basically lose (there is no practical way to parallelize that because, again, most monoidal combinators are quite simple, like "integer addition", and the memory traversal costs completely dominate the problem and can not be parallelized).
This is also sort of an answer to "Why would you ever do this?" that others are asking in this thread. There are other languages that this is useful in. Monoid is an interface, basically, so you can write generic algorithms on that interface. Go's type system is not capable of expressing the interface in question, though.
It's useful to understand and recognize the general concept. There's virtually no way to use this recognition in Go, though.
[–]zoomzoom83 2 points 1 month ago
Go doesn't support generic statically typed monoids. You won't get the nice clean typeclass based approach used in Haskell.
But a monoid does not require either of these things. Strings in Go are monoids, because they just are. Lists are monoids, because they just are. Any custom type with a default value and an associative concatenation function is a monoid, because it just is. Adding two numbers together? Monoid.
You don't need language support to use monoids. You may not be able to write generic code over any monoid in Go, but by obeying the monoid laws in your data types - even if not generic or type checked - you can be confident that your data type will behave in a specific sane way. (And more specifically, so will other developers using your type)
[–]natefinch 1 point 1 month ago
My point was just that the blog post showed examples of how to construct the monoids, but not how to actually make use of the benefits they provide. And there were no examples of actually using the identity anywhere, except a self-referential proof that the identity is the identity.
[–]dasacc22 1 point 1 month ago
there was no description of why the identity is important
Why the identity is important, in general, may be more clear with a different implementation of product
product = func(xs []float64) float64 {
if len(xs) == 0 {
return 1 // identity
}
return xs[0] * product(xs[1:])
}
[–]Fwippy 2 points 1 month ago
I'm not really familiar with a lot of CS terms - this is basically writing the "reduce" part of map/reduce, with the restriction that the reduction function is associative, which enables parallelism, right?
Also, I know I'd be confused as heck to see a function named mappend
in actual code - I'd expect it to be named according to the actual operation performed, like concatenate
or sum
.
[–][deleted] 2 points 1 month ago
Sadly addition with floating point numbers isn't associative:
package main
import "fmt"
func main() {
x, y, z := 0.1, 0.2, 0.3
fmt.Println((x+y)+z == x+(y+z)) // false
}
- apps & tools
- Alien Blue iOS app
- mobile beta
- buttons
Use of this site constitutes acceptance of our User Agreement and Privacy Policy (updated). © 2015 reddit inc. All rights reserved.
REDDIT and the ALIEN Logo are registered trademarks of reddit inc.
π