semi random, but for another example of someone enjoying the hell out of go for personal projects, take a look at:
that guy's amazing, one of my programming heroes.
semi random, but for another example of someone enjoying the hell out of go for personal projects, take a look at:
that guy's amazing, one of my programming heroes.
Go was the first compiled language I learned coming from Python and scientific computing. And I felt the same way and was so delighted to write fast native multithreaded code without ceremony.
But then I learned some other languages that have elegant and powerful type systems (namely, Rust, OCaml and Haskell) and now I'm somewhat disgusted at my former self. Go could have been great, but it ain't. It's a blub language if ever there was one.
I know my opinion on these things doesn't matter. But I feel resentful of Go, I feel like I was duped.
GOPATH took me a few hours to figure out at the time, but that was because the documentation was incredibly sparse at the time (this was before Go hit 1.0). Now it's just:
mkdir -p ~/go/src/hello
echo "package main" >> ~/go/src/hello/main.go"
echo "func main() { println("Hello world") }" >> ~/go/src/hello/main.go"
go build hello
./hello ///usr/bin/env go run "$0" "$@"; exit $?
package main
import "fmt"
func main() {
fmt.Println("Hello World")
}but i wouldn't feel "duped".
those are much more ambitious languages than go; they're in a different space. go is simple, easy to learn, small...
(a lot what's nice about go is beyond the language too -- the whole ecosystem is just very pleasant to work with.)
1. Documentation. It's lacking or spread thinly across the Internet, and it's mostly low quality in my experience. 2. Windows support was dodgy last I checked. 3. Build tooling is byzantine and fragmented 4. Standard libraries - The official standard library is limited and frustrating - Other standard libraries are limited and frustrating - There is more than one standard library 5. Devs seem more interested in adding language features than making it useful to people who want to write real applications
> At least Ocaml has such a great package manager
As long as I'm consuming packages, it's great. Making packages is a nuisance. Go's dependency and distribution tooling isn't pretty, but at least it gets out of my way--`dep` does what I need it to do and I haven't had any problems. Still, both Go and OCaml's package management story is a far cry from Rust's Cargo.
> better compiler
What does this mean? Certainly not "faster" or "produces faster code" or "works better across platforms".
> repl
Granted, but I program in Python professionally and rarely touch the repl. I use it more often as a command line calculator than anything. If I were doing data science, I might feel differently, but for application development I don't miss it.
> allocation profiler
Go has had an (excellent) allocation profiler built into the toolchain for years. Besides, it's much easier to intuit about (and control) allocations in Go than it is in OCaml.
If I could borrow anything into Go from OCaml, it would be generics and sum types. The rest (syntax, runtime, tooling, libraries, etc) I'll leave be.
Yes ocaml compiler is light years ahead Go’s one in terms of optimizations and code analysis (and even correctness [1]). It is still not as great as haskell’s one, but very good, especially with new lambda middle end. Go compiler is straightforward as hell and can’t do much inlining or optimizations that ocaml can.
Windows support was always tier 1 in compiler. Jbuilder also supports windows and even cross-compilation with windows as a target. Opam now compiles on Windows was too.
As for libraries opam now have thousands of these and ocaml libraries’ quality is often much higher than the quality of libs of this other imperative language due to quality of language.
>go standard library
lol no math for ints, no data structures beyond map, but crappy http and Json serialization.
[1] https://blog.janestreet.com/proofs-and-refutations-using-z3
This reads like you're trying to pass a stylistic objection off as a functional objection. If that's not the case, feel free to add substance.
> And how is making packages is a problem? You jast add opam file and that is all. You can do versioning, pin any opam or git repo, or even some fs resource.
Ignoring the one-off syntax choice, opam files require you to bring your own installation and build scripts.
> Yes ocaml compiler is light years ahead Go’s one in terms of optimizations and code analysis (and even correctness [1]). It is still not as great as haskell’s one, but very good, especially with new lambda middle end. Go compiler is straightforward as hell and can’t do much inlining or optimizations that ocaml can.
I don't care about "light-years of optimizations" if the end result is still slower than Go.
> lol no math for ints, no data structures beyond map, but crappy http and Json serialization.
This is an enumeration fallacy. I can rattle off a laundry list of OCaml standard library problems as well. This isn't constructive discussion.
> As for libraries opam now have thousands of these and ocaml libraries’ quality is often much higher than the quality of libs of this other imperative language due to quality of language.
I find this not to be true, at least in the case of OCaml vs Go. OCaml libraries are typically overly-abstract or they prefer unintuitive operators and identifiers and generally take much longer to grok than the time they save to use.
Again, I agree that Go the language needs work, but the ecosystem is fantastic. Of course, improvements to the language could benefit the ecosystem (for example, sum types would bring sanity to JSON), but I can still be far more productive in Go than in OCaml.
What do you mean?
>if the end result is still slower than Go.
Benchmarks?
>OCaml libraries are typically overly-abstract or they prefer unintuitive operators and identifiers and generally take much longer to grok than the time they save to use.
Examples? I’ve never seen any of this in a whole mirage stack, lwt, angstrom/faraday, yojson or any other major ocaml lib.
build: [
["./configure" "--prefix=%{prefix}%"]
[make]
]
> Benchmarks?I'm not asserting that Go is faster, I'm saying that you need to provide evidence that OCaml is faster if you want me to believe that OCaml's compiler is "light-years ahead of Go's in terms of optimizations". Perhaps you didn't mean "OCaml is faster", but only "OCaml is hard to very hard to make fast, but the OCaml compiler does a fantastic job despite". In which case you'll need to justify why that matters to me if it's not actually faster than Go (especially if the performance is worse and/or less intuitive).
> Examples? I’ve never seen any of this in a whole mirage stack, lwt, angstrom/faraday, yojson or any other major ocaml lib.
It's been a while, so the details are foggy. Looking at the RealWorldOCaml page for yojson, however, immediately takes us through an example with a dozen `|>` operators and functional combinators. Perhaps this is a documentation problem and there are more straightforward mechanisms, but that's no great comfort to me as a user. Something as common as JSON should be dead simple, at least in the main cases. And while I have lots of criticism for Go's JSON handling, it is dead simple in the main cases.
Note that this isn't a particularly good example of OCaml libraries being overly abstract; it's just the most concrete example I could provide in a 5 minutes.
Nowadays it's just build: ["jbuilder" "build" "-p" name "-j" jobs ]
It's just one line of config and it is worth it since it gives an opportunity to use any build system you want to (or for some reasons have to) use. Still much better then pulling "deps" from github repos directly.
>I'm saying that you need to provide evidence that OCaml is faster
>"OCaml is hard to very hard to make fast, but the OCaml compiler does a fantastic job despite". In which case you'll need to justify why that matters to me if it's not actually faster than Go (especially if the performance is worse and/or less intuitive).
Sure, you can write manually a ton of boilerplate for each numeric type in go, just like it's done in gonum. I'm not sure if it is good since more code means more issues and bugs, and I definitely prefer to write or hack something like this:
https://github.com/inhabitedtype/httpaf/blob/master/lib/pars...
instead of this:
https://github.com/valyala/fasthttp/blob/master/header.go
(and this is only a header)
and let the compiler do all the dirty work.
> with a dozen `|>` operators
how the hell is `|>` an obscure combinator? It's just a "unix pipe's" typesafe kin. I've never seen any usage of obscure combinators in ocaml beyond parser-combinator libs ofc but these usually are well documented and you wouldn't use them if you don't like combinators anyway.
>Something as common as JSON should be dead simple
It is dead simple, just add [@@deriving yojson] to your data structure, and you'll get to\of_yojson functions, what could be more simple?
It's just one line of config and it is worth it since it gives an opportunity to use any build system you want to (or for some reasons have to) use. Still much better then pulling "deps" from github repos directly.
I strongly disagree here. Deps is rather ugly, but it works and it's easy to use. A language should have 1 build tool that works for 99% of use cases, and the rest of the tooling should support that by default. This is especially painful for beginners, amplified by the fact that the docs point you to Makefiles by default.
> Sure, you can write manually a ton of boilerplate for each numeric type in go, just like it's done in gonum. I'm not sure if it is good since more code means more issues and bugs, and I definitely prefer to write or hack something like this:
I'm confused; you're responding in the context of compilers producing fast code, but you seem to be advocating for a more generic type system than Go has, which I've already agreed about.
> how the hell is `|>` an obscure combinator? It's just a "unix pipe's" typesafe kin. I've never seen any usage of obscure combinators in ocaml beyond parser-combinator libs ofc but these usually are well documented and you wouldn't use them if you don't like combinators anyway.
I didn't claim it was obscure; I claimed that it's not useful--it's optimizing for fewer keystrokes and not readability. I can appreciate code-golf for its own sake, but I need my team to be able to jump into code quickly, and that often means that naive is better than clever and a little boilerplate is better than terseness. BTW, the HTTP parser that you shared is a good example of this. The Go version might be imperative, but at least it's clear.
> It is dead simple, just add [@@deriving yojson] to your data structure, and you'll get to\of_yojson functions, what could be more simple?
Like I said before; this might not be a good example, it's just the first one that came to my mind. Maybe the problem here is that the good documentation is so hard to find. Still, I've come across lots of unnecessarily abstract libraries before, I just don't recall the details.
it makes code much more readable
produce_collection ()
|> Col.filter pred
|> Col.map to_json
Only pure logic of the program remained, no garbage like intermediate vars, loops, etc.>The Go version might be imperative, but at least it's clear.
Depends on how do you define clear. If huge manually optimized pile of imperative spagetty is clear, than yes. My definition of clear presumes sophisticated abstractions making hard things easier to reason about and comprehand, not a pile of hand-written state machines.
>Still, I've come across lots of unnecessarily abstract libraries before,
So many that you couldn't find an example?
search again