News for hackers. Stuff that matters.
Re:The State of Go by grabcocque on Sunday February 05, 2017 @09:43AM (#13572566)
The best summary I read recently is that go isn't a bad language, nor is it a particularly good one. What fascinates me is the way the Golang community have concretised that essential middle-of-the-roadness as the language's prime virtue. That, of course, has long been Java's prime virtue as well. (see Blub Paradox)

By putting "we're okay with being okay" as your Big Thing you're clearly pitching for that vast bulk of mid-quality developers that make up the huge middle chunk of corporate devs, the space where Java reigns supreme.

Re:The State of Go by dilap on Sunday February 05, 2017 @12:41PM (#13573447)
Nah. I like Go because the language itself is minimal yet powerful, and because the quality of engineering is extremely high. I am so tired of having to deal with bullshit because of poorly-thought-out and poorly-engineered tools; Go minimizes that.

An excellent example is the handling of this bug report(§):

https://github.com/golang/go/issues/12914

which resulted in this language-change proposal:

https://github.com/golang/proposal/blob/master/design/12914-...

And then these commits:

https://go-review.googlesource.com/#/c/36255/

I feel like any other language I've used would've just added a "monotonicTime" function and called it a day; the Go solution is impressive, elegant, and shows an exceedingly high level of care for the end-outcome results for the users of the language.

To me, that's what makes Go special.

(§After a rocky start; it took the core devs a bit to realize it was a real issue because within Google's special environment it isn't.)

Re:The State of Go by Groxx on Sunday February 05, 2017 @12:53PM (#13573521)
I dunno... in some ways, the problem is that they didn't think it through to begin with, and chose something widely-known-to-be-ambiguous-and-problematic like "time.Now()", instead of choosing unambiguous names / structures from the start.

It's kinda the equivalent of making a new language (nowadays) and not defining what encoding your native strings use. Of course it's going to cause problems. Except the timer issue has been around much longer than the standardization on utf-8.

Re:The State of Go by dilap on Sunday February 05, 2017 @01:25PM (#13573668)
Fair point! And I certainly don't claim that the Go devs don't make mistakes. They started with the theory that the problem should solved as Google does, by arranging that clocks don't run backwards. When it become clear that wasn't reasonable, they moved towards a new solution in a way that I felt was impressive.
Re:The State of Go by Groxx on Sunday February 05, 2017 @01:36PM (#13573734)
It's mostly-impressively backwards compatible, I'll definitely agree there. It's clever, and in many cases it'll do the right thing automatically. Since it seems that's their goal, they achieved it quite elegantly, and that's a tricky thing to do. (edit: and quite quickly! seriously, this is an example of a healthy community at its best)

But personally I don't agree with the decision - it adds surprises when you try to convert times to other types and then compare things. Or convert to something else and then back to a time instance. I've watched things like this become the source of bugs many, many times - this will only make that worse, since now a "time" is two values but you can really only access one of them (the one that's equivalent to wall-clock, which is causing the problems). And they're particularly painful bugs, because the cause lies in implicit conversions and behavior. That seems to run counter to the "minimal surprises" that Go seems to prioritize.

Re:The State of Go by dilap on Sunday February 05, 2017 @02:44PM (#13574138)
There's no denying it's at least flirting with "too clever" territory. What saves it for me is (1) the analysis of a large body of code that seemed to show only positive impact (2) that the behavior is well-documented and (3) anytime you're converting between types, you should always be thinking, "what is the range of these types? what information might get lost?", which with (2), should leave you alright.

But, I could easily see looking back in 2 years and realizing you were right.

Re:The State of Go by Groxx on Sunday February 05, 2017 @03:00PM (#13574235)
"Should", definitely :) Easier said than done. But I'm happy to wait and see, it's not like this would make Go the only language with weird time handling. As it stands they're probably in a better place than most people are used to.

That code-corpus-analysis is pretty neat, I hadn't looked through in detail before. Thanks for pointing it out!

---

Sorta as an aside, it seems the proposal can lead to:

  t1 = time.Now()
  ...
  t2 = time.Now()
  diff = t2.Sub(t1)
  t1.Add(diff) != t2
Times are hard :|
Re:The State of Go by dilap on Monday February 06, 2017 @09:05PM (#13586336)
I think that should be fine.

    t1.Add(diff).Equal(t2) 
would still hold, because Now gets monontonic time, Add and Sub maintain it, and Equal checks it.
Re:The State of Go by Groxx on Tuesday February 07, 2017 @02:16PM (#13591788)
It's entirely possible I'm wrong since I didn't read through things in great detail, but this is what I'm thinking.

  // time = [wall, mono], just ints for simplicity
  t1 = time.Now() = [10, 10]
  t2 = time.Now() = [19, 20]             // wall clock lags slightly on second measure
  diff = t2.Sub(t1) = (20 - 10) == 10    // Sub only operates on mono-time
  t1.Add(diff) == [20, 20]               // Add adds `diff` to both wall and mono
  [20, 20] ==?== [19, 20]
I'd expect those to be different, since they represent different wall-clock times.
Re:The State of Go by dilap on Tuesday February 07, 2017 @07:40PM (#13594544)
If both times have mono time, then Equal() compares that, and ignores wall time.

So t2.Equal(t1) is true.

You are right that "t1 == t2" (comparing the raw bytes of the time structures) is false, but that was already broken anyway (because time-zones break raw byte equality).

(Whether you think it's OK to have a language that doesn't overload == and makes you know that for complex structures you've got to call a method like Equal() probably correlates pretty highly with your opinion of Go.)

There will of course be other weird things, like:

    print(t1) // "20 [20]"
    print(t2) // "19 [20]"
But you could argue that's basically the least-surprising possible result in the face of the surprising fact time having gone backwards one second. :)

By the way, worth mentioning that while this is all implemented in HEAD in Go, it's not a done deal yet -- it'll have a 3-month window for people to try it out in the real world, and if it's found to be problematic, it'll get backed out before becoming part of the official release.

Re:The State of Go by Groxx on Tuesday February 07, 2017 @09:34PM (#13595191)
>If both times have mono time, then Equal() compares that, and ignores wall time.

Gotcha, I missed that somewhere. That's essentially fine - then the only real surprises are when you deserialize a Time (so it doesn't have a mono time), which should in principle have no interactions with this proposal.

And yeah, Equal vs ==, the meaning was clear enough that I didn't bother to be specific :) Thanks for the infos!

Re:The State of Go by dilap on Tuesday February 07, 2017 @09:40PM (#13595210)
Cheers!
Re:The State of Go by solipsism on Sunday February 05, 2017 @06:45PM (#13575447)
I am so tired of having to deal with bullshit because of poorly-thought-out and poorly-engineered tools

Seems to be some cognitive dissonance (in the modern erroneous sense of the word) going on. This was a hack necessary because the design of the library wasn't fully thought out. Imagining the world would one day become Google is not thinking things out.

Re:The State of Go by dilap on Monday February 06, 2017 @12:57AM (#13576875)
It was something not in the library because it wasn't in their sphere of consideration. When that expanded, due to feedback from the outside world, they responded in an impressive way.

And that's just an example that was intended to illustrative.

You'll just have to take my word for it that my experience of the Go ecosystem, tools, and standard library has been more solid than the various other things I've used over the years (python, C# + unity, c++, fucking maven, boost...).

If I'm missing out on something even better, let me know. ;-)

Re:The State of Go by geodel on Sunday February 05, 2017 @09:11PM (#13576049)
> This was a hack necessary because the design of the library wasn't fully thought out.

Easy to say 'not fully thought out'. It took Java from version 1.2 to 1.8 to fix its date/time library.

Re:The State of Go by AdieuToLogic on Monday February 06, 2017 @12:12AM (#13576676)

  It took Java from version 1.2 to 1.8 to fix
  its date/time library.
That is incorrect[0]. When spreading FUD[1], expect assertions such as these to be fact checked by others.

0 - http://search.maven.org/#search%7Cgav%7C1%7Cg%3A%22joda-time...

1 - https://en.wikipedia.org/wiki/Fear,_uncertainty_and_doubt

Re:The State of Go by jwilk on Sunday February 05, 2017 @01:43PM (#13573780)
Clever? Sure.

Elegant? Hell, no. It's an ugly hack.

Re:The State of Go by artursapek on Sunday February 05, 2017 @10:32AM (#13572749)
What on earth is a "good" language?

> you're clearly pitching for that vast bulk of mid-quality developers that make up the huge middle chunk of corporate devs

That was actually something Google aimed for with Go, and I don't see what is shameful about it. It's a simple language on purpose. It is meant to be easily learned by any developer, and similarly Go code is meant to be easily read.

Also, what sets Go apart for me, in addition to this simplicity, is the tooling and documentation. I think people mistakenly yearn for languages that are exciting to use or offer interesting abstractions. This stuff is fun for the individual developer but costs an organization in the long run.

Go is bland on purpose. Notice how between versions most of the headline updates are internal improvements (GC, tooling, general performance)

Re:The State of Go by aeturnum on Sunday February 05, 2017 @12:46PM (#13573485)
When I think about Go in comparison to other languages, I think of car metaphors. Lots of people talk about cars that are good. Some people think a good car is fast, some people think a good car is low maintenance, some people think a good car is eye-catching. They are all right, those are all descriptors of good cars.

Go, however, is like a Toyota Corolla or a Honda Civic. It's dependable, but relatively plain. It's not necessarily a joy to drive but there's not much of a learning curve. It lets you go fast, but not so fast you'd hurt yourself. It's designed with safety in mind, so much so that it can feel a little over-bearing at times.

It's not a language that draws you in with one clear feature or philosophy. I've used it very successfully and I still find myself rolling my eyes at "go-isms." Lines of "ok, err = ...", rewriting extremely similar data structures, careful channel management, etc. In a list of dependencies, the go dependency will need the least maintenance time and tuning, but what you do need will often be drudgery.

Go is a useful language, but it's a language that has purposefully stripped out all the magic. People like magic, they miss it.

Re:The State of Go by artursapek on Sunday February 05, 2017 @01:03PM (#13573571)
> Go is a useful language, but it's a language that has purposefully stripped out all the magic. People like magic, they miss it.

I agree with everything you wrote except this. After 3 years in a job where I had to use Ruby on Rails, I am utterly tired of "magic" and I regret the many hours of my life I have wasted debugging issues that were created/concealed by it. Lack of magic is a feature in my opinion. But as you said, that's all this is - opinions.

Re:The State of Go by strken on Sunday February 05, 2017 @06:09PM (#13575286)
I find Forth, Ruby, Elixir, various Lisps, etc. almost impossible to reason about because of this. Powerful metaprogramming tools can lead to really hard to understand and hard to refactor code.
Re:The State of Go by enraged_camel on Sunday February 05, 2017 @11:15PM (#13576432)
>>Powerful metaprogramming tools can lead to really hard to understand and hard to refactor code.

They can, but that doesn't necessarily mean they do.

For example, the usage of Elixir macros, which are the primary metaprogramming tool in Elixir, is discouraged in the docs:

http://elixir-lang.org/getting-started/meta/macros.html#fore...

Re:The State of Go by artursapek on Sunday February 05, 2017 @08:41PM (#13575928)
Refactoring is the worst part, so bad that people just don't do it. This naturally leads to very convoluted code bases. Ugh. Never again.

And actually, this is another place Go shines. Refactoring Go code is easy because the compiler helps you along. There's even standard tooling that automates some of it. Amazing.

Re:The State of Go by omginternets on Sunday February 05, 2017 @02:23PM (#13574032)
>Go is a useful language, but it's a language that has purposefully stripped out all the magic. People like magic, they miss it.

Agreed, and I'd further argue:

1) most people driving Ferraris aren't skilled enough to drive them properly

2) most people driving Ferraris have no need to corner at 120 MPH

3) most people driving Ferraris are just trying to show off

4) most people driving Ferraris are more likely to hurt themselves and others than to save the day through the car's performance and handling

(To be clear: I think we're in agreement, but the metaphor is worth explaining in depth)

Re:The State of Go by prodigal_erik on Sunday February 05, 2017 @02:46PM (#13574151)
It's an apt metaphor. Much like programming, there are a hell of a lot of people driving who really shouldn't be.
Re:The State of Go by eeZah7Ux on Sunday February 05, 2017 @04:57PM (#13574889)
Then there should be programming licenses:

Level 1: let interns use Go(-karts), like their parents did with Basic.

Level 2: most languages. Proper training required and you still have to be careful.

Level 3: C, C++, critical code, kernels, crypto code. Training a commercial airline pilot takes years; and while this stuff is not hip enough for some, there's plenty of demand.

Re:The State of Go by pka on Sunday February 05, 2017 @05:41PM (#13575141)
C programmers should be held personally accountable for the damage they cause.

Now of course everybody makes mistakes, but if you deliberately choose C when there are better options available then you should pay out of pocket for your buffer overflows and 0-day exploits.

Re:The State of Go by aeturnum on Sunday February 05, 2017 @08:08PM (#13575786)
Yes, I think there are a lot of parallels between high performance cars and high performance languages. Both are held in high esteem and are frequently mis-used when a more balanced vehicle would do better.
Re:The State of Go by baby on Sunday February 05, 2017 @02:56PM (#13574214)
> It's not necessarily a joy to drive

Go is the most fun language I've been using. On the contrary, I don't understand how some people can enjoy Java.

Re:The State of Go by watwut on Sunday February 05, 2017 @05:10PM (#13574964)
The thing that makes java pleasant is large open source ecosystem around it + IDE quality (meaning mostly refactoring and code navigation, especially when compared to dynamic languages). Frameworks like spring or hibernate etc are mature enough and old enough, so there is a lot to learn just by reading.

The language itself makes it easier to figure out what large code written by somebody else was mean to do - not that everything would be readable nor anything like that, but easier then say ruby or javascript.

Re:The State of Go by zik on Sunday February 05, 2017 @10:06PM (#13576211)
> Go, however, is like a Toyota Corolla or a Honda Civic.

The only problem with this argument is that everywhere - even in this thread - there are people saying that Go is a joy to program in. It's not lacking magic, it's magical in its own right.

A better car analogy would be that Go is a Lotus Elise. It's nowhere near as powerful as your friend C++'s Mustang or Rusty's McLaren. But to C++ and Rusty's dismay Go's little Elise still gets around a racetrack crazy fast. It may have a smaller engine but it's just taken a really different approach to going fast which works really well. And Go has a much more pleasant time getting to his destination than C++ and Rusty do.

Re:The State of Go by enraged_camel on Sunday February 05, 2017 @11:11PM (#13576425)
>>>> Go, however, is like a Toyota Corolla or a Honda Civic.

>>The only problem with this argument is that everywhere - even in this thread - there are people saying that Go is a joy to program in.

Not sure why it's a "problem". I love driving my 2004 Honda Civic, and prefer it to newer, fancier cars. It's fuel-efficient, drives very well, and has not given me an ounce of trouble. So yeah, the comparison to Go seems very apt.

Re:The State of Go by peteretep on Sunday February 05, 2017 @10:23PM (#13576270)
Some people find dull cars a joy to drive.
Re:The State of Go by geoka9 on Sunday February 05, 2017 @01:06PM (#13573585)
Using a similar metaphor, I'd compare Go with a jet that's high performance but easy to fly - i.e. it doesn't have the numerous gotchas and quirks high performance jets usually have that the pilot has always have to keep in mind to avoid shooting themselves in the foot (aka making a hole in the ground :)).

E.g. it won't let you overload your engine by using a very special feature that lets you get away with it, but it'll let you fly fast and enjoy afterwards how trouble free the experience was.

OK, I think I'll stop with the mataphors now :)

Re:The State of Go by bsg75 on Sunday February 05, 2017 @04:06PM (#13574645)
Re:The State of Go by pmontra on Sunday February 05, 2017 @05:57PM (#13575222)
> What on earth is a "good" language?

I've seen enough languages to make comparisons.

Some languages get in my way and slow me down as a developer. For example I'll always pick Ruby over Java if I have to deliver something quickly. However some languages get in the way of the CPU and slow it down and if that's important I'll pick Java over Ruby.

So both Ruby and Java can be good or bad languages depending on the use case. Some languages make both the developer and the CPU lose time so I won't say they are good.

I have no first hand knowledge of Go but it seems it's fast so it should be good at least where the CPU matters.

Re:The State of Go by rpercy on Sunday February 05, 2017 @10:18AM (#13572694)
Do you have an example of the community celebrating mediocrity?

My impression is of a community willing to go without some features, in order to preserve those it values. Namely simplicity, explicitness, terseness, and consistency.

Re:The State of Go by MichaelGG on Sunday February 05, 2017 @12:06PM (#13573264)
Explicitness and terseness seem a bit at odds - I wouldn't call go code very terse at all. It seems verbose and repetitive. Consistency? Aren't only some built in types blessed with generic functions?

Mediocrity? The preference for writing loops over simple maps or folds is a bit mediocre. IIRC in Tim Sweeny's "Next Mainstream Programming Language"[1], he notes that around 90% of all the loops in Unreal are folds or maps. Maps and folds are just simpler than loops, without even appealing to terseness and elegance.

Hey I know I'm in no place to judge -- the creators of go and Google overall have accomplished more than I'll ever do. I just really cannot grasp the mindset and penchant for unexpressive languages.

1: http://lambda-the-ultimate.org/node/1277

Re:The State of Go by spion on Sunday February 05, 2017 @12:44PM (#13573474)
Thats not a strength of Go. Structural interfaces, channels and performant M:N green threads are its main strengths, and AFAIK there is no other language that provides a similar combination in a familiar C/ALGOL-like packaging.

If such a language existed and had generics and Swift or Rust style error handling as well as some backing by a large-ish corporation / organization, I think that language would be preferred to Go.

More expresiveness isn't always better. Examples that hit the sweet spot are C# / Swift (C# really needs algebraic data types). Beyond a certain point, you will start to lose users. Haskell is very expressive, but few will ever have the time or patience to learn enough to build their perfect monad transformer stack and take advantage of the mtl typeclasses to easily use it. Even though it does have M:N green threads, channels, STM and everything.

In fact, Haskell could probably compensate for this and beat Go by having excellent library documentation and well written, focused tutorials for the working engineer.

Re:The State of Go by reikonomusha on Sunday February 05, 2017 @03:06PM (#13574272)
I feel like maybe 10 years ago no one would utter something like "C# needs ADTs" because they didn't have mainstream appeal, despite computer scientists' understanding of them.
Re:The State of Go by spion on Tuesday February 07, 2017 @07:46PM (#13594589)
Yes, things are moving forward, even if slowly :)
Re:The State of Go by watwut on Sunday February 05, 2017 @05:39PM (#13575127)
The loop and map are equally readable, it is just that some people are used to one form more then the other.

More importantly, how many character needs to be used for simple idiom like that has zero influence on how maintainable your system is going to be few months later on, how fast it is and so on. The difference between loop and map wont make you do less or more bugs. It may make you read the code few seconds longer first time you encounter form you are less used to - but then you will adjust and read it just fine.

Re:The State of Go by lewisl9029 on Sunday February 05, 2017 @07:43PM (#13575674)
Functions are trivially composable, while imperative loops are not. The difference that makes in terms of maintainability and readability of non-trivial applications is hard to overstate.

Writing code in terms of small, composable, reusable functions with a clear single intent (through good naming), that you can then mix, match, and reuse to compose into larger functions is what makes good functional code so much easier to write, test, and reason about than imperative code.

My favorite intro to functional programming concepts for those used to imperative coding is Sott Sauyet's Functional Programming presentation: http://scott.sauyet.com/Javascript/Talk/FunctionalProgrammin...

The presentation makes heavy use of JavaScript and the RamdaJS library in its examples, but the concepts are universally applicable to any language with the necessary functional programming primitives. It also does a great job of comparing imperative and OO implementations of a solution to a problem vs the functional implementation. I highly recommend taking a look if you're even slightly interested in why so many people are starting join the functional programming bandwagon.

So what I'm trying to say is, it's not just a matter of readability. Although if anyone still wants to argue that imperative looping is anywhere close in readability compared to functional composition for non-trivial cases (think multi-level nested loops vs composing multiple functions), then we should just agree to disagree since I don't foresee that becoming a productive discussion.

Re:The State of Go by watwut on Monday February 06, 2017 @03:12AM (#13577501)
"Writing code in terms of small, composable, reusable functions with a clear single intent (through good naming), that you can then mix, match, and reuse to compose into larger functions is what makes good functional code so much easier to write, test, and reason about than imperative code."

Absolute, that holds for non functional code as well.

It just does not matter whether the smallest function inside that system of functions has a loop or a map inside it. Loops are as easy to tuck into reusable functions as maps or anything else. Notably examples in the presentation you link have functional version shorter, but harder to read - they have more features however. Even the first one pipe(..., reduce(add, 0)) just does not read fluently.

But again, this low level has very little influence on maintainability of the larger program. In anything that is not computational library, how you compose them matters more. It is as if you assumed code with loops can not be split into smaller composable units.

I worked with codebase written in largely functional style. It was hard to read at first, but then I got used to it. However, it never became all that much easier to read them loops nor easier to work with. It gets bad when people get clever with composing functions.

Re:The State of Go by lewisl9029 on Monday February 06, 2017 @04:33AM (#13577936)
> It just does not matter whether the smallest function inside that system of functions has a loop or a map inside it. Loops are as easy to tuck into reusable functions as maps or anything else.

This is certainly true! You can definitely wrap all your loops in functions that take in a collection as argument, and return another collection or value, and as long as you don't produce any externally observable side effects with your loops, these functions are as good as any other as building blocks of a functional program.

Consider the age old adage: "If a tree falls in the forest and nobody hears it, did it actually fall?", similarly, "If a function mutates some internal state only visible within its own scope (a counter or accumulator in an imperative loop, for instance), did it actually mutate anything?" The practical functional programmer would answer with a resounding "no". In fact, RamdaJS itself is implemented mostly imperatively internally for performance/compatibility reasons, but exposes a functional API for the consumer. Similarly, Clojure is implemented the same way for many of its core functions, and exposes an easy way for users to perform mutations for similar purposes within the functional, immutable-by-default language using transients: https://clojure.org/reference/transients

If you use imperative loops by wrapping them in this way, however, note that you're essentially implementing the same function signature of a function that calls map/filter/reduce on a collection, but with imperative primitives, and that's definitely a valid approach. If you build your programs by writing and composing these kinds of functions, you are in fact doing functional programming, and can reap all the composability, maintainability, and testability benefits that come with it.

I don't think there's any room to debate that most developers don't use imperative loops in this way, however. And my point was that the way they're usually used was not trivially composable. Of course, you could always refactor them into small functions that are trivially composable, but that they need to be to become composable is why I prefer using trivially composable primitives like map/reduce/filter to implement my programs as a default, and optimize specific functions with imperative implementations on an as-needed basis after profiling and identifying all the critical paths (premature optimization, and whatnot).

RE: `var sumOfSquares = pipe(map(square), reduce(add, 0));` not reading fluently.

This is where we'll have to agree to disagree. To me that reads quite literally as "given a collection, return the square of each item, and add the result of each to the next, starting from 0, to return the final value". The functional approach could definitely look more intimidating to readers without any general knowledge of functional primitives and what they do, but that's an issue of familiarity, rather than one of inherent readability.

Yes, people can get crazy with nesting multiple inline composed functions inside of other inline composed functions on one insanely long line, and that can quickly get out of hand in terms of maintainability and readability, just as people can get crazy with nesting loops. But that's just a case of bad functional code that needs to be refactored using a composition of smaller, well-named functions broken down into multiple lines. Nobody is claiming functional programming is a panacea for bad code.

Re:The State of Go by solidsnack9000 on Sunday February 05, 2017 @06:24PM (#13575354)
It is not necessarily easy to recognize when a loop is a map or filter -- I think that's the issue. It's why someone like McSweeney would bring it up.

The Python approach -- where maps and loops share a lot of syntax -- is maybe the middle way. On the one hand, it's not an approach that gives rise to `.map()`, `.collect()`, `.flat_map()` and so forth; on the other, it's marked out as something returning a result.

Re:The State of Go by skybrian on Sunday February 05, 2017 @12:43PM (#13573469)
The preference for maps and folds looks like a fad to me. I can use them but I don't think it makes the code any easier to understand, just different.
Re:The State of Go by Groxx on Sunday February 05, 2017 @01:11PM (#13573610)
I dunno, ruby has some nice tendencies here, like `out = [1,2,3].map(&:to_s)` which is small and descriptive[1].

Compare that to:

    out = []
    [1,2,3].each do |x|
      out.append(x.to_s)
    end
IMO that's not fad material - that's progress. Maps and folds can totally be abused to produce inscrutable nonsense, but for small, common operations they're often much more obviously-correct.

[1]: `&:method_name` is extremely-common shorthand for "call this method"

Re:The State of Go by XorNot on Sunday February 05, 2017 @05:20PM (#13575021)
I had no idea what you were trying to do in the first paragraph whereas without knowing much ruby I can easily read the intent of the second.
Re:The State of Go by sheepmullet on Sunday February 05, 2017 @10:56PM (#13576377)
That has more to do with familiarity than anything else.

A tale of two cities is an easier book for an English speaker than Les Aventures de Tintin.

Map applies a function to each item in a collection.

As pseudo-code:

Collection.map(function)

And in the parents example we have:

[1,2,3].map(&:to_s)

The only Ruby specific part is &:.

Re:The State of Go by Cthulhu_ on Sunday February 05, 2017 @02:33PM (#13574091)
It does though. Maps and folds - and functional programming in general - focuses on the /what/. For-loops on the other hand tell the compiler / cpu the /how/.

Summing is a nice example. A naive for-loop will just iterate through the list, keep a variable around, add the next item in the list to it. In functional programming (or with a reduce), you tell it to sum in a more concise way - but more importantly, you don't tell the compiler how exactly it should do it. It's trivial with functional programming to make the task (for example) multithreaded or to use advanced underlying cpu tricks, without you as a developer needing to know how exactly it does what you ask it to.

Re:The State of Go by ridiculous_fish on Sunday February 05, 2017 @09:38PM (#13576124)
Consider product as a counter-example. With an imperative loop, it's easy to add an early-out condition if zero is encountered. But this is harder to do in a (strict) functional language.
Re:The State of Go by Athas on Monday February 06, 2017 @04:21AM (#13577868)
This is exactly why lazy evaluation is often described as control-flow. Lazy evaluation permits efficient composition, without doing extra work (although the constant factors become much larger).
Re:The State of Go by sagichmal on Sunday February 05, 2017 @04:57PM (#13574888)
Yes, that's exactly right. And Go takes a relatively strict stance on making the _how_ obvious to the programmer. It goes out of its way to avoid hiding O(n^k) loops behind language sugar like map or fold, for example.
Re:The State of Go by kibwen on Sunday February 05, 2017 @05:12PM (#13574975)
> O(n^k) loops

I'm unclear where algorithmic complexity is coming into this. Can you clarify what you're trying to imply?

Re:The State of Go by Scriptor on Sunday February 05, 2017 @07:25PM (#13575601)
map doesn't do any magic behind the scenes, it goes through a sequence exactly once.

Can you given an example where map might increase algorithmic complexity like that where the imperative version would not?

Re:The State of Go by sagichmal on Sunday February 05, 2017 @07:55PM (#13575727)
Map hides a loop behind a statement. That's all I meant.
Re:The State of Go by Scriptor on Sunday February 05, 2017 @08:34PM (#13575901)
You can hide a loop behind a function call in Go, Python, really any imperative language.

What makes map different is that it separates the looping mechanics (incrementing, initializing and appending to the collection) from the actual computation we want to perform on each element. It's just separation of concerns.

Re:The State of Go by sagichmal on Sunday February 05, 2017 @09:20PM (#13576074)
Yes. In Go, function and method calls are the primarily, perhaps only, mechanism of abstracting computational complexity. That is, when you see a function or method call, you know that "anything goes" back there, and you need to dig and find out what the computer is gonna be doing. Pretty much everything else is implemented "in plain sight"; in the case of fold/map, that means with a for loop, where you see precisely how many iterations you're going to step through.

You're right: map separates looping mechanics from computation. In Go, that's a bit too much obscurity.

Re:The State of Go by solidsnack9000 on Sunday February 05, 2017 @06:26PM (#13575359)
A 70 year fad.
Re:The State of Go by sidlls on Sunday February 05, 2017 @12:21PM (#13573336)
Maps and folds are implicit loops. For some explicit is simpler.
Re:The State of Go by Scriptor on Sunday February 05, 2017 @01:42PM (#13573778)
Maps are explicit transformations of data. For some, making the business logic explicit is simpler.
Re:The State of Go by solidsnack9000 on Sunday February 05, 2017 @06:27PM (#13575368)
Loops are just implicit goto...

The argument for maps and folds is the same as the argument for structured programming in general: using common/reusable idioms brings clarity and familiarity.

Re:The State of Go by sidlls on Sunday February 05, 2017 @07:55PM (#13575733)
Terseness doesn't necessarily bring clarity.
Re:The State of Go by solidsnack9000 on Sunday February 05, 2017 @09:19PM (#13576071)
It's the recognizability, not the terseness, that brings clarity.

Although Python's approach is not terse -- `fstyle = [f(x) for x in arr]` -- it is eminently recognizable.

Your argument is not really about anything I specifically said; and without something to counterbalance, it argues against structured programming, too.

Re:The State of Go by sidlls on Monday February 06, 2017 @01:07AM (#13576926)
How does it argue against structured programming?

My argument is that "recognizability" is in the eye of the beholder. One programmer's "map is a powerful abstraction over transforms, for example loops" is another's "this is some cutesy code/math creole by a CS graduate who desperately wants to find nails to apply his functional programming and applied math hammer on".

That's a fairly harsh way of saying that at some point the abstraction isn't clarifying, whether it's recognizable or not.

Disclaimer: I'm a big fan of functional idioms (they're one of my favorite parts of Rust, for example). I'm not so much a big fan of absolutism or over-generalization.

Re:The State of Go by mattnewton on Sunday February 05, 2017 @01:37PM (#13573743)
No, maps are conversions between types containing other types. Maps are much more powerful than just doing something over an array in languages that support a functional style.
Re:The State of Go by sidlls on Sunday February 05, 2017 @01:50PM (#13573827)
The original comment was comparing maps and folds to loops, not the general application of maps.
Re:The State of Go by tu7001 on Sunday February 05, 2017 @01:17PM (#13573624)
I don't know go, can't you write a map in it?
Re:The State of Go by mattnewton on Sunday February 05, 2017 @01:36PM (#13573731)
Not a type safe one that works on your own types.
Re:The State of Go by s_ngularity on Sunday February 05, 2017 @07:44PM (#13575683)
You can't define a polymorphic function map, but you definitely could definitely define a map method for your own monomorphic container type.
Re:The State of Go by user5994461 on Sunday February 05, 2017 @11:19AM (#13573012)
Java reigns supreme because there is nothing which come close to its characteristics in terms of capabilities, libraries supports, tooling, performances, easiness to learn, simplicity and maturity.

If you want faster or lower level, you gotta move to C++, which is uber-hardcore in terms of non-simplicity and impossible-to-learn.

If you want easier, you gotta move to python/ruby/node.js, which are a joke in terms of performance and concurrency, with the last 2 being fairly young and immature (< 10 years).

Either way, the tooling sucks compared to Java, if not entirely non existent.

Entreprisey development is on Java because that's what best for them. Web development is on something else because they pick what's cool and trendy.

Re:The State of Go by tyre on Sunday February 05, 2017 @11:43AM (#13573147)
Ruby came out in 1995, 22 years ago. It is neither young nor immature.
Re:The State of Go by user5994461 on Sunday February 05, 2017 @11:51AM (#13573189)
Of course I mean ruby on rails when I say ruby.

Initial release 2005. i.e. Young.

Re:The State of Go by closeparen on Sunday February 05, 2017 @11:58AM (#13573230)
Are you using Struts or something?

How could a 12-year-old framework not be old enough for you?

Re:The State of Go by jankiel on Sunday February 05, 2017 @12:41PM (#13573442)
Ruby on Rails is a web framework, not a language. Also web dev is about shipping a product fast, that's why you don't see Java there.
Re:The State of Go by closeparen on Sunday February 05, 2017 @03:28PM (#13574424)
You do see a ton of Java web apps in in-house and consultant-built line of business applications. Just not so much from product companies.
Re:The State of Go by watwut on Sunday February 05, 2017 @05:27PM (#13575060)
Once you know whatever java framework well enough and your project is not something ruby on rail spits out immediately, shipping fast is not a problem. In 4 months timeframe, you can definitely produce more or as much as with node.js or something like that.

The issue is that you wont do good frontend in it (obviously), java programmers are more expensive, learning it well enough so that you can actually be that fast takes a lot of time and hosting is way more expensive. Learning language itself is easy, but absorbing necessary frameworks takes time. Moreover, people who are good in frontend prefer languages similar to javascript, because they already know it very well so those are easier to learn for them.

I think this is why it does good in enterprise - they have money to throw at hardware, most projects are under huge time pressure constantly and requirements change constantly. Frontend is super important for product, but not so much for enterprise.

Re:The State of Go by baby on Sunday February 05, 2017 @02:57PM (#13574219)
How is Java easy to learn, you need a huge IDE, I don't know how many SDKs or dependables and two pass compilation and 1000 layers of abstraction, ...
Re:The State of Go by user5994461 on Sunday February 05, 2017 @05:12PM (#13574976)
Try these languages in order of ascending difficulty: C, assembly, Delphi, Ada, C++

After that, you'll understand that Java is on the spectrum of "easy" programming languages.

The IDEs are very helpful by the way. You only need one SDK, which is a single download.

Re:The State of Go by watwut on Sunday February 05, 2017 @05:30PM (#13575076)
Ide makes learning easier and faster instead of harder. You dont have to care about compiler passes, ide compiles seamlessly.

But yeah, learning java ecosystem well enough takes a lot of time for someone who is just starting and you have to be comfortable with abstract thinking.

Re:The State of Go by bsg75 on Sunday February 05, 2017 @04:09PM (#13574662)
That is due to maturity / age, and at one point Java was the new kid on the block.
Re:The State of Go by sidlls on Sunday February 05, 2017 @12:18PM (#13573323)
"Good" and "bad" aren't really useful descriptors without additional context. And what do you mean by "mid-quality" developers? That seems gratuitously insulting.
Re:The State of Go by throw2016 on Sunday February 05, 2017 @01:08PM (#13573590)
I think simplicity is often the most difficult to achieve and requires deep technical expertise to deliver. It shows the creators have thought about the end user and usage scenarios. It would be a mistake to confuse complexity with quality or vice versa.