News for hackers. Stuff that matters.
Re:Go is Google's language, not ours by bunderbunder on Wednesday May 22, 2019 @08:34AM (#19980435)
> Java has only things that were proved to work in other languages.

But they still somehow keep finding ways to make them not work so well when implemented in Java.

C# may move faster, but its design team is also much more methodical about ensuring that new features have good ergonomics. In Java, I tend to feel surrounded by hacks that were hastily slapped on in an effort to keep up with C# and, increasingly, Kotlin.

Re:Go is Google's language, not ours by Raidion on Wednesday May 22, 2019 @09:49AM (#19981116)
Idk, have you seen the interfaces with default implementations in latest C#? Also duck typing? Both are mistakes IMO. First missteps I feel like I've seen C# make.
Re:Go is Google's language, not ours by EpicEng on Wednesday May 22, 2019 @12:38PM (#19982913)
If by "duck typing" you mean dynamic, then I don't know what you're complaining about. It has a very niche set of use cases where it is needed. If people are abusing it then it's on them. There is no good or even alluring reason to use dynamic outside of it's intended purpose, so I don't feel like it's one of those "shiny hut dangerous" features you see in some other languages.
Re:Go is Google's language, not ours by bunderbunder on Wednesday May 22, 2019 @10:16AM (#19981419)
Fair point. I switched from C# to Java several years back, so I'm at least somewhat working from nostalgia for a certain point in time.

I look at the feature list in the latest iteration of the language, and my thought is, "Y'know, you really should stop when you're done."

Re:Go is Google's language, not ours by insertnickname on Wednesday May 22, 2019 @11:21AM (#19982160)
What duck typing? Are you talking about the `dynamic` keyword?
Re:Go is Google's language, not ours by JamesBarney on Wednesday May 22, 2019 @04:13PM (#19984976)
Why don't you like default implementations?
Re:Go is Google's language, not ours by emn13 on Wednesday May 22, 2019 @09:48AM (#19981099)
Hmm, I do a lot of C# programming, including very language-y low-level stuff, and I'm not sure I completely agree.

I appreciate that by moving faster they get more stuff into more hands faster, but they definitely have a lot of hackish solutions with poor ergnomics outside of the narrow scope they were originally intended for.

If you will: the language features have a clear purpose but a general implementation; and outside of the narrow purpose the designs usually feel pretty poor.

E.g.:

- LINQ/expression trees don't support most of the C# language, and new language features are usually without equivalent expression tree. This isn't a full lisp or F# style quotation, but a pretty narrow window that's not easy to use outside of linq-to-sql style usages.

- LINQ trees are again intrinsically inefficient, since the expression trees compile not to a statically shared expression, but to a bunch of constructors (i.e. looping over even a medium sized expression is bound to be slow); and they're not equatable, so it takes a lot of effort for a consumer to detect this case leading to overly complex (and hard to reproduce correctly) hacks inside stuff like EF.

- LINQ is restricted, but the restrictions are fixed, not customizable. That makes it a poor fit for DSLs, including stuff like Entity Framework, because there are usually lots of expressions your DSL can't support, but there's no way of communicating that to the user. Also, if you use expressions as DSL, you need to follow C# semantics, which isn't trivial; witness gotchas in ORMs surround dealing with null and equality.

- lambdas are either delegates or expressions; not both, and this isn't resolved via the normal type system, but by special compiler rules, making it hard to do both, and leading to type inference issues such as that var f = (int a) => a + 1; cannot compile.

- Roslyn: very poorly documented, and ironically very dynamically typed to the point that many casts or type-switches are necessary but finding out what types there are and what they do is generally a matter of trial and error since the docs aren't great. Ergonomics are poor in other ways too; e.g. dotnet is xplat, but the build-api is not - i.e. it's clearly not dogfooded. Also: totally not integrated with expression trees, which is at least mildly surprising.

- string interpolations are unfortunately quite restrictive (compare with e.g. javascript, where this was implememented much better), and intrinsically and unnecessarily inefficient (at least 2 extra heap allocations, and usually lots of boxing, and the parsing the compiler necessarily must do is not exposed in any kind of object tree, but instead reserialized to string.Format compatible syntax necessitating re-parsing at run-time). Also, like expression trees, this was really hacked into the language, so, e.g. you can't participate in other normal C# features like overload resolution the way you might expect, extension methods plain don't work, culture-sensitivity can be a gotcha: basically this works for immediately evaluated expression, but is tricky elsewhere.

