I would love this; I feel entirely the same. The runtime is pretty good, performance is nice, concurrency is great, the tooling is wonderful (if you ignore the GOPATH nonsense and thew lacklustre package management solution). The language itself is quite frustrating to use, full of needless repetitive boilerplate and a mediocre type system.
I'd love a similar language with all the goodies that I find make development safer and more productive: proper enums, pattern matching, sum types, generics, and a handful of other features.
This is one of the better articles that shows both when comparing Python, Go and Elixir.
https://medium.com/unbabel-dev/a-tale-of-three-kings-e0be17a...
For example, there is the May[1] concurrency library. It provides alternative implementations of the standard library's IO interface, but does Go's automatic suspend/resume, so it still looks like blocking code, which is nice. From what I can tell it's still early days on a one-person project, but it is interesting, at least.
On the other hand, the concurrency OOTB languages have all had much better ecosystems and experiences; C#, nodejs(now and w/TypeScript), F#, Golang, etc.
Inferior approaches sometimes do get baked in to standard libraries. Having a culture of versioning, deprecating, migrating, is better IMO. But it's even better again to do a really good job first time around. Not easy, but I didn't say it was!
libfringe is another extremely interesting player in this space.
I don't know about "might be worth it" part, and I don't think Go is success is because of it's concurrency model. Instead, I think Go wins because it can get thing done quickly, in one stop.
The concurrency model has been designed to help achieve that, and the huge battery pack came with the language is also for help achieve that.
I'm not discouraging you from design your language, though. In fact, I could be very happy to see a new language which can give me all the benefits that Go gives me and at same time just ... simply be a better language.
My ideal language (in my opinion) is a combination of Go and Rust: Big standard battery (Help me get things done and encourage to it's ecosystem)(&BTW, it don't have to be in the standard library), and fearless programming (Help me avoid mistakes).
Sadly Rust don't want to have a big battery for some reason :(
Rust is against pulling it in the standard library because that forces them to make additional stability guarantees. When you do that, you end up like python's `urllib`/`urllib2` situation.
That's what I did for my current project. I love Go but for web apps is not the best in my opinion. I had some spare time and ended up building a VM that compiles typescript to bytecode. The performance loss is minimal, I still use the Go std library but it is a pleasure to use VS Code, generics (the VM ignores types but the TS compiler gives you static type safety, autocompletion, refactoring, etc...) Also exceptions is great for web apps where usually there is nothing else you can do but save all the info that you can and show an error to the user.
I hardly ever use classes unless I'm extending a vendor library. I have never used generics. Why are generics such a critical component of a programming language that every thread about Go mentions it? It's an honest question from me.
Go has built-in generic arrays, slices, and dictionaries, but nothing else, and you can't define your own functions that work on those without specifying the type. So say you write a function that shuffles the elements of an array, like Python's random.shuffle(list). You can't make your function work for all kinds of arrays. You have to have a different function to shuffle arrays of strings, arrays of ints, arrays of FooBarClass, etc. even though the shuffling logic doesn't give a damn about what sort of thing is in the array.
I have a suspicion that this occasionally leads developers to write code inline that they previously would've extracted into a utility function. See the answers here:
https://stackoverflow.com/questions/12264789/shuffle-array-i...
So essentially, containers and function overloading is damned near impossible. Got it.
def example(a):
return a
Would be perfectly legal python code. But in Go you would have to choose the type of A and duplicate the function under a different name if you want it to work with a different type.So, when a language implements static typing without generics they actually mean 'lots of code and approaches legal in Python would be rejected'.
So it doesn't add a feature to the expressiveness of the code. It fixes a bug in the type system so that the expressive code is considered legal. Of course better type systems have existed since the 70's, but the set of people that know the ins and outs of how to implement those and the trade offs behind it does not include Rob Pike. His interests and skills are different (and the cause of some of the better features of Go)
Personally, I do not feel that strongly about generics; it would be nice to have them, but for my purposes, I can live without them.
But still: generic container types would be very nice. I don't need to use it very often, but Go's sort.Sort is very uncomfortable to use. If Go had proper generics, it would be easier to define a "generic" interface to iterate over things - currently, Go's builtin slice and map types are privileged over user defined types. There are probably more issues I cannot think of right now.
None of those are deal breakers for me. Go is highly compatible with the way my mind works, to such a degree I can easily forgive it all the things I do not like about it. But I also work in C# from time to time, and seeing how the .Net framework uses generics makes me wish Go had them, too.
However, comparing to Python won't make much sense; people see generics as essential to statically typed langauges. You don't need them for dynamically typed ones!
Agreed. Something that's been underlined for me since picking up TypeScript in addition to JavaScript. I can take or leave TS when writing a script, but I consider it indispensable when writing a library.
That's the reason why the Go community feels generics are not the top priority (euphemism.)
Only in very specific cases (implementing data structures, for example) you can feel the need for generics. Maybe also in serialization, although that's really normal to pass a generic container (object, void *, interface{}) and use introspection.
I don't think it's such a bad idea, considering how stable the language itself is, it's a pretty solid bet.
Why not fix Go instead?
The lack of libraries is what drove me away, too. The type system is gorgeous, though. I really hope Pony grows a decent library ecosystem soon, the language itself was very pleasant to use once I got past the initial learning curve.
If you rephrased that as 'a templating language for generating Go code', it would slot into the 'go generate' build stage and people would love you (if you got it right ;) ). The only current solution to boilerplate and lack of generics is code generation, but the templating languages all seem to suck for Go code generation so people are stuck with writing Go programs to generate Go code (like the various enum generators), or attempt to marry Go code with the standard text templating which is awful to work with (like, say, Xo).
(Edit: BTW I do not necessarily agree that)
For example, consider trying to implement a List data structure in Go. What type does the List hold? It poses no constraints on the type of things put in it, except that they must all share that type.
The List can store `interface{}`, but then there's nothing to stop you from adding two different types to the list. And what type of value would a method like `getFirstItem()` return? Just an `interface{}`, forcing the user to cast.
Go's interfaces express constraints on individual types (e.g. type A has methods Foo and Bar) but not across functions defined on a struct (e.g. the type that a List stores is the SAME type that the getHead() function returns).
There are good aspects of Go concurrency like how the whole ecosystem is async by default (like Node's), but truly praising the model is something I mainly hear from beginners.
I adore Go's concurrency model but loathe go's actual language. The constant repetition in error handling, lack of generics and lack of parameterised types and Option<> make it feel like a children's toy set version of C instead of a useful modern language akin to Rust and Swift (and modern javascript).
I really really love the concurrency model though. And as far as I can tell there isn't much like it available elsewhere. You can make a similar concurrency model in rust, but you have to use much heavier OS level threads to do it, and all the other crates don't support it. Erlang / elixir do it but come with a much higher runtime performance penalty. Pony is interesting but very new - there aren't a lot of libraries for it and when I was playing with it the compiler seemed crazy slow.
I'm a little bit tempted to make a simple compile-to-go language. I'd get lynched at Go meetups for fragmenting the ecosystem, but it might be worth it. I like almost everything about go except the language itself.