TE
TechEcho
Home24h TopNewestBestAskShowJobs
GitHubTwitter
Home

TechEcho

A tech news platform built with Next.js, providing global tech news and discussions.

GitHubTwitter

Home

HomeNewestBestAskShowJobs

Resources

HackerNews APIOriginal HackerNewsNext.js

© 2025 TechEcho. All rights reserved.

FP-Go: Functional programming library for Golang

223 pointsby arpanetusalmost 2 years ago

45 comments

physiclesalmost 2 years ago
This is a tour de force, and it accomplishes the goal of enabling FP using the Go syntax and toolchain.<p>But code written using this library is no longer Go: most Go programmers can&#x27;t grok it, and it&#x27;s awkward to call normal Go libraries because there&#x27;s no way to know if that function you&#x27;re calling is pure.<p>If your goal is to &quot;make it easy and fun to write maintainable and testable code in golang&quot; by making pure functions first-class, is there another way to do that without inventing a new language?<p>From experience and inspired by Carmack&#x27;s classic essay on FP in C++[1], I tend toward a functional style: minimize state, treat locals as const, avoid non-const globals, enable parallelism by isolating state. Go makes it easy to write static analysis tools, so go vet could be augmented to, for example, keep track of which functions are pure, and show some yellow underlines at those places where input parameters are mutated.<p>I&#x27;d use something like that.<p>[1] <a href="http:&#x2F;&#x2F;sevangelatos.com&#x2F;john-carmack-on&#x2F;" rel="nofollow noreferrer">http:&#x2F;&#x2F;sevangelatos.com&#x2F;john-carmack-on&#x2F;</a>
评论 #37172741 未加载
评论 #37175528 未加载
评论 #37174456 未加载
评论 #37179364 未加载
moonshxnealmost 2 years ago
Love expression-oriented pseudo-FP (F#, Scala, Rust), but I think this recent trend of trying to shoehorn Haskell-lite features into mainstream imperative languages is, to put it gently, <i>extremely</i> awkward.<p>That said, I actually do remember my first exposure to Golang being a blog post about using monads to avoid incessantly typing `if err != nil`. Very much like that original author, my personal values in software engineering just don&#x27;t align with Go at all, and that should be OK!
评论 #37173795 未加载
评论 #37175613 未加载
mplewisalmost 2 years ago
It&#x27;s an interesting exercise, but this library doesn&#x27;t fit well into the Go ecosystem&#x27;s habit of writing straightforward, imperative, boring, verbose, simple-to-read code. Even as someone who likes FP tools, I won&#x27;t be using this.
fyzixalmost 2 years ago
As much as I love functional programming(f# being my fav). I&#x27;d be pissed if I opened a go file and saw code like what&#x27;s presented here.
rebeccaskinneralmost 2 years ago
I&#x27;m glad to see this idea getting some traction again. I haven&#x27;t used Go much in the last few years, but I started playing around with a similar idea back in 2016 when I was working on a small compiler for a configuration management tool, and later put together a small stand-alone proof of concept library(<a href="https:&#x2F;&#x2F;github.com&#x2F;rebeccaskinner&#x2F;gofpher">https:&#x2F;&#x2F;github.com&#x2F;rebeccaskinner&#x2F;gofpher</a>) as part of a talk (<a href="https:&#x2F;&#x2F;speakerdeck.com&#x2F;rebeccaskinner&#x2F;monadic-error-handling-in-go" rel="nofollow noreferrer">https:&#x2F;&#x2F;speakerdeck.com&#x2F;rebeccaskinner&#x2F;monadic-error-handlin...</a>) I gave in 2017.<p>At the time, I remember finding FP in go surprisingly ergonomic. Implementing the library to support it was a pain since the type system wasn&#x27;t expressive enough to prevent everything from devolving into a pile of untyped reflection, but it was reasonably easy to keep that an implementation detail. On the whole, I felt like go would have lent itself well to the &quot;dash of FP for flavor&quot; style of programming that seems to be gaining popularity these days. Unfortunately, in 2017 at least, the Go community seemed to have very little interest in the idea.<p>I still have a fondness for Go. It always felt nice to use. If the language features have caught up to the point where a robust library like this is feasible, and the communities attitude has shifted, I might take another look at the language.
评论 #37175517 未加载
708145_almost 2 years ago
Seriously, why? The only compelling argument for monadic effect systems I see is in languages with no easy-to-use and lightweight concurrency, and this is where Go shines. I thinks this is cool and all but I don&#x27;t think it can ever be justified with this added complexity in Go. I have worked much with Cats Effect in Scala, which is nice but it adds some serious cognitive overhead.
评论 #37228515 未加载
AYBABTMEalmost 2 years ago
The long README needs some usage examples.
评论 #37171727 未加载
评论 #37171807 未加载
mseepgoodalmost 2 years ago
I always wonder why some people go to a new place and then want to make it like the place they came from.
评论 #37184514 未加载
评论 #37175396 未加载
Spiwuxalmost 2 years ago
Go is not a functional language and its generic type system is very restrictive. Why not use a functional language to begin with?
评论 #37177444 未加载
评论 #37228711 未加载
PhilippGillealmost 2 years ago
A simple alternative is the combination of:<p>- <a href="https:&#x2F;&#x2F;github.com&#x2F;samber&#x2F;lo">https:&#x2F;&#x2F;github.com&#x2F;samber&#x2F;lo</a><p>- <a href="https:&#x2F;&#x2F;github.com&#x2F;samber&#x2F;mo">https:&#x2F;&#x2F;github.com&#x2F;samber&#x2F;mo</a><p>The split is also nice as you can choose to just use the generic convenience functions from lo without the more FP related things from mo.
Eddygandralmost 2 years ago
Step 1: Make a beginner friendly language with minimal syntax and nice concurrency primitives.<p>Step 2: Add “Monoids for the Endomorphism where the `concat` operation is the usual function composition.”<p>Step 3: …<p>Step 4: Profit?
beltsazaralmost 2 years ago
As much as I like the functional paradigm, I don&#x27;t think it will work well on Go due to two simple reasons:<p>1) Go doesn&#x27;t have a concise lambda expression. This makes the functional approach in Go will be more verbose and less readable than the traditional imperative approach.<p>2) Go&#x27;s type inference is not sophisticated enough. Most of the time you will still need to explicitly annotate the types, which, again, makes it more verbose and less readable.
评论 #37228828 未加载
mkl95almost 2 years ago
Sorry for the ad-hominem, but... it looks like something IBM would do in 2023.
I_am_tiberiusalmost 2 years ago
Was just scrolling through the docs. Does anyone feel comfortable with all these generic type annotations? I&#x27;m not expert programmer but this looks overkill to me.
评论 #37171923 未加载
38almost 2 years ago
oh my, its horrible:<p><pre><code> client := H.MakeClient(HTTP.DefaultClient) readSinglePost := H.ReadJson[PostItem](client) readSingleCatFact := H.ReadJson[CatFact](client) data := F.Pipe3( T.MakeTuple2(&quot;https:&#x2F;&#x2F;jsonplaceholder.typicode.com&#x2F;posts&#x2F;1&quot;, &quot;https:&#x2F;&#x2F;catfact.ninja&#x2F;fact&quot;), T.Map2(H.MakeGetRequest, H.MakeGetRequest), R.TraverseTuple2( readSinglePost, readSingleCatFact, ), R.ChainFirstIOK(IO.Logf[T.Tuple2[PostItem, CatFact]](&quot;Log Result: %v&quot;)), ) result := data(context.Background()) fmt.Println(result()) </code></pre> <a href="https:&#x2F;&#x2F;github.com&#x2F;IBM&#x2F;fp-go&#x2F;blob&#x2F;main&#x2F;samples&#x2F;http&#x2F;http_test.go">https:&#x2F;&#x2F;github.com&#x2F;IBM&#x2F;fp-go&#x2F;blob&#x2F;main&#x2F;samples&#x2F;http&#x2F;http_tes...</a>
评论 #37177438 未加载
randomdataalmost 2 years ago
<i>&gt; If your pure function can return an error, then it will have a (T, error) return value in idiomatic go. In functional style the return value is Either[error, T] because function composition is easier with such a return type.</i><p>This seems flawed. In idiomatic Go, T and error are always independently observable. The Either monad implies that they are dependent, which is not true.
评论 #37177822 未加载
评论 #37176406 未加载
kalekoldalmost 2 years ago
How does this make code easier to read and maintain? It all looks like gibberish to me.
评论 #37174088 未加载
loosescrewsalmost 2 years ago
I think a compile to Go approach would have been better. It would allow bypassing most of the warts and still potentially allow interoperability with existing Go code. It would also likely be better received as it would be clear that this is not supposed to be Go.
haspokalmost 2 years ago
The determined Real Programmer can write FORTRAN programs in any language.
shartsalmost 2 years ago
Just use OCaml.
truth_seekeralmost 2 years ago
This library could be only useful if someone trying to build new Programming Language with its own ecosystem with Golang runtime as backend, like for example Scala on JVM. In upcoming versions Go 1.22 they are also improving code inlining support, so that might help.<p>Trying to merge this abstractions and patterns with existing Golang&#x27;s philosophy and community libraries is simply a case of over-engineering.
评论 #37172248 未加载
vips7Lalmost 2 years ago
This is giving me flash backs to RxJava. Don&#x27;t force these things into languages that aren&#x27;t designed around it.
rollulusalmost 2 years ago
I hope this remains just a curiosity that showcases a fascinatingly bad idea, rather than that anyone out there thinks that this is a good idea and start depending on it.<p>Picture jumping into a codebase to quickly fix something, then stumble upon ChainFirstIOK or Eithersize5 because someone went overboard showing off that they remember FP from cs classes.
throw78311almost 2 years ago
The horror on my PM&#x27;s voice when I showed him this library was funny. Instantly blacklisted it in my organization.
satvikpendemalmost 2 years ago
See also, fp-ts and fpdart, both of which I use for my frontend projects. On the backend, I use Rust.
yankputalmost 2 years ago
Adding generics to go was a mistake
评论 #37175449 未加载
评论 #37175104 未加载
评论 #37172886 未加载
sideeffffectalmost 2 years ago
This seems to be missing persistent collections, like immutable Map, Set or Vector&#x2F;Sequence. Those are very important when doing FP in practice.<p>Is there some other established Go library that contains these collections&#x2F;containers?
defanoralmost 2 years ago
AIUI, Go intentionally avoids programming language features considered too advanced by its authors in order to lower the bar (to make it easier for most programmers to pick up, that is) and to keep the code uniform, supposedly to the advantage of companies using it. While hammering unidiomatic approaches into a language virtually always is awkward: there are other libraries and programmers, even if you are fine with the rules you have to follow in order to emulate the desirable features using a library. The combination of those things looks even stranger than they do separately.
zadokshialmost 2 years ago
Why?
评论 #37172231 未加载
atsjiealmost 2 years ago
My eyes hurt.
sohexalmost 2 years ago
The issue they link for semantic-release is hilariously baffling to me. It seems they don&#x27;t support keeping a project at 0.y.z per semver because &quot;you should just dev up to 1.0.0 faster bro&quot; and &quot;we know better than you bro&quot;.
cultofmetatronalmost 2 years ago
cool exercise but its ultimately lubing a square peg to fit in a round hole.<p>A pragmatic systems programming language with garbage collection and good support for functional programming already exits. Its called Ocaml and really deserves more love.
fowliealmost 2 years ago
&gt; very important senior grug say &quot;this too complicated and confuse to me&quot;<p><a href="https:&#x2F;&#x2F;grugbrain.dev" rel="nofollow noreferrer">https:&#x2F;&#x2F;grugbrain.dev</a>
评论 #37176098 未加载
KingOfCodersalmost 2 years ago
I think map() is useful, even if it does not look like Go and rubs a little against the sprit of simplicity of Go. Wish the for loop in Go would return a result, which could accomplish the same but would be a little bit more Go like<p><pre><code> x := for y := range z { return y } &#x2F;&#x2F; unclear return :-( </code></pre> If you want Either, use Haskell.<p>There seems also to be a performance problem with map(). It would work better if Go had Iteration instead of slices, otherwise map() creates a lot of slices. And if map does not return a slice you have an ugly<p><pre><code> y := x.map(...).native </code></pre> everywhere.
评论 #37171409 未加载
keylealmost 2 years ago
Potentially a silly question: isn&#x27;t the garbage collection going to become a problem with this style of Go implementation in large software?
评论 #37171585 未加载
monadicnomadicalmost 2 years ago
It will be entertaining to see usage of this library show up in PRs on CNCF projects that IBM contributes to.
zer8kalmost 2 years ago
I didn&#x27;t look too much at this but are they offering an alternative to the (IMO ugly) error checking pattern Go enforces? It&#x27;s interesting to me shoehorning this into Go in particular. Go is notoriously stringent on <i>how</i> you write code.
评论 #37171578 未加载
gv83almost 2 years ago
&quot;use the right tool for the job&quot; &#x2F;s
jekudealmost 2 years ago
Never thought I’d see these three things together. The library looks extremely well done, although I’d expect some interesting reaction as Go is as imperative as it gets.
nologic01almost 2 years ago
The flying gopher logo is cool though
adamnemecekalmost 2 years ago
These abstractions are not native to go. If you miss them, pick a better language.
评论 #37171385 未加载
评论 #37171595 未加载
Fire-Dragon-DoLalmost 2 years ago
Nope
xvilkaalmost 2 years ago
Why not use Rust instead of you need FP?
评论 #37171720 未加载
sambeaualmost 2 years ago
I’m sorry, but this is just awful.<p><pre><code> func TraverseTuple10[F1 ~func(A1) IOEither[E, T1], F2 ~func(A2) IOEither[E, T2], F3 ~func(A3) IOEither[E, T3], F4 ~func(A4) IOEither[E, T4], F5 ~func(A5) IOEither[E, T5], F6 ~func(A6) IOEither[E, T6], F7 ~func(A7) IOEither[E, T7], F8 ~func(A8) IOEither[E, T8], F9 ~func(A9) IOEither[E, T9], F10 ~func(A10) IOEither[E, T10], E, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10 any](f1 F1, f2 F2, f3 F3, f4 F4, f5 F5, f6 F6, f7 F7, f8 F8, f9 F9, f10 F10) func(T.Tuple10[A1, A2, A3, A4, A5, A6, A7, A8, A9, A10]) IOEither[E, T.Tuple10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10]]</code></pre>
评论 #37171836 未加载
评论 #37173023 未加载
评论 #37175408 未加载
评论 #37171806 未加载
sambeaualmost 2 years ago
I don’t know who to feel more sorry for: the junior programmer who has dutifully taught themselves idiomatic go and explicit error handling being shown a large unreadable codebase full of this nonsense on their first day, or the the poor sods having to tear this nonsense out of a large tangled codebase in three years time.
评论 #37172258 未加载
评论 #37172066 未加载
评论 #37172080 未加载