- razor (not strictly C#) is hugely complex, and has a very impractical underlying model. Compared with e.g. JSX which is trivial is (ab)use creatively, and which uses mostly language-native constructs for control flow, razor makes it impossible to use even basic features like methods to extract bits of common code; lots of basic programming features are reimplemented differently. Instead of passing a lambda or whatever, you have to deal with vaguely equivalent yet needlessly different stuff like partials + tag helpers.

- optional parameters are kind of a mess (no way to enforce named args, no way to cleanly wrap optionals, restriction on compile-time constant, interaction with overloads can be suprising); tuples are too (names are dealt with differently than everything else in the language, no syntax for empty or 1-elem tuples, no way to interpret arg lists as tuples or vice-versa, no checks on nasty naming errors like swapping order); equality is a mess (how many kinds are there again?), lots of apis are disposable but should not be disposed but for others it's critical, no good way to compose disposables, huge ever expanding api without practical deprecation path is a pitfall for newbs, no partial type inference for generics, no unification of all the various func-and-action variations means billions of pointless overloads (and sometimes per-API ways around it); tuples and anonymous objects are sort of redundant, but not entirely; no good way of implementing equality/hashcode/comparability and yet easy way to detect misused non-equatable types.

I mean, I respect their choices here, and there's a tradeoff with lots of benefit too: they're really quite fast-moving, and I want those new features ;-). But it's not without costs; they definitely aren't "much more methodical" or anything like that.

Re:Go is Google's language, not ours by adamc on Wednesday May 22, 2019 @01:43PM (#19983532)
Uprated because you gave lots of specific examples. Too many conversations get vague fast.
Re:Go is Google's language, not ours by emn13 on Wednesday May 22, 2019 @03:04PM (#19984374)
Thank - I hope I don't come across as too bitter - I really do think there's an upside to all those limitations. I'm just past the exuberance of thinking that because it's so actively developed, that all these flaws are eventually fixable. It's a fast lifecycle, and probably at some point it'll be too impractical to continue as is, and then we'll just jump ship to some slimmed down alternate with a good transition story - and that's fine. So far: so good.
Re:Go is Google's language, not ours by pron on Wednesday May 22, 2019 @01:50PM (#19983599)
C# has made some serious mistakes: reified generics (which has basically destroyed simple language interop on the CLR and makes it an unattractive target for language implementors), and recently, async/await. Both of these help in some ways, but have costs that are higher than the benefit and much better alternatives.

Java is not trying to "keep up." It is intentionally slow-moving and conservative (this design goal was set by James Gosling when Java was first created), and only adds features once they have been proven in other languages for a while.

Re:Go is Google's language, not ours by pjmlp on Wednesday May 22, 2019 @02:41PM (#19984146)
As former Java dev, returned into .NET world, I don't consider it a mistake, the CLR was designed with multiple languages in mind, and there are plenty of options available, even if Scala devs failed at that.

On the other hand, what I consider a major mistake from Java side was ignoring value types and AOT compilation since it's inception.

Had Sun blessed such features since the beginning, and many use cases for C and C++ wouldn't be necessary.

Re:Go is Google's language, not ours by pron on Wednesday May 22, 2019 @03:02PM (#19984356)
Value types add complexity and they weren't necessary in 1995. They only became necessary due to hardware changes circa 2005. Similarly, AOT compilation has only become attractive for the kinds of applications people use Java for only recently, when startup time became important for serverless. The lack of neither has caused Java lasting damage; what has is the domination of the browser on the client, but that has affected all languages.

As to baking variance into the runtime, I think this is just a bad idea, which is so far used only in C++ and .NET, two languages/runtimes with notoriously bad interop (it's not just Scala; Python and Clojure have a similarly bad time on the CLR, as would any language not specifically built for .NET's variance model). It is simply impossible to share a lot of library code and data across languages with different variance models once a particular one is baked into the platform. This is too high a price for a minor convenience.

Specialization for value types (which are invariant), is another matter, and, indeed, it is planned for Java. Perhaps some opt-in reification for variant types has its place, but not across the board. I am not aware of other platforms that followed in .NET's misplaced footsteps in that regard. Those that are known for good interop -- Java, JS and LLVM, don't have reified generics.

