5 ms·
This is the same thing that happened in Java. Other languages started prototyping features... that eventually just end up being implemented in Java.
by WrtCdEvrydy 8y ago
This is the same thing that happened in Java.
Other languages started prototyping features... that eventually just end up being implemented in Java.
- int_19h 8y agoJava did it way too slow, and that is a significant contributor to it being relegated to "legacy" in many areas. If it waited for the other languages to prototype stuff, it might have not been the case. The problem is that it waited for them to prototype it, refine it, release it, popularize it, and for their community to adopt it, before even starting to work on it in Java - which means that by the time they had it, most people who needed it were already elsewhere (not necessarily off JVM, just another language). Lambdas were a very good example - if you look at the closest competitor, C#, it got the first take on them back in 2005. Then a major refinement in 2008, adding type inference. By 2010, lambdas were idiomatic in C#. Java, in contrast, released the first version in 2014. And even then, they're still less powerful.
- kjeetgill 8y agoHuh. I didn't know they worked any differently in C#. In what ways are they less powerful in Java?
- int_19h 8y agoFor example, in Java, lambdas cannot capture mutable variables from the outer scope - it must be final, or effectively final. C# always let you do that, from the very first implementation of lambdas.
- eropple 8y agoC# lets you do that because C# doesn't have a way to declare a local readonly/final variable at all. I significantly prefer features that encourage the use of `final` variables everywhere that it is possible in Java. I write C#, Java, and Kotlin in roughly equal measure. Each has its pluses. But the claim that Java's lambdas are worse because it doesn't let you--and this was a conscious design choice!--do something so potentially catastrophic and difficult to debug is an odd one.
- manigandham 8y agoI rather be able to do something than be prevented because someone somewhere thinks that it's "potentially catastrophic". That seems especially hyperbolic in this case.
- kjeetgill 8y agoTo each their own, but I can second that most Java programmers find that ability horrifying and if it came to a vote would probably get it ejected.
- int_19h 8y agoDo Java programmers find mutable variables in general horrifying? That was not my impression - certainly, the language doesn't make it easy to make everything immutable. If so, why the special distinction for lambdas? The official rationale was that they expected lambdas to be mostly used for parallel sequence processing, and wanted to avoid race conditions. Of course, in practice, lambdas are very useful in many other places, where there's no concurrency issue at all - async continuation callbacks, for example, or pseudo-custom language constructs implemented as functions with a lambda for a body.
- int_19h 8y agoC# could do the "effective final" rule, same as Java did - don't allow a variable to be closed over if it's mutated anywhere. And yet it didn't - which made implementation that much more complex, since capturing mutable locals requires lifting them to extend lifetime.
- chrisseaton 8y agoWhat’s the memory model for captured variables being mutated by multiple threads?
- kjeetgill 8y agoYea, that seems frightening. I like to think of my local variables as my inaccessible local state. I'd imagine it keeps my JIT happy too. What would it even mean to have a lambda reference to a variable who's stack frame has already popped?
- chrisseaton 8y ago> What would it even mean to have a lambda reference to a variable who's stack frame has already popped? That bit is simple - the variable is kept alive as long as there is still a lambda that references it. Don’t think about stacks - that’s an implementation detail and the compiler is free to use a combination of the stack and the heap to implement local variables. The issue I’m talking about is if one thread writes a local and another reads it, what does that look like?
- int_19h 8y agoThe same memory model as any other shared variable being mutated by multiple threads - you either explicitly synchronize, or you just don't do it. But given that lambdas are far from the only way to get there - and those other ways are already idiomatic in the language (e.g. statics) - why single out lambdas specifically for this? The ideal solution is to make this a part of the function type - so that APIs that do intend to invoke lambdas concurrently can mark them as such, and then the language would enforce sharing, while other APIs that do not use lambdas in a concurrent context, can use their full power. Same thing goes for lambdas that cannot escape vs those that can - if you reflect this in the type system, then you can also support safe nonlocal breaks and returns in the former, for example. One of the early Java lambda proposals, the one by Neal Gafter, did just that, and it was awesome.
- chrisseaton 8y ago
- vvanders 8y agoYeah, or value types. Still waiting on those...
- pjmlp 8y agoYou can use the extensions in IBM J9 or Azul, just like some use GCC C while claiming it is C. :) Also looking forward to them and disappointed they weren't there since the beginning.
- pjmlp 8y agoLooking around the office and my phone, Java is anything but "legacy". As for alternative JVM languages, while they are cool and have brought many fresh ideas into the platform, they remain a very tiny portion of the Java developers' market. Java takes a very long time, because backwards compatibility and cooperation among giant companies takes years. C# has basically Microsoft deciding how the roadmap looks like and rebooting the platform multiple times. C# 8 won't even be fully supported on the .NET Framework.
- manigandham 8y agoRuntimes are different from languages. The C# language has never been rebooted and is fully backwards compatible, and there's no better example of long-term support than Microsoft. You can still run apps from the MSDOS era, and even upgrade MSDOS through to Windows 10 if you have all the CDs today.
- pjmlp 8y agoRuntimes and languages go hand-in-hand, a runtime that doesn't support everything that one expects from the standard library breaks compatibility. Code starts getting full of #ifdefs Siverlight, .NET Core, WinRT, UWP just to give three reboots. No support for dynamic APIs, appdomains, IL generation on the fly, reflection APIs done in a different way, ... Actually C# is not fully backwards compatible, variables declared on foreach statements changed their semantics in C# 5. https://blogs.msdn.microsoft.com/ericlippert/2009/11/12/closing-over-the-loop-variable-considered-harmful/ https://blogs.msdn.microsoft.com/ericlippert/2009/11/12/clos... MS-DOS is only supported in 32 bit variants, a species in extinsion.
- general8bitso 8y agoSo, like DOS 3.3 to 5 to 6.2, and Windows 3 to 3.1, to 95 to 98 to 98SE, to ME, to XP, to 7, to 8 to 8.1, to 10? I think I was using floppies until Win 98?
- manigandham 8y agoHere's a 10 hour video from DOS to Win10: https://www.youtube.com/watch?v=l60HHWWo9z4 https://www.youtube.com/watch?v=l60HHWWo9z4
- imtringued 8y agoA lot of useful features don't end up being implemented in Java and even if they do, libraries and frameworks have to update to take advantage of them. With a new language libraries are built from the ground up based on the new features. For example adding async to the language isn't necessarily going to change your programs to be async because every widely used library has already adopted threads and doesn't support async yet and often never will.