Underscore seems like it would not at all be a good fit for Golang. Golang really wants you to just use a for-loop.
Underscore seems like it would not at all be a good fit for Golang. Golang really wants you to just use a for-loop.
I really dislike being that guy, but there's no reason why a language, today, shouldn't implement a decent map shorthand construction. For loops and unnecessary visual burden for a large variety of tasks and give no hint to the semantics of the code within a loop (is my loop doing a map, a transform, a reduction?).
Go was designed for systems programming, and the code is intentionally verbose. A few extra characters, brackets, and syntactic constructs are a small price to pay for more control in performance-critical applications.
JavaScript was designed for the web to make authoring interactive pages easier. The web benefits as an ecosystem to have commonly-used abstractions for lower-level data transformations and common tasks.
So yes, there are reasons why a map shorthand is not needed. Mostly because it doesn't do anything a loop cannot, and the ecosystem in which it was developed does not benefit from it.
Seriously; LuaJIT achieves greater performance and has more abstractions in place; Rust fills the niche of systems programming languages easily.
I just fail to see the long-term utility of Go in a space where you have upcoming, high-performance languages like Julia and Rust, all while V8 and asm.js continue to improve in performance, LuaJIT wipes the floor in sheer speed for a dynamically typed language, C++ gets saner abstractions every day and the Erlang VM gets such a nice language as Elixir in the space of critical distributed apps.
Go would be interesting if you were at least getting something interesting out of that garbage collector in terms of type system goodness; as it stands Go is only slightly safer than C in that regard.
And by the way: what the hell does not having a Map() function have anything to do with performance? C++11 has std::transform which goes as fast as anything else. Any functional traversal of data structures can be trivially turned into an internal representation with the same performance characteristics as a loop. It's the biggest cop out ever.
- Mesa/Cedar (Xerox PARC)
- Modula-3 (Compaq/Olivetti)
- Oberon/Active Oberon (Swiss Federal Institute of Technology)
- Sing# (Microsoft Research)
- D (Digital Mars)
- not such a constrained set of concurrency primitives
- such a basic type system.
I imagine those languages have a good type system and/or good concurrency primitives (i.e. possibly making up for their GC "penalty").
Actually the original Oberon type system is simpler than Go's. Its later revision Oberon-07 is even simpler.
All the other ones I mentioned, have better type systems than Go, even support for some form of generics.
Concurrency depends on the language, but you get a mix of threads, co-routines, tasks, active objects and processes, overall.
> Go was designed for systems programming, and the code is intentionally verbose. A few extra characters, brackets, and syntactic constructs are a small price to pay for more control in performance-critical applications.
Rust offers more fine-grained control over memory, and things like map, filter etc. are more idiomatic than straight for-loops. They are implemented in a way that makes it a zero-cost abstraction compared to regular for-loops.
Generally I think Rust and Go gets compared too much, since they are very different languages both technically and philosophically. But the claim that things like map, filter etc. is unsuitable in a systems programming language (and Rust's definition of 'systems' has more stringent requirements than Go's definition of 'systems') is clearly false.
I can understand programmers wanting FP concepts and techniques in languages like C++; there is a lot of legacy C++ code, libraries and overall a large ecosystem. Some C++ programmers might either
1) have started programming in C++ many years ago (let's say 8+ years ago), and they might have thought that procedural and OO concepts where all that they wanted in C++. Now they might see some benefit in FP concepts, and want to see them used in C++, too. They don't want to switch languages because they already like C++ overall, and they have invested a lot of time into it.
2) They are "stuck" with C++ because of libraries, legacy code etc.
But the Go language is, what, 5 years old? It probably also has less legacy code, and I guess also relatively lacking ecosystem of libraries compared to other more established (or just older) languages. Why shoehorn FP concepts into Go instead of just moving on to a language where these concepts aren't seemingly going against the grain of the design of the language? Do most people really have a lot to lose from "ditching" Go?
This has come from some work I have been doing in Go. I was finding it very repetitive to constantly create basic constructs for common operations and patterns.
The approach I have been working with is using reflection based helpers to move fast, especially while exploring a problem space, and then refactor as appropriate when the design has solidified.
One advantage of underscore.go is you can create typed functions, so you aren't losing the compiler's help. The performance is generally OK, it is obviously slower than raw loops, but I think the tradeoff in many cases is worth it. In my experience, development time is a scarcer resource than cpu cycles. And nothing about this prevents you from gaining those cycles back when you need to.