
Underscore.go - Goranek
http://tobyhede.github.io/underscore.go/
======
jerf
Underscore was chosen in JS presumably because it is a valid variable name
that isn't used for anything. Underscore in Go actually means something, which
is why this is actually _double_ -underscore, which makes it even visually
more confusing.

The approach is interesting, but I'd _really_ rather see a better name.

~~~
6cxs2hd6
Module systems really ought to allow renaming on import. (Such as: rename
individual functions, add a prefix to all of the functions, or even do a
regexp style replace of all existing prefixes if any.)

But unfortunately, from a quick glance it looks like Go's doesn't, is that
correct?

~~~
icholy
You can rename the package on import
[http://play.golang.org/p/V01jD_EZyX](http://play.golang.org/p/V01jD_EZyX)

------
tptacek
Underscore is not a perfect fit for JS, but it's close enough; if you like
coding in the style Underscore promotes, Underscore.js makes Javscript
programming simpler.

Underscore seems like it would _not at all_ be a good fit for Golang. Golang
really wants you to just use a for-loop.

~~~
Daishiman
It seems that enough people are tired of such a verbose idiom in 2014 to merit
a library like this.

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?).

~~~
shantanubala
It depends on the level of abstraction with which the language was designed.

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.

~~~
Daishiman
A systems programming language would never come with a baked-in, hardcoded
garbage collector incapable of soft realtime applications and such a limited
scope in utility, not such a constrained set of concurrency primitives and
such a basic type system.

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.

~~~
pjmlp
> A systems programming language would never come with a baked-in, hardcoded
> garbage collector incapable of soft realtime applications and such a limited
> scope in utility, not such a constrained set of concurrency primitives and
> such a basic type system.

\- Mesa/Cedar (Xerox PARC)

\- Modula-3 (Compaq/Olivetti)

\- Oberon/Active Oberon (Swiss Federal Institute of Technology)

\- Sing# (Microsoft Research)

\- D (Digital Mars)

~~~
dbaupp
Presumably you're contesting the garbage collection point? However, the
statement was a conjunction of that and:

\- 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").

~~~
pjmlp
My main point was GC, yes.

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.

------
benatkin
What is the term for unpythonic in the Go community? This seems to be it. By
the way it isn't using gofmt.
[https://github.com/tobyhede/underscore.go/blob/master/src/un...](https://github.com/tobyhede/underscore.go/blob/master/src/underscore_test.go)

It shows that the author knows how to code go, but I get the impression that
go programmers are more picky about idiomatic code than even python
programmers, so if the author wants to get into go development, the author
should probably stop that and work on something more idiomatic.

~~~
nestlequ1k
goop. just kidding, i made that up, but i hope it sticks

~~~
jzelinskie
It won't because "goop" is already a dependency manager for Go.

------
ChikkaChiChi
The Go community is still small enough that any packages like this that get
promoted become cringe-worthy if they are not idiomatic. If someone is coming
from a javascript background and this is the first package they see, it might
give them the wrong idea about Go.

While this could be considered pedantic idolatry by some, Codegangsta's very
public admission on his experience with Martini (and now Negroni) show that
this is a something to be considered when launching shiny new baubles.

In my opinion, the more attempts at stuff like this, the better. This is how
we all learn!

[http://blog.codegangsta.io/blog/2014/05/19/my-thoughts-on-
ma...](http://blog.codegangsta.io/blog/2014/05/19/my-thoughts-on-martini/)

------
tobyhede
Oh hello. Library author here.

Underscore.go is a mostly WIP that I hadn't intended to go live on HN :)

The general feedback so far is __ is annoying, I thought it was cool and if
people were annoyed they could fix it on import. But I might be quite wrong on
this one.

The directory layout is going to change and I am working on a branch at the
moment that splits the whole thing into a file per algorithm, which makes
things much easier to work with.

~~~
enneff
You should make the library installable with "go get" (yes, "__" is an
ecosystem-hostile import path), and remove .go from the repository name.

~~~
tobyhede
Yep. Both points are top of the todo list.

------
alexpw
Not quite as interesting to see an _ clone after watching this critique of _
[https://www.youtube.com/watch?v=m3svKOdZijA](https://www.youtube.com/watch?v=m3svKOdZijA)

------
garfij
Neat. I like that you can add your own type specific functions.

I was interested in seeing the implementation of the Parallel Map, but on a
quick browser through the source, could not find it.

If you're interested in other works in the same space, I think think the the
Gen library
([http://clipperhouse.github.io/gen/](http://clipperhouse.github.io/gen/))
goes a long way towards providing type-safe, idiomatic, Go code to achieve the
same effects.

~~~
ktsmith
It doesn't appear that it is complete when compared to the listed
functionality on the site.

~~~
mwsherman
Yes, but gen is more general for type-driven code generation. It’s implemented
as pluggable ‘typewriters’, which anyone can create:
[https://github.com/clipperhouse/gen/blob/master/CHANGELOG.md](https://github.com/clipperhouse/gen/blob/master/CHANGELOG.md)

The default ‘genwriter’ package does LINQ/underscore stuff. If someone wanted
to go further with it, they could create a new package (or extend that one).

------
jprob
If there's a `src` folder in your repo, you're doing it wrong.

~~~
Kiro
Why?

~~~
jprob
[http://golang.org/doc/code.html#Workspaces](http://golang.org/doc/code.html#Workspaces)

------
ankurpatel
Similar to [https://github.com/markmontymark/underscore-
go](https://github.com/markmontymark/underscore-go)

------
pjmlp
Love how the library takes advantage of Go's generics to expose parametric
functional programming.

[https://github.com/tobyhede/underscore.go/blob/master/src/un...](https://github.com/tobyhede/underscore.go/blob/master/src/underscore.go#L59)

[https://github.com/tobyhede/underscore.go/blob/master/src/un...](https://github.com/tobyhede/underscore.go/blob/master/src/underscore.go#L85)

------
mediocregopher
As a shameless, related plug, here's a clojure-like seq library I wrote for
go:

[https://github.com/mediocregopher/seq](https://github.com/mediocregopher/seq)

It isn't quite as pretty as this one is, but it does support (thread-safe)
lazy sequences.

As someone who writes lots of go code, I don't think either of these are
actually _necessary_ , although they may be fun to use in some cases.

------
ahmett
I have done something similar in the past:
[http://ahmetalpbalkan.github.io/go-linq/](http://ahmetalpbalkan.github.io/go-
linq/) ([https://github.com/ahmetalpbalkan/go-
linq](https://github.com/ahmetalpbalkan/go-linq)) this also has filter/map
functions (where/select in LINQ) I haven't used reflection but callers should
make type assertions needed.

This doesn't make things very slow but not very faster either. When you need
performance, a code generator like this can help:
[http://clipperhouse.github.io/gen/](http://clipperhouse.github.io/gen/)

------
findjashua
Using the function as the first argument and the iterable as the second, makes
it easy to curry functions. A port of Ramda
([https://github.com/CrossEye/ramda](https://github.com/CrossEye/ramda)) would
be better for this reason.

~~~
tobyhede
Thanks that's an interesting idea

------
Randgalt
-1 on double underscore. Very off-putting.

~~~
tobyhede
Yeah. Feedback received. Changing.

------
maninalift
Ew, now you can have an awkward weak implementation of some FP ideas in Go
too.

Yeah, I'm a bitch.

~~~
igl
yo dawg, i heard you like FP...

------
mc_hammer
really cool, thx for this. just what go needs imo.

