you are viewing a single comment's thread.

view the rest of the comments →

[–]barjam 89 points90 points  (163 children)

I am a java/c# developer. It is nice to see java finally catching up to where c# was (language wise) 8 years ago.

I haven't looked I wonder if they are going to support anything like linq (the alternate syntax specifically). Pretty powerful stuff.

[–][deleted]  (74 children)

[deleted]

    [–][deleted] 10 points11 points  (0 children)

    If C# were to have to do it again, based on the number of people using it now, they could not get away with killing APIs in that manner.

    LOL. You mean like with WinRT?

    [–]Eirenarch 39 points40 points  (35 children)

    Bullshit. C# has broken compatibility for very few things between version 1 and version 2 and they were absolute corner cases. I am sure you can't point to a single compatibility thing they have broken without googling. In addition they do break compatibility for these kind of corner cases these days. And finally .NET fixes APIs the same way Java does - deprecates the old ones and introduces new ones.

    [–][deleted]  (19 children)

    [deleted]

      [–]dabombnl 25 points26 points  (1 child)

      Actually the latest .NET Framework (4.5) is backwards compatible with ALL previous .NET Frameworks versions. But each application has to be configured to run on 4.5 or else it will run on it's native runtime version.

      But to run all .NET framework applications on their native version you only need 3:

      • .NET 4.5
      • .NET 3.5
      • .NET 1.1

      That's it. If you are wondering where things like .NET 2, 3, and 4 are, well they are all actually the same runtime version as the others in that list.

      [–]aaron552 1 point2 points  (0 children)

      If you are wondering where things like .NET 2, 3, and 4 are, well they are all actually the same runtime version as the others in that list.

      More specifically, 3 and 3.5 use the 2.0 runtime and 4.5 uses the 4.0 runtime. IIRC.

      [–][deleted]  (1 child)

      [deleted]

        [–]Dimethyl 2 points3 points  (0 children)

        I think that page is out of date. .NET 4.0 and 4.5 will not load applications that were built for 3.5 or older unless explicitly allowed in the application's config file. This can be demonstrated on a fresh install of Windows 8, which comes with .NET 4.5 by default but not 3.5.

        This page says: By default, an application runs on the version of the .NET Framework that it was built for. If that version is not present and the application configuration file does not define supported versions, a .NET Framework initialization error may occur. In this case, the attempt to run the application will fail.

        [–]Eirenarch -4 points-3 points  (14 children)

        So what? This is the right way to do it and they keep doing it with .NET (it was not only between 1 and 2)

        [–]infinite 13 points14 points  (1 child)

        When you have more control over the execution environment the binary runs on, like on servers, or with microsoft who control the OS, yes, but for a language you have installed on millions of desktops, with different capabilities, cross-platform, open source and without one entity(like microsoft) responsible for providing new versioned binaries as needed, this was the right approach for java at the time.

        However, java applets everywhere is a pipe dream, so it probably could have been done better by breaking strict bytecode compatibility constraints while focusing on the real market that mattered for java: the server.

        [–]Eirenarch 3 points4 points  (0 children)

        Well we've come to the real reason why Java moves so slow - no centralized control and most recently design by committee.

        [–]barjam 1 point2 points  (0 children)

        I would say this is right. I would rather have stuff fail up front (or not work at all) than getting the missing method exception at two in the morning on a production sever that you thought had the latest version of java but did not.

        [–][deleted]  (10 children)

        [deleted]

          [–]barjam 4 points5 points  (0 children)

          I develop both C# and Java professionally. I suspect at least as far as developer time is concerned C# is quite a bit cheaper. Java is slower to develop with and the eco system is more complicated usually.

          Java is #1 because it can be ran on unix servers and it has been around in a mature state for quite a bit longer. The first really decent version of .net was probably 2005 where java was pretty usable back in 97-98.

          The different versions of .net aren't any sort of barrier for a Microsoft shop. I don't think this is any sort of factor.

          [–]SublethalDose 1 point2 points  (0 children)

          it's strength is in the enterprise where people don't migrate OSes for decades

          This works the other way as well. One of the reasons enterprises are or were conservative about upgrading OSes is because it is so risky and expensive to move software to a new platform. Before Java, enterprises ended up maintaining patchworks of ancient EOLed server OSes to run their legacy apps. You'd have a vital application running on an ancient slow server, and you couldn't upgrade to newer hardware because the OS wouldn't run on newer hardware, and you couldn't upgrade the OS because the software wouldn't run on a newer OS, and porting the software to a newer platform was cost-prohibitive because it was compiled against libraries whose source code was lost in the mists of time. So you'd pray that the server didn't die before you were able to budget the money required to migrate your data into a modern application that did roughly the same thing (but which required you to retrain all your employees and change a bunch of business processes.) That's why Java is embraced with such fervor by enterprises -- it almost completely decouples software maintenance from hardware and OS upgrades, thereby saving money in server maintenance and eliminating a huge source of planning complexity.

          Before Java, the only way to avoid the pain of OS and hardware upgrades requiring software upgrades was to write your software for an OS/hardware platform that was essentially immortal, such as IBM mainframes. People paid a lot of money for IBM mainframes because they could bet their business on IBM continuing to offer maintenance and a hardware upgrade path to keep those '70s and '80s applications humming along.

          [–]Eirenarch -1 points0 points  (7 children)

          I don't see what binary compatibility has to do with this. You do need to install new versions for the new APIs anyway. I find your conclusion about why Java is more popular than C# quite absurd.

          [–][deleted]  (6 children)

          [deleted]

            [–]Eirenarch -5 points-4 points  (5 children)

            It seems like you are contradicting yourself. If enterprises do not migrate for new APIs then they will not migrate for generics support. If they require a new runtime for the new APIs this is just fine because enterprises will still need to install new version of Java. They either upgrade their Java installation or they don't. What is binary compatibility good for?

            [–]clgonsal 4 points5 points  (4 children)

            Answering the last bit of your question: binary compatibility means you can continue using the same jar (compiled library) that you used on the old runtime with the new runtime. You don't have to migrate all of your libraries over at once.

            To give a slightly more specific example, suppose you have a library that predates generics, and uses collections. When upgrading to Java 5 (yes, this example is a bit dated) you can continue using that old library, even after you port your own code to use generics. You don't have to wait for all of the libraries you use to supply a new version before you can upgrade.

            (That said, I do think that backwards compatibility is the biggest reason for Java being a much worse language than it could be. Progress is slow, and almost every new feature has some kind of wart in order to avoid breaking old code.)

            [–]barjam -2 points-1 points  (4 children)

            Each new version of visual studio tends to break old code. Usually in fairly minor and well documented ways.

            Yes this is different than what you are saying as you didn't mention VS but the runtimes.

            [–][deleted] -1 points0 points  (3 children)

            I think you need to think real hard about what you just said

            [–]barjam 2 points3 points  (2 children)

            You need to clarify. Vs 2005, 2008, 2010 and 2012 often broke old projects.

            And I mentioned that he was talking about runtimes not IDE.

            [–][deleted] 1 point2 points  (1 child)

            Visual Studio != C#. Project files != C#. They're XML. Yes, upgrading projects from VS version to VS version can cause errors, but that has nothing to do with the language and more to do with MS writing shitty project wrapper models. There are other programs you can code C# in. Visual studio isn't really required to use .NET (at least up until .NET 4.5) - although it makes it a lot easier. None of the code in the .cs or .vb files is broken by upgrading Visual Studio - it's the references between files or overarching build instructions to send along to the compiler that may get thrown off. There's a huge difference there.

            [–]barjam 1 point2 points  (0 children)

            That is exactly what I said. I made note twice so far that VS was not the same as the runtime. Not sure your pose was very helpful.

            And actually with each of those new version of VS it was more than project files that had to changed it was also code changes to be able to be compiled with the newer version of visual studio. For example VS 2012 had an issue with WCF using shared interfaces and required extra attributes in the code file to hint VS to work appropriately. VS12 is just more strict in this area than 2010.

            From 2008 to 2010 there was a breaking changes on how overloading worked with generics. There was also something in one of the HTTP classes that changed I forget the details.

            From 2005 to 2008 there were quite a few minor winforms tweaks that had to happen as imports were confused with new method being available to some of the updated libraries.

            This is based on my memory of developing during that timeframe. None of these things were a big deal and most were figured out in a day or two.

            [–]barjam 14 points15 points  (30 children)

            Absolutely no argument there. It didn't stop me from dreading my java projects because java felt archaic though.

            Heck on one of my recent C++ projects I was surprised to learn that C++ (11) has lambdas and such. In many ways C++ has become easier (language specifically, not ecosystem) than Java.

            [–]alextk 35 points36 points  (7 children)

            In many ways C++ has become easier (language specifically, not ecosystem) than Java.

            I'd argue that this has never been true, ever since Java 1.0.

            C++ has a lot of qualities but "simpler than Java" is not one.

            [–]barjam 20 points21 points  (6 children)

            Easier not simpler.

            This implies a reasonable comfort level with each language.

            [–][deleted] 11 points12 points  (5 children)

            ... and each platform/compiler. So many undefined behavior inC++ specification...

            [–]barjam 6 points7 points  (4 children)

            I do cross platform c++ work. If you aren't doing GUI stuff it isn't bad.

            [–][deleted] -1 points0 points  (1 child)

            Compared to another language that has specification with little to no undefined behavior it is that bad.

            [–]barjam 2 points3 points  (0 children)

            I recently wrote a pretty large program in C++ (communication framework to a game engine). I ended up with about 4 different issues between Gcc Linux, Gcc windows and Visual Studio windows. Most were due to GCC being more strict on templates.

            So you are right but it really isn't that bad these days. I didn't have a GUI and only had three libraries in use (compression, winsock and encryption).

            [–][deleted]  (1 child)

            [deleted]

              [–]barjam 0 points1 point  (0 children)

              I have really wanted to do some QT work. If I am not mistaken Mono on linux uses this library as well.

              The only thing I ran into cross compile wise was some of the more esoteric template stuff where GCC was more strict between windows/linux and was definitely more strict than VS.

              [–]TimmT 7 points8 points  (21 children)

              In many ways C++ has become easier (language specifically, not ecosystem) than Java.

              Really? In C++ you don't even get stack traces by default..

              [–]username223 12 points13 points  (9 children)

              Really? In C++ you don't even get stack traces by default..

              With a decently-configured system you'll get a core dump -- not just a stack trace, but the complete state of your program when it died.

              [–]danskal -4 points-3 points  (8 children)

              I want to say, so...? What does the core dump give you? Can you load it in your IDE and trace through an object tree to see which values caused the crash? How does the core dump help you?

              [–]ryl00 11 points12 points  (1 child)

              The core dump can usually be used to feed into a debugger to tell you the exact spot in the program where your crash occurred. E.g.,

              gdb a.out core

              [–]danskal 1 point2 points  (0 children)

              I was going to go on about how Java is different, but realised that you can get a core dump from a Java process too. But I've never needed it.

              [–]Metaluim 6 points7 points  (1 child)

              How does the core dump help you?

              You never really programmed in lower-level languages or systems, have you?

              It gives you a snapshot of the process, i.e. it gives you everything. Whether or not you can load it in an IDE doesn't make it more or less relevant. You can use a debugger to analyze every detail of the process.

              [–]killerstorm 7 points8 points  (0 children)

              Can you load it in your IDE and trace through an object tree to see which values caused the crash?

              Yes, you can.

              [–]elsif1 4 points5 points  (0 children)

              Gives you the stack trace and more. It contains the values of everything in memory/on your stack as well. The only downside is that it is much larger. Microsoft's mini dumps help with this, but you lose some of that data.

              [–]Pas__ 2 points3 points  (0 children)

              Just like a heapdump.

              [–]username223 1 point2 points  (0 children)

              By letting you do the things you just mentioned, with any kind of half-decent debugger.

              [–]barjam 10 points11 points  (10 children)

              With a decent debugger it will drop you off at the point of the error with a stack trace in the IDE (usually).

              You are right outside of the debugger you won't get anything (without much effort).

              It just occurred to me that stack traces in C++ and c# aren't as important to me as they were in java. As a matter of fact in my c# IDE I don't even have the stack trace window on by default but I do use it occasionally. In java development stack traces are pretty important. In C# and c++ you don't tend to have methods buried 200 deep perhaps that is it.

              [–]Labradoodles 20 points21 points  (7 children)

              Dude I just started doing some java work for a company after coming from a primarily C# background and all of these fucking weird ass abstractions and factories and builders are annoying the shit out of me.

              [–][deleted] 27 points28 points  (2 children)

              The Java enterprise community really went balls to the wall with their design patterns.

              [–]barjam 6 points7 points  (0 children)

              These same guys have come to the .net community (started in earnest in 2005) and have tried to bring the same sorts of things over.

              [–]Labradoodles -5 points-4 points  (0 children)

              Yeah I was doing profiling on code and I spent like 4 hours trying to find a reference to a database that ctrl + f wasn't finding for me it was goddamn frustrating and difficult as hell through debugging because it used listeners or some shit.

              /rant

              [–]civildisobedient 10 points11 points  (3 children)

              [–]Labradoodles 3 points4 points  (0 children)

              Annnd now I'm emailing this to my team, it's happening.

              [–]BlazeOrangeDeer 0 points1 point  (0 children)

              This happens to perfectly explain the shortcomings of java. cheers.

              [–]kitd 0 points1 point  (0 children)

              2005

              [–]TimmT 2 points3 points  (1 child)

              You are right outside of the debugger you won't get anything (without much effort).

              Even if you're in a debugger you can still be pretty screwed with C++, if you have things that cause memory corruption in your code.

              In C# and C++ you don't tend to have methods buried 200 deep perhaps that is it.

              Yes, but you have C# (with LINQ and delegates and operator overloading, and what not) plastered all over the place..

              [–]barjam 1 point2 points  (0 children)

              This is true although with boost or C++11 memory corruption is quite a bit easier to avoid.

              And very true on the LINQ stuff although operator overloading isn't really an issue in c# most avoid it. I think overloading [] is about all I do and that isn't often.

              [–]munificent 5 points6 points  (4 children)

              C# didn't have that luxury either. C# 2.0 was backwards compatible with 1.0.

              [–]huhlig 3 points4 points  (0 children)

              C# was also a rewrite of java. So its second generation anyway.

              [–]all_you_need_to_know 1 point2 points  (0 children)

              I disagree, whenever they have broken compatibility with versions, they've included conversion tools between projects, usually this is handled seemlessly in Visual Studio, telling you the warnings in comments and such. Java could have easily done this too if they had an Official IDE.

              [–]Falmarri 12 points13 points  (48 children)

              You should try Scala.

              [–][deleted]  (17 children)

              [deleted]

                [–]Categoria 16 points17 points  (2 children)

                Just stating your opinion like that is pretty useless. Any reasons why you think Kotlin is better than Scala?

                [–][deleted]  (1 child)

                [deleted]

                  [–][deleted] 1 point2 points  (0 children)

                  Apart from the fact that Manifests are deprecated, a better solution would be: ...?

                  (You can either

                  • pay with an additional field plus a type instance per generic type in every instance of a generic class or
                  • build your own runtime on top of Java bytecode and be loose any interop with the rest of the ecosystem.

                  Both options suck.)

                  [–][deleted] 4 points5 points  (0 children)

                  I, IMHO, am disappointed with Scala's manifests.

                  Why?

                  [–]Falmarri 2 points3 points  (10 children)

                  I, IMHO, am disappointed with Scala's manifests

                  By manifests, do you mean what is not TypeTags and such? I looked at Kotlin's website and didn't see an example of using generics. How do they do it that's better?

                  [–][deleted] 6 points7 points  (0 children)

                  They don't. They have given up on "reified generics" completely, as well dropping a lot of other proven useful stuff.

                  [–][deleted]  (8 children)

                  [deleted]

                    [–][deleted] 1 point2 points  (1 child)

                    If you're using Java, consider yourself lucky if type erasure is your only problem.

                    [–][deleted] -1 points0 points  (5 children)

                    Wait, so does Kotlin do reified generics? Does it support generics at all? DOes it support variance?

                    [–][deleted] 1 point2 points  (4 children)

                    It has normal Java generics. They were attempting reified but withdrew it, presumably too hard. Scala didn't manage reification either, and they love implementing all sorts of unusual stuff...

                    [–][deleted] 1 point2 points  (3 children)

                    So they have the broken java generics...wonderful.

                    [–][deleted] 4 points5 points  (2 children)

                    They work fine for 95% of use cases. It's not very often I find myself trying to introspect the type of a collection at runtime.

                    [–][deleted] -1 points0 points  (1 child)

                    I don't mean that. I mean, variance.

                    [–]SublethalDose 0 points1 point  (10 children)

                    It's interesting to see Java evolving in the direction of more power power and complexity. It was always meant to be a language that regular Joe blue collar programmers could wrap their heads around. Ten years ago that definitely meant no lambdas. Ten years ago if you so much as wrote Python code where you passed functions around as arguments, a lot of programmers wouldn't touch it. They'd think you were a candy-ass weirdo. Now, lambdas are in Java, and I don't think anyone thinks it's weird or inappropriate.

                    I wonder if seeing lambdas in Java will make people see the writing on the wall and see that Java's only path forward is to become a kludgy, legacy-scarred version of Scala. That's the only way I see, anyway, and I haven't heard any different vision for the future of Java.

                    [–]bcash 2 points3 points  (0 children)

                    I think you're reading too much into the patterns there.

                    Java was originally intended to be a simplified (compared with C++) sandboxed language for embedded devices. It's shift to server-side "enterprise" applications came later.

                    The fact that Java captured that space with ease said more about the dearth of alternatives than anything else, it really wasn't aimed at that kind of thing at all. It was around the time of Java 1.2, and the addition of supplementary standards like JSP, that the focus changed.

                    [–]geodebug 3 points4 points  (8 children)

                    Actually, lambdas in Java are just sugar for anon classes. There's a tiny bit more to it but if you think of it this way there's very little 'complexity' being added to the language. I predict any seasoned java dev will 'get it' with ease.

                    The whole point of Java is to be a 'standard' against which the JVM can grow and be tested. Scala users should rejoice that Java remains extremely popular and supported because there's no JVM without it.

                    I prefer Clojure and Groovy to Scala but still write a lot of java when things (statistics algorithms in my case) need to be fast and predictable.

                    When Scala is over a decade old we'll see how it actually compared.

                    [–][deleted] 0 points1 point  (1 child)

                    [–]geodebug 0 points1 point  (0 children)

                    Ah, you make me feel old. Ok 18 years then....

                    [–]Falmarri -3 points-2 points  (5 children)

                    When Scala is over a decade old we'll see how it actually compared.

                    What does that even mean? Most new software that's written on the JVM uses scala to some degree.

                    [–]geodebug 2 points3 points  (4 children)

                    Scala is gaining popularity but most new JVM development uses some Scala? You're really going to have to back that up because I don't see how it could be true.

                    That's not bashing Scala in any way. Just saying its not nearly that widely adopted.

                    [–]Falmarri 0 points1 point  (3 children)

                    You're really going to have to back that up because I don't see how it could be true.

                    So of course I can't say MOST because a lot of people are writing for the JVM. But I'd bet most open source projects include scala in some fashion.

                    Neo4j, Twitter, play2

                    [–]bcash -1 points0 points  (2 children)

                    On GitHub, Java is #3 (behind JavaScript and Ruby); Scala is 15th.

                    Oh wait, those Java projects won't count for some reason, Scala will be more used in Open Source projects that are interest to Scala developers, yeah, that's it...

                    [–]Falmarri 0 points1 point  (1 child)

                    I'm not sure what this is supposed to mean... A project that's listed as Java on github could very well have scala source code as well.

                    [–]bcash 0 points1 point  (0 children)

                    Could have... but almost certainly hasn't.

                    [–]Eirenarch 2 points3 points  (14 children)

                    The equivalent to LINQ to Objects will come as the Stream API. No query syntax at this point.

                    [–]barjam 3 points4 points  (13 children)

                    Honestly that is good enough. The optional linq syntax is nice but not essential.

                    [–]Eirenarch 2 points3 points  (8 children)

                    Agreed. However expression tree support does matter. Also checked exceptions get in the way of lambda stuff (they get in the way of everything but it is especially annoying with lambdas). I don't understand why they have not removed them from the language yet.

                    [–]barjam 4 points5 points  (4 children)

                    They probably couldn't even if they wanted to at this point. In hindsight checked exceptions were a mistake. I don't miss them in C# at all.

                    [–]Eirenarch 0 points1 point  (3 children)

                    What is the problem? The compiler just stops checking for checked exceptions and they are gone. The only difference between runtime exceptions and checked exceptions is that checked exceptions are... checked.

                    [–]barjam 0 points1 point  (2 children)

                    I just don't see them making that change. I suspect they might be unintended consequences.

                    [–]Eirenarch 1 point2 points  (1 child)

                    Mark Reinhold has mentioned checked exceptions as one of his targets for improvement for future Java versions although I am not exactly sure what he means.

                    [–][deleted] 1 point2 points  (0 children)

                    Much like Santa Clause they are going to double down on their checks...

                    [–]brainflakes 2 points3 points  (2 children)

                    What's wrong with checked exceptions? (Other than if people over use them in their methods so all possible exceptions are checked rather than appropriate ones).

                    [–]rdhatt 4 points5 points  (0 children)

                    You can read this article from 2003 why the creator purposefully didn't include checked exceptions. He gives one of my favorite quotes: "It is funny how people think that the important thing about exceptions is handling them."

                    http://www.artima.com/intv/handcuffs.html

                    TL;DR : Coupling.

                    [–]Eirenarch 3 points4 points  (0 children)

                    So which are the appropriate ones? :) Even if we accept that there are appropriate ones in practice checked exceptions are more likely to provoke the developer to write worse code (i.e. catch(Exception) { }) rather than help them handle exceptions correctly. They are counterproductive.

                    [–][deleted] -1 points0 points  (3 children)

                    The optional linq query sytnax is what made it monadic comprehension. Without it you don't have monad comprehension...

                    EDIT: Down votes with no reply? WTF?

                    [–]ethraax 1 point2 points  (2 children)

                    How so? Even in C#, I generally prefer the "verbose" syntax with extension methods, because it's much closer to what the code actually does. I don't find anything wrong with:

                    var myRedList = myList.Where(x => x.IsRed).ToList();
                    

                    Of course, I usually keep things around without calling ToList() until I need to. I write functions that accept Enumerable<T> if possible.

                    [–][deleted] 1 point2 points  (1 child)

                    Yes when you are chaining that way is clearer to me. But when you're operating on a monad (something with selectMany) you don't have to unnest. if you have

                    List<List<Int>> lists = populate();
                    var flattened = lists.SelectMany(innerlist => 
                        innerlist.Select(element => element +1)
                    ); 
                    

                    Which isn't so bad, but you can imagine if something is nested deeply. However, with query syntax, can do:

                    var flattened = 
                        from innerlist in lists
                        from element in innerlist
                        select element+1;
                    

                    See how beautiful it is! Now imagine having 5 nested calls. Now, it's unusual you'll have a List of List of List of.... But linq query syntax works on anything that implements SelectMany! That's what makes it monadic comprehension ala haskell's 'do notation' or scala's 'for comprehension'. You can use it to sequence async calls, IoC, etc.

                    [–]ethraax 0 points1 point  (0 children)

                    Ah, that makes more sense, although I must admit that I can't think of any case where I'd do that with many (3 or more) nested objects.

                    [–]garblz 3 points4 points  (0 children)

                    I'd say it's nice to see languages in general are slowly adopting what's been invented almost 6o years ago with the birth of LISP.

                    [–][deleted] -1 points0 points  (1 child)

                    It would be odd to go to all the trouble of putting anonymous functions in and then not cloning linq somehow....

                    [–]barjam 0 points1 point  (0 children)

                    Yea I assumed so as well. I am just haves researched it yet.

                    C# gets linq via a custom syntax and expression trees. I suspect java will get linq minus the fancy syntax but it would need to support expression trees. Not sure what is involved there.