What's worse is that it's a mistake that cannot be unmade or resolved at the frontend language level. Even Java's big mistakes (like finalizers, how serialization is implemented, nullability and native monitors) are much more easily fixed.

Re:Go is Google's language, not ours by emn13 on Wednesday May 22, 2019 @03:15PM (#19984473)
Value types aren't "necessary", but they would have been valueable at day 1. The GC heap is simply inefficient; not necessarily because of the GC (which indeed is harder with massive multicore), but simply because of the per-object memory overhead.

There's a reason java had built-in value types from day 1, because it made sense even back then.

Frankly, I think both java and C# kind of got this wrong. There was an overreaction against the C/C++ of the day, and whereas the GC turned out brilliant, the idea that it's not even necessary to express the notion of references/pointers/values etc. was too much; and the idea of a single type system root (object) is similarly dubious, and then particularly the idea that that root type isn't the empty type. Object has semantics, and that was a mistake, because it contributes to the bloat. I'm totally happy with ignoring those features 99.9% of the time, but having them completely unavailable makes those 0.1% cases extremely expensive. (I mean, I think those things are slightly changing, but it's slow going).

Re:Go is Google's language, not ours by pron on Wednesday May 22, 2019 @04:10PM (#19984951)
> because it made sense even back then.

That was necessary for performance back then. User-defined value types weren't, and Java has done well without them.

> Object has semantics, and that was a mistake, because it contributes to the bloat.

I think most of the RAM bloat is due to the GC trading off extra RAM for speed rather than object headers, and I'm not sure trading off complexity for headers was right 25 years ago (JS is doing fine on the client without value types). What changed was the performance characteristics.

As to object semantics, it may be a fixable mistake. The goal is to get value types without today's object semantics while preserving a single class hierarchy at the same time. The Valhalla team thinks that's achievable.

Re:Go is Google's language, not ours by emn13 on Friday May 24, 2019 @02:46AM (#19999075)
Heap (over)use by the GC is effectively a scaling factor. How large the underlying objects are remains remains relevant: if your objects are twice the size necessary, the GC will "bloat" that further - and this tradeoff isn't entirely GC specific, other allocators such as those used to implement malloc/free have related tradeoffs to make; free() won't release memory to the OS either (and memory, released or not, may end up evicted from RAM anyhow).
Re:Go is Google's language, not ours by pron on Friday May 24, 2019 @08:21AM (#20000709)
Of course it is relevant. I'm just saying it isn't the decisive factor that makes this an absolute necessity, as evidenced by the fact that much the backbone of the largest software services in the world is Java. There are lots and lots of tradeoffs in runtime design, and it's important to look at the whole rather than at one decision in isolation and point out that it's important. As a whole, the criticality of value types for Java is relatively recent.
Re:Go is Google's language, not ours by pjmlp on Thursday May 23, 2019 @12:42AM (#19988547)
I advise you to read Mesa/Cedar report on the impact of garbage collection algorithms available at Xerox PARC bitsavers archive, EthOS or SpinOS experience with Modula-3.

All of them refer that having value types alongside GC had a relevant impact improving performance.

All systems designed before Java was a thing.

Or since you refer to JS, the paper about SELF's design.

Even Dylan was designed with AOT/JIT and value types support, which is relevant here given that its domain was being a systems language for the Newton. That politics killed it is another matter.

Re:Go is Google's language, not ours by pron on Thursday May 23, 2019 @06:50AM (#19990463)
Oh, I don't deny that value types would have helped performance back in '95, just that they were absolutely essential for Java. Smalltalk/Self and Scheme/CL didn't have them, and those were probably Java's greatest influences; I don't think VB had them, either. Also, in its first four years, before HotSpot was ready, Java was interpreted, so it had bigger performance problems.

I don't know why there was no emphasis on AOT back then. I guess they started with interpreter/JIT, and then there just wasn't much demand for AOT until now.

Re:Go is Google's language, not ours by pjmlp on Thursday May 23, 2019 @07:25AM (#19990651)
Microsoft Basics have support for value types since MS-DOS.

QuickBasic supported value types and AOT to native code, and while Visual Basic used P-Code, version 6 introduced a proper AOT native compiler.

Modula-3 was also a big influence, at least accordingly to some papers.

There was surely demand for AOT, given that most commercial JVMs had it in some form or the other since 2000.

Even Sun actually supported it in Java Embedded variant for OEMs, probably grudgingly.

Common Lisp certainly has support for value types.

Re:Go is Google's language, not ours by pron on Thursday May 23, 2019 @08:56AM (#19991239)
What user-defined value types did CL have in '95? Also, are you sure about VB having had them then?

As for AOT, there may not have been sufficient demand from Sun/Oracle. I only joined relatively recently, but we generally do expensive things only if we believe they have a huge benefit or in huge demand, and we believe it can be long-lasting. The assumption is that any new feature will require maintenance for 20 years, taking away resources from other things. So if something is expensive, even if it's cool or some people could find it very useful -- we don't do it. The assumption is that the ecosystem is large enough that others can, and will.

Re:Go is Google's language, not ours by pjmlp on Thursday May 23, 2019 @09:19AM (#19991464)
Arrays, structs, fixnums, explicit stack allocation.

I can check the respective manuals if you wish.

Yep, I did VB programming for a short while.

And please note that even though my focus is now elsewhere, Java is one of my favourite eco-systems.

As a peasant I just wished that Java 1.0 was more like Go, given the existing alternatives back then.

So it kind of stayed as a pet peeve of mine.

Same applies to .NET, just in a different way.

Re:Go is Google's language, not ours by pron on Friday May 24, 2019 @08:27AM (#20000750)
Well, we can disagree about when AOT and value types became critical for Java (and I would argue that they clearly weren't back then because Java has done spectacularly without them), but Java is getting both soon.
Re:Go is Google's language, not ours by pjmlp on Friday May 24, 2019 @09:47AM (#20001384)
I would say that it had other factors that contributed to its sucess, so it succeeded in spite of lacking those features.

However due to the hardware architecture changes and new kids on the block, it is starting to be an issue.

I keep wishing to see them arrive, have watched all the JVM Language Summit, Devoxx and JavaONE talks about them.

Meanwhile I can already enjoy them elsewhere. :(

Re:Go is Google's language, not ours by pron on Friday May 24, 2019 @11:32AM (#20002597)
> Meanwhile I can already enjoy them elsewhere. :(

That's perfectly fine. We think that our priorities are right for the workloads Java is used for (e.g. people care more about a low-latency GC like ZGC, and deep low-overhead in-production profiling, like JFR, than about AOT).

Re:Go is Google's language, not ours by pjmlp on Wednesday May 22, 2019 @03:35PM (#19984664)
C# got it right from day one, regarding value types.

AOT compilation not so much, given the NGEN constraints.

However they got it both wrong, considering CLU, Modula-3, Delphi and Eiffel are considered influencial languages on their design.

Re:Go is Google's language, not ours by pron on Wednesday May 22, 2019 @04:13PM (#19984975)
Mutable structs are not exactly value types, but Microsoft has always preferred control over simplicity (after all, they pushed C++ really hard). I won't say whether that philosophy is right or wrong, but it is very different from Java's.
Re:Go is Google's language, not ours by pjmlp on Wednesday May 22, 2019 @03:30PM (#19984619)
In 1995 I was enjoying Oberon, Component Pascal, Eiffel and Delphi.

Value types were pretty much obvious as necessary.

More so when one dives deep into how languages like CLU and Mesa/Cedar were designed.

Having a AOT support doesn't preclude having a JIT as well, like Common Lisp or Eiffel already had in 1995.

Re:Go is Google's language, not ours by pron on Wednesday May 22, 2019 @04:17PM (#19985012)
There's a difference between useful, and even very useful, and absolutely necessary. Clearly value types weren't absolutely necessary, as Java did well without them (and JS still does).

Gosling said that his goal was to have nothing you can somehow live without (I don't know how well early Java lived up that ideal, but that was the ideal). Hardware changes made user-defined value types absolutely necessary for workloads Java wants to target.

Re:Go is Google's language, not ours by pjmlp on Thursday May 23, 2019 @12:26AM (#19988469)
Being there since the beginning, I wrote my first Java game in 1996, early Java only did well thanks to Sun's marketing weight and it being free beer vs the alternative of having to pay for a compiler like Delphi.
Re:Go is Google's language, not ours by pron on Thursday May 23, 2019 @06:57AM (#19990491)
I was around, too, and I don't think that was at all the full story. Marketing has never been solely responsible for the long-term success of any product. There were other languages that were very heavily marketed: VB and C++ (and FoxPro, too, I think) by Microsoft, Delphi, and about a million other RAD tools. Being free was one of the reasons, but so was targeting the web, and Gosling's design of wrapping a JVM that gave people what they wanted (dynamic linking, fast compilation, garbage collection) wrapped in a language that felt familiar and non-threatening. I don't remember what were Delphi's issues, but a big project I wasn't involved with at the same organization I was working at circa 2002 (I was all C++ back then) did Java on the server and Delphi on the client. Maybe Delphi didn't have a good server-side story?
Re:Go is Google's language, not ours by pjmlp on Thursday May 23, 2019 @07:26AM (#19990656)
It sure did, as long as you were a Windows shop.
Re:Go is Google's language, not ours by 0815test on Thursday May 23, 2019 @07:30AM (#19990679)
No need for Windows. There was an official Linux implementation back in the day, codenamed Kylix.
Re:Go is Google's language, not ours by pjmlp on Thursday May 23, 2019 @09:21AM (#19991483)
Kylix was full of issues and was a mismanaged product variant, largely ignored.

If I recall correctly it even depended on WINE.

Re:Go is Google's language, not ours by apta on Wednesday May 22, 2019 @05:10PM (#19985539)
> and native monitors

Are there any plans to fix those?

Re:Go is Google's language, not ours by pron on Wednesday May 22, 2019 @05:29PM (#19985731)
Some ideas; nothing concrete. Need to figure out cost/benefit.
Re:Go is Google's language, not ours by dirkg on Wednesday May 22, 2019 @03:43PM (#19984726)
async/await is fantastic and pretty much the direct inspiration for the exact same feature om ES6, where its a godsend.

C# i s one of the best dev experiences in any language/IDE

Re:Go is Google's language, not ours by pron on Wednesday May 22, 2019 @04:36PM (#19985178)
Async/await is fantastic compared to not having anything at all. It's a big downside compared to other things you can do (cf Go, Erlang), and hard to get rid of. It's the classic case of getting easy short-term benefits at the expense of long-term costs. It's main benefit from an implementor's perspective is that it's better than nothing and very cheap to implement quickly. Just as .NET has lived to regret reified generics[1], it will live to regret async/await.

[1]: Maybe not C# programmers, but there are easier ways to do a single-language runtime.

Re:Go is Google's language, not ours by DaiPlusPlus on Wednesday May 22, 2019 @06:45PM (#19986393)
The other main alternative to `async/await` with the Promise<T>/Task<T>/future<T>-paradigm is Rx's Observable - but let's not pretend that because Observable<T> is capable of handling every situation that Promises can doesn't mean we should use it everywhere - Angular tried that when they changed their HTTP client library to use Observable<T> instead of Promise<T> because they wanted to expose retries and other nifty logic - but in doing-so made the learning curve a vertical brick-wall for everyone involved (and now we can use Promise<T> with support for retries and better error-handling anyway) in addition to adding a very hard dependency on a fast-moving project (e.g. Angular 6 comes with a load of RxJS compatibility shims because RxJS radically changed their API design (again)).

Go's goroutines seem okay - but I don't like how much control they take away from the programmer. For example, last year I worked on calling-into a black-box C DLL from a Go program and we learned the C DLL had code that was actually simply terminating the thread inside of it (by design!) because the author of the C DLL assumed ownership of the thread. That caused a problem for us because Go's goroutines are scheduled by the Go runtime and it will never let you give-up ownership of a Go thread - and I couldn't see how I could use my own thread (e.g. getting a thread from a native OS call to keep it outside of Go's control) with goroutines. The project was almost DOA after we learned this, fortunately we convinced the author to always return instead of killing the thread. I'm not sure if anything's changed in Go since then that would have made things easier for us. But since then we haven't used Go for anything new. The only reason we used Go was because it gave us binaries that "just worked" for Windows, macOS and Linux without having to worry about Java, .NET and other dependencies - but I wasn't happy about the ~20-30MB-sized executable output.

Re:Go is Google's language, not ours by pron on Wednesday May 22, 2019 @07:15PM (#19986645)
What we're doing in Java is letting you choose, for each sequential computation, whether you want a heavyweight (kernel) thread or a lightweight usermode thread (like a goroutine), and if you choose the latter, you can use your own scheduler (schedulers are written in Java, and aren't a part of the runtime). No promises, no observables, no async/await, and no thread control issues.