13 ms·
FP-Go: Functional programming library for Golang
- I_am_tiberius 3y agoWas just scrolling through the docs. Does anyone feel comfortable with all these generic type annotations? I'm not expert programmer but this looks overkill to me.
- Spiwux 3y agoWhy, what's wrong with func TraverseParTuple10[F1 ~func(A1) ReaderIOEither[T1], F2 ~func(A2) ReaderIOEither[T2], F3 ~func(A3) ReaderIOEither[T3], F4 ~func(A4) ReaderIOEither[T4], F5 ~func(A5) ReaderIOEither[T5], F6 ~func(A6) ReaderIOEither[T6], F7 ~func(A7) ReaderIOEither[T7], F8 ~func(A8) ReaderIOEither[T8], F9 ~func(A9) ReaderIOEither[T9], F10 ~func(A10) ReaderIOEither[T10], A1, T1, A2, T2, A3, T3, A4, T4, A5, T5, A6, T6, A7, T7, A8, T8, A9, T9, A10, 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]) ReaderIOEither[T.Tuple10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10]] (https://pkg.go.dev/github.com/IBM/fp-go/context/readerioeither#TraverseParTuple10 https://pkg.go.dev/github.com/IBM/fp-go/context/readerioeith...)
- mseepgood 3y agoWow, this looks like Rust
- sambeau 3y agoExactly, I can’t wait to force this on my junior programmers and make them look stupid. cracks knuckles over keyboard
- deleted 3y ago[deleted]
- wheelerof4te 3y agoBlasphemy. Kill it with fire but make sure to pour some Holy water first.
- cleue 3y agoThis is also one of my favorites, but it can get even more verbose. However this is how the go type system is designed to work with covariance. Without the `~` operator these functions could only be used for a much smaller range of inputs. But this complexity is an implementation detail of the library, you do not have to understand it as a user of these functions. From my perspective it is a valid approach to move complexity from use application layer into the library layer, so it can be hidden there and tested once.
- zer8k 3y agoI didn't look too much at this but are they offering an alternative to the (IMO ugly) error checking pattern Go enforces? It's interesting to me shoehorning this into Go in particular. Go is notoriously stringent on how you write code.
- kadoban 3y agoThey have Either, so kind of. It looks serviceable, if a little messy without language support for safely destructuring its cases.
- bPspGiJT8Y 3y agoSafe destructuring could be achieved with Church encoding.
- rebeccaskinner 3y agoI'm glad to see this idea getting some traction again. I haven'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(https://github.com/rebeccaskinner/gofpher https://github.com/rebeccaskinner/gofpher) as part of a talk (https://speakerdeck.com/rebeccaskinner/monadic-error-handling-in-go https://speakerdeck.com/rebeccaskinner/monadic-error-handlin...) I gave in 2017. 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'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 "dash of FP for flavor" 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. 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.
- metadat 3y agoWould be a lot more interesting with some usage examples or tests.
- cleue 3y agoThere exist at least some examples as part of the go docs, e.g. here https://pkg.go.dev/github.com/IBM/fp-go/either#pkg-examples https://pkg.go.dev/github.com/IBM/fp-go/either#pkg-examples or https://pkg.go.dev/github.com/IBM/fp-go@v1.0.19/array#pkg-examples https://pkg.go.dev/github.com/IBM/fp-go@v1.0.19/array#pkg-ex... but there certainly could be more. Are there any examples you'd be interested in in particular?
- adamnemecek 3y agoThese abstractions are not native to go. If you miss them, pick a better language.
- stevefan1999 3y agoJust like FPP is incompatible with C, I agree. And if you want a real taste of FPP go with either Haskell, OCaml or even the good ol' LISP
- adamnemecek 3y agoOr Rust.
- kadoban 3y agoMy contention that FP has no meaning gains another point of evidence.
- stevefan1999 3y agoAs a Rust guy, I disagree. For one, Rust does not have lazy evaluation, just like C which is why I raised the point C is incompatible with FPP. Lazy evaluation in C (and Rust) can be emulated by function pointers (and closures), but it is not easy to use
- deleted 3y ago[deleted]
- KingOfCoders 3y agoI 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 x := for y := range z { return y } // unclear return :-( If you want Either, use Haskell. 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 y := x.map(...).native everywhere.
- charlieflowers 3y ago`Either` works pretty well in Go. I implemented it and it felt reasonably close to Rust/Haskell (without `try!` of course).
- 12345hn6789 3y agoEither is nearly in the language anyways. The vast majority of pragmatic go functions will return [Result, Error] and or just [Error]. We are only missing support to treat this as a monad.
- corethree 3y agoYou don't need support. Monad composition isn't a special feature it can be implemented directly. Not an expert in Go but I think you can do this: func compose[A any, B any, C any](a func(A) (B, error), b func(B) (C, error)) func(A) (C, error) { return func(aInp A) (C, error) { res, err := a(aInp) if err == nil { return b(res) } else { return *new(C), err } } } The above is equivalent to haskells fish operator >=> The bind operator (>>=) can be implimented in terms of composition: func bind[A any, B any, C any](a func(A) (B, error), b func(B) (C, error), aInput A) (C, error) { return compose[A, B, C](a, b)(aInput) }
- kadoban 3y agoEither as a pattern is _used_ everywhere, but the standard library in go doesn't have one (people just use a tuple), so it's _always_ encoded wrong. It's very annoying.
- jekude 3y agoNever 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.
- AYBABTME 3y agoThe long README needs some usage examples.
- lastangryman 3y ago100%. That's the first thing I want to see after a brief intro.
- dveeden2 3y agoTrue, however the README does link to this: https://github.com/IBM/fp-go/tree/main/samples https://github.com/IBM/fp-go/tree/main/samples
- mc10 3y agodata := F.Pipe3( T.MakeTuple2("https://jsonplaceholder.typicode.com/posts/1", "https://catfact.ninja/fact"), T.Map2(H.MakeGetRequest, H.MakeGetRequest), R.TraverseTuple2( readSinglePost, readSingleCatFact, ), R.ChainFirstIOK(IO.Logf[T.Tuple2[PostItem, CatFact]]("Log Result: %v")), ) This looks like a pain to modify if you're not intimately familiar with the fp-go library and are just trying to insert a debug statement. Also, the passing two values in parallel via a chain of functions seems really brittle.
- sambeau 3y agoAnd, after all that, they don’t even handle the IO errors.
- vjerancrnjak 3y agoIt is very probable that data is an Either[Error, Result]. So you are forced to handle the error. You could also probably add a mapLeft and deal with an error at every step of computation. Given the way fp-ts work, this library should be very type safe. But of course, all of this looks much prettier and less verbose in haskell
- cleue 3y ago
- keyle 3y agoPotentially a silly question: isn't the garbage collection going to become a problem with this style of Go implementation in large software?
- nrabulinski 3y agoWhy would it be a problem? A lot of functional languages are garbage collected and it hasn’t been a problem for them
- kerkeslager 3y agoFunctional languages typically have much more sophisticated garbage collectors than Go's.
- fyzix 3y agoAs much as I love functional programming(f# being my fav). I'd be pissed if I opened a go file and saw code like what's presented here.
- deleted 3y ago[deleted]
- defanor 3y agoAIUI, 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.
- zadokshi 3y agoWhy?
- sambeau 3y agoI can think of two good reasons: 1. To look clever. 2. To make junior programmers look stupid.
- xvilka 3y agoWhy not use Rust instead of you need FP?
- jamesrom 3y agoWhy not use a functional programming language if you need FP?
- mkl95 3y agoSorry for the ad-hominem, but... it looks like something IBM would do in 2023.
- haspok 3y agoThe determined Real Programmer can write FORTRAN programs in any language.
- moonshxne 3y agoLove 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, extremely awkward. 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't align with Go at all, and that should be OK!
- osclarto 3y agototally agree, for me golang is a strongly imperative language and that's ok. I'm willing to be proved wrong, but I would imagine if you want to do functional programming it's going to be a lot easier to just use a different language.
- dingnuts 3y agoBig time agreement here as well. I'm biased because I've built a career on Go at this point but the pragmatism and ability to just get things done in Go without faffing about with unnecessary abstractions is I think one of the strongest practical demonstrations of how incredible an imperative language can be, and for me personally at least, no FP language will ever beat the productivity that I can achieve with Go, especially because at least in my problem domain the real world problems always have enough corner cases that FP wouldn't even be useful. In Go I just systematically eliminate and handle each possible step and state, in a straightforward way, directly deal with the business logic, and then it's done and it works predictably and efficiently for years. Interfaces really are a sufficient form of polymorphism, too.
- MSFT_Edging 3y agoI've always had a hard time breaking into FP paradigms. The basic tutorials feel a bit like math proofs and it's hard to connect the ideas into things I'm actually doing. As it turned out, I accidentally started learning some functional-lite paradigms in Python. I learned that I actually do like some of these paradigms, and think through them already, I just couldn't connect my internal understanding with the language of FP. I started learning Rust recently, as it's an exciting systems language with some hype. There, you see even more functional bits which is just a pleasure to use. I'm not in an area where purely functional would make sense but having the quality of life that certain paradigms brings is nice. I'm still very much a novice in FP techniques, but the ability to try aspects as I go is helpful in learning.
- physicles 3y agoThis is a tour de force, and it accomplishes the goal of enabling FP using the Go syntax and toolchain. But code written using this library is no longer Go: most Go programmers can't grok it, and it's awkward to call normal Go libraries because there's no way to know if that function you're calling is pure. If your goal is to "make it easy and fun to write maintainable and testable code in golang" by making pure functions first-class, is there another way to do that without inventing a new language? From experience and inspired by Carmack'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. I'd use something like that. [1] http://sevangelatos.com/john-carmack-on/ http://sevangelatos.com/john-carmack-on/
- Cthulhu_ 3y agoIt's syntactically Go but it adds a functional DSL on top of it - that is, you can't just know Go, you need to learn the ins and outs of this library too (plus functional programming) before you can use it. I cannot recommend this unless you really have to for whatever reason. Besides readability, another factor to consider is performance; Go is not optimized for functional programming structures. It doesn't have things like tail call optimization. There's better languages than Go if you want to / have to do functional programming.
- stouset 3y ago> you can't just know Go, you need to learn the ins and outs of this library too… before you can use it. That is… literally just how libraries are. You need to understand the underlying language and the semantics and details of the library API.
- goeiedaggoeie 3y agoFeels like the spirit of Scala reborn.
- cle 3y ago
- sambeau 3y agoI’m sorry, but this is just awful. 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]]
- deleted 3y ago[deleted]
- jpk 3y agoBig Scala vibes here, see also [1]. 1: https://github.com/scala/scala/blob/v2.13.11/src/library/scala/Function22.scala#L21 https://github.com/scala/scala/blob/v2.13.11/src/library/sca...
- eweise 3y agoThat looks pretty straightforward actually.
- jpk 3y agoUltimately it is, but I guess my point is that having goofy signatures like these down in the bowels of a library (like FP-Go, or Scala's stdlib) might just be necessary goofiness because FP is FP. (Not to knock FP. Engineering is about tradeoffs.)
- eweise 3y agoFrom the Go standard library "func CompareFunc[S1 ~[]E1, S2 ~[]E2, E1, E2 any](s1 S1, s2 S2, cmp func(E1, E2) int) int { " Looks like Scala
- alex_lav 3y ago
- atsjie 3y agoMy eyes hurt.
- Spiwux 3y agoGo is not a functional language and its generic type system is very restrictive. Why not use a functional language to begin with?
- eigenhombre 3y agoNot picking sides here (though disclosure: I use and like FP techniques/tools/languages/libraries). Go provides a set of nice features (fast startup, easy cross-platform building, great tooling, good package management) that can be hard to come by with other languages. It is not unreasonable to want to have your cake (all of the above features) and eat it too (occasionally use functional idioms in addition to the usual imperative ones). For this reason I try to keep abreast of the various FP libraries in Go, though I have yet to use one in anger.
- cleue 3y agoBecause in some cases the aspect whether or not the language is functional is not the only decision criteria for the choice of language. If it was, I would absolutely recommend to consider a language than go. But if go is selected because of different criteria (i.e. interoperability with an existing eco-system, cross compilation support, FIPS compliance, ...) then this library can help to apply fp paradigms in you go code. Hopefully to make it readable and testable.
- sharts 3y agoJust use OCaml.
- mplewis 3y agoIt's an interesting exercise, but this library doesn't fit well into the Go ecosystem's habit of writing straightforward, imperative, boring, verbose, simple-to-read code. Even as someone who likes FP tools, I won't be using this.
- truth_seeker 3y agoThis 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. Trying to merge this abstractions and patterns with existing Golang's philosophy and community libraries is simply a case of over-engineering.
- monadicnomadic 3y agoIBM is a leader in (over)engineering.
- sambeau 3y agoI 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.
- xyzzy123 3y agoFortunately it's all paid for by investors.
- deleted 3y ago[deleted]
- deleted 3y ago[deleted]
- loosescrews 3y agoI 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.
- satvikpendem 3y agoSee also, fp-ts and fpdart, both of which I use for my frontend projects. On the backend, I use Rust.
- 708145_ 3y agoSeriously, 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'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.
- cleue 3y agoOne of the design aspects is to make a distinction between functions with and without side effects (pure). In a way to tell these apart by looking at the function signature without having to read the function body. The library uses a function signature without an input but with an output for this purpose. Aside from the trivial case of a constant function, such a signature can only mean that the function has side effects. type IO[A any] func() A If you consider this a valid approach, then the set of monadic helper functions make it easier to compose these effectful functions with pure functions. This article https://betterprogramming.pub/investigating-the-i-o-monad-in-go-3c0fabbb4b3d https://betterprogramming.pub/investigating-the-i-o-monad-in... contains some more detailed reasoning.
- PhilippGille 3y agoA simple alternative is the combination of: - https://github.com/samber/lo https://github.com/samber/lo - https://github.com/samber/mo https://github.com/samber/mo 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.
- deleted 3y ago[deleted]
- monadicnomadic 3y agoIt will be entertaining to see usage of this library show up in PRs on CNCF projects that IBM contributes to.
- mseepgood 3y agoI always wonder why some people go to a new place and then want to make it like the place they came from.
- deleted 3y ago[deleted]
- deleted 3y ago[deleted]
- sohex 3y agoThe issue they link for semantic-release is hilariously baffling to me. It seems they don't support keeping a project at 0.y.z per semver because "you should just dev up to 1.0.0 faster bro" and "we know better than you bro".
- nologic01 3y agoThe flying gopher logo is cool though
- rollulus 3y agoI 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. 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.
- kalekold 3y agoHow does this make code easier to read and maintain? It all looks like gibberish to me.
- kokizzu5 3y agoi agree, the horror of obfuscation '__') if it have to be in FP style, this one is better https://github.com/koss-null/FuncFrog https://github.com/koss-null/FuncFrog still prefer non-FP part tho
- yankput 3y agoAdding generics to go was a mistake
- gonzo41 3y agoConsidering what was done with Go before generics it's hard to disagree.
- cy_hauser 3y agoI've ended up using at least a half dozen generic helpers in every application I've written since they were added. They've made my coding easier, more concise, and help with testing. Adding generics to Go was well-founded.
- assbuttbuttass 3y agoCan you share some examples? I personally haven't found any excuses to use generics yet, so I'm curious where other people are finding them useful
- shinies 3y agoHere is an example in the standard library: https://pkg.go.dev/slices https://pkg.go.dev/slices
- assbuttbuttass 3y agoI've used the slices package and I agree it's useful. I was wondering more about generics use in application code
- shinies 3y agoBefore the slices package you had to write those functions for all your types, it's much better now! I also like using generics for API request/response code, ex: https://go.dev/play/p/OWf9eFmg1qF https://go.dev/play/p/OWf9eFmg1qF With generics you don't need to return any/interface{} / type assert at runtime
- Eddygandr 3y agoStep 1: Make a beginner friendly language with minimal syntax and nice concurrency primitives. Step 2: Add “Monoids for the Endomorphism where the `concat` operation is the usual function composition.” Step 3: … Step 4: Profit?
- 38 3y agooh my, its horrible: client := H.MakeClient(HTTP.DefaultClient) readSinglePost := H.ReadJson[PostItem](client) readSingleCatFact := H.ReadJson[CatFact](client) data := F.Pipe3( T.MakeTuple2("https://jsonplaceholder.typicode.com/posts/1", "https://catfact.ninja/fact"), T.Map2(H.MakeGetRequest, H.MakeGetRequest), R.TraverseTuple2( readSinglePost, readSingleCatFact, ), R.ChainFirstIOK(IO.Logf[T.Tuple2[PostItem, CatFact]]("Log Result: %v")), ) result := data(context.Background()) fmt.Println(result()) https://github.com/IBM/fp-go/blob/main/samples/http/http_test.go https://github.com/IBM/fp-go/blob/main/samples/http/http_tes...
- lenkite 3y agoActually, this sample is pretty easily followed and readable to anyone familiar with iterators, tuples, filter, map and transduction. Sure the stuff like Pipe3/Map2 is irritating because Go doesn't have function overloading. Now, try and do the equivalent in "normal" Go code - it will be 3x-5x the lines of code. (Probably more)
- 38 3y agoit has no error handling. also look at the API, what a joke: https://godocs.io/github.com/IBM/fp-go/function https://godocs.io/github.com/IBM/fp-go/function and check out the "constants": https://godocs.io/github.com/IBM/fp-go/function#pkg-variables https://godocs.io/github.com/IBM/fp-go/function#pkg-variable...
- lenkite 3y agoIt actually does have error handling. It uses a Result type type ReaderIOEither[A any] RE.ReaderIOEither[context.Context, error, A] In fact the test code you linked actually even does a check on the result: assert.Equal(t, E.Of[error](count), result()) In order to avoid all those excessive functions and 'silly' constants, Go needs to support const and variadic generics like C++ does. Then the API would become quite clean. I am not supporting the use of this library in prod code used in a large team - but its OK for small tools where one needs to iterate quickly. Folks familiar with FP constructs (esp users of fp-ts) would follow this code almost immediately. Basically the dirtiness and pain (most of it) has been encapsulated into the library.
- beltsazar 3y agoAs much as I like the functional paradigm, I don't think it will work well on Go due to two simple reasons: 1) Go doesn'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. 2) Go'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.
- cleue 3y ago1) I would argue that with fp style you might want to structure your code into small, pure functions, anyway, for testability reasons. Also many functions from the go library are already pure functions with one input and one output, so they can be used right way, e.g. `Atoi` from `strcov` or `ToUpper` from `strings`. Also go has the nice feature that you can pass methods on structs (member functions) from their instance as functions (the instance reference is bound in a closure). So lambda functions are not really needed that much 2) I absolutely agree, type inference could be better. However this has improved over time and go1.21 has also made good progress. I would expect that type inference will continue to improve in the future. This library tries to easy the pain of having to specify types redundantly by carefully choosing the order of type parameters. Those parameters that can be inferred (e.g. because they are part of the immediate function argument) come last, whereas the parameters that cannot be inferred come first, so you only have to specify those. This compromizes on a consistent type ordering, preferring useability over (internal) consistency. Examples are `Left` and `Right` of the `either` package. The order of type parameters is reversed between the two to avoid excessibe typing.
- throw78311 3y agoThe horror on my PM's voice when I showed him this library was funny. Instantly blacklisted it in my organization.
- fowlie 3y ago> very important senior grug say "this too complicated and confuse to me" https://grugbrain.dev https://grugbrain.dev
- pphysch 3y agoIBM big brain use dark FP magic for make job security
- gv83 3y ago"use the right tool for the job" /s
- randomdata 3y ago> 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. 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.
- deleted 3y ago[deleted]
- garfij 3y agoI spent about 6 years writing Go at $dayjob, and while what you're saying is technically true, idiomatically you also generally wanted to avoid scenarios where you would _want_ to observe them independently. The standard behavior is is if `err != nil`, the result should be ignored.
- vlowther 3y agoAnything that implements or consumes `io.Reader` or `io.Writer` would dispute that.
- awused 3y agoYeah, there are counterexamples, but the only way to know is to read the comments or source code of the function you're calling. (T, err) doesn't convey any useful information and, in the overwhelming majority of cases, err != nil means T is a meaningless default value that should be ignored or a null pointer. By and large I think the stuff in this repo is too much and doesn't fit Go. I don't particularly want Go to pretend to be functional, but Either and Option at least would be nice to have in the stdlib and help prevent this exact issue where there are rare exceptions to normal practices. I don't see them getting widespread use without being part of the stdlib though. If Either/Option were common in Go but io.Reader was one of the few APIs returning (T, error), that would convey a lot more information.
- 3y ago
- cultofmetatron 3y agocool exercise but its ultimately lubing a square peg to fit in a round hole. A pragmatic systems programming language with garbage collection and good support for functional programming already exits. Its called Ocaml and really deserves more love.
- vips7L 3y agoThis is giving me flash backs to RxJava. Don't force these things into languages that aren't designed around it.
- sideeffffect 3y agoThis seems to be missing persistent collections, like immutable Map, Set or Vector/Sequence. Those are very important when doing FP in practice. Is there some other established Go library that contains these collections/containers?
- Fire-Dragon-DoL 3y agoNope