From pavel.rappo at oracle.com Wed Jul 1 20:49:41 2020 From: pavel.rappo at oracle.com (Pavel Rappo) Date: Wed, 1 Jul 2020 21:49:41 +0100 Subject: Will Java ever allow comments to nest? Message-ID: Hello, JLS specifies that comments do not nest [1]. For example, the below source will not compile $ cat CommentsDoNotNest.java public class CommentsDoNotNest { /* /* */ */ } $ javac CommentsDoNotNest.java CommentsDoNotNest.java:2: error: illegal start of type /* /* */ */ ^ 1 error Some modern languages allow comments to nest. For example, Swift, F#, and Haskell do that. Why doesn't Java do that? Will Java ever do that? I can see cases where nesting would be useful: 1. Commenting out long blocks of code that possibly contain `/* ... */` comments. 2. Having a character sequence resembling a comment terminator `*/`, for example, in a regex or a glob pattern. 3. Having a `/* ... */` comment within a doc comment `/** ... */`. This is typically used in doc comments of language modeling APIs and, admittedly, is a niche case. All of the above can be done today, albeit with much friction. Thanks, -Pavel [1] https://docs.oracle.com/javase/specs/jls/se14/html/jls-3.html#jls-3.7 From martinrb at google.com Wed Jul 1 22:28:25 2020 From: martinrb at google.com (Martin Buchholz) Date: Wed, 1 Jul 2020 15:28:25 -0700 Subject: Will Java ever allow comments to nest? In-Reply-To: References: Message-ID: I have an ancient perl script that can __reliably__ extract comments from Java (and C) sources with a regex. That would not be possible if comments were nested. Comment nesting is one language design decision to only get to make once. On Wed, Jul 1, 2020 at 1:53 PM Pavel Rappo wrote: > > Hello, > > JLS specifies that comments do not nest [1]. For example, the below source will not compile > > $ cat CommentsDoNotNest.java > public class CommentsDoNotNest { > /* /* */ */ > } > > $ javac CommentsDoNotNest.java > CommentsDoNotNest.java:2: error: illegal start of type > /* /* */ */ > ^ > 1 error > > Some modern languages allow comments to nest. For example, Swift, F#, and Haskell do that. Why doesn't Java do that? Will Java ever do that? > > I can see cases where nesting would be useful: > > 1. Commenting out long blocks of code that possibly contain `/* ... */` comments. > 2. Having a character sequence resembling a comment terminator `*/`, for example, in a regex or a glob pattern. > 3. Having a `/* ... */` comment within a doc comment `/** ... */`. This is typically used in doc comments of language modeling APIs and, admittedly, is a niche case. > > All of the above can be done today, albeit with much friction. > > Thanks, > -Pavel > > [1] https://docs.oracle.com/javase/specs/jls/se14/html/jls-3.html#jls-3.7 > From pavel.rappo at oracle.com Thu Jul 2 14:15:27 2020 From: pavel.rappo at oracle.com (Pavel Rappo) Date: Thu, 2 Jul 2020 15:15:27 +0100 Subject: Will Java ever allow comments to nest? In-Reply-To: References: Message-ID: > On 1 Jul 2020, at 21:49, Pavel Rappo wrote: > > Hello, > > JLS specifies that comments do not nest [1]. For example, the below source will not compile > > $ cat CommentsDoNotNest.java > public class CommentsDoNotNest { > /* /* */ */ > } > > $ javac CommentsDoNotNest.java > CommentsDoNotNest.java:2: error: illegal start of type > /* /* */ */ > ^ > 1 error > > Some modern languages allow comments to nest. For example, Swift, F#, and Haskell do that. Why doesn't Java do that? Will Java ever do that? > > I can see cases where nesting would be useful: > > 1. Commenting out long blocks of code that possibly contain `/* ... */` comments. > 2. Having a character sequence resembling a comment terminator `*/`, for example, in a regex or a glob pattern. Scratch that. Item 2 has nothing to do with nesting; it's just a standalone `*/` $ cat CommentsDoNotNest2.java public class CommentsDoNotNest { /* The result of "/home/".matches(".*/") is true. */ } $ javac CommentsDoNotNest2.java CommentsDoNotNest2.java:2: error: unclosed string literal /* The result of "/home/".matches(".*/") is true. */ ^ CommentsDoNotNest2.java:4: error: reached end of file while parsing 2 errors A solution to this is to hide `*/` from the compiler. Depending on the context this can be done differently. If this is a regular comment I could choose between these: a. // The result of "/home/".matches(".*/") is true. b. /* The result of "/home/".matches(".*" + "/") is true. */ If this is a doc comment I could use HTML entities or tags of the Standard doclet: c. /** The result of "/home/".matches(".*/") is true. */ d. /** The result of "/home/".matches(".*/") is true. */ e. /** The result of "/home/".matches(".{@literal *}/") is true. */ The problem with [c], [d], and [e], however, is that they make a comment less WYSIWYG. The less a doc comment diverts from WYSIWYG the better: if a doc comment uses a lot of markup, I will need a browser to render that (for example, to copy-paste a snippet into my code). While experimenting with comments I found that IntelliJ IDEA thinks that these are valid comments: /* \u002a/ */ /* *\u002f */ These comments are invalid for the same reason this is not a valid string literal: "Hello,\u000Aworld" JLS specifies that the compiler translates Unicode escapes as the first step of lexical translation, 2 steps before comments are discarded: https://docs.oracle.com/javase/specs/jls/se7/html/jls-3.html I filed a bug against IDEA: https://youtrack.jetbrains.com/issue/IDEA-245018 -Pavel > 3. Having a `/* ... */` comment within a doc comment `/** ... */`. This is typically used in doc comments of language modeling APIs and, admittedly, is a niche case. > > All of the above can be done today, albeit with much friction. > > Thanks, > -Pavel > > [1] https://docs.oracle.com/javase/specs/jls/se14/html/jls-3.html#jls-3.7 > From alex.buckley at oracle.com Thu Jul 2 18:04:10 2020 From: alex.buckley at oracle.com (Alex Buckley) Date: Thu, 2 Jul 2020 11:04:10 -0700 Subject: Will Java ever allow comments to nest? In-Reply-To: References: Message-ID: <1418edc9-9280-41ce-3d20-f6c50eb1ea59@oracle.com> On 7/2/2020 7:15 AM, Pavel Rappo wrote: > While experimenting with comments I found that IntelliJ IDEA thinks that these are valid comments: > > /* \u002a/ */ > /* *\u002f */ > > These comments are invalid for the same reason this is not a valid string literal: > > "Hello,\u000Aworld" > > JLS specifies that the compiler translates Unicode escapes as the first step of lexical translation, 2 steps before comments are discarded: > > https://docs.oracle.com/javase/specs/jls/se7/html/jls-3.html > > I filed a bug against IDEA: > > https://youtrack.jetbrains.com/issue/IDEA-245018 Thank you for filing this bug, and (from looking at the comments in youtrack) helping the vendor to better understand it. Alex From martinrb at google.com Fri Jul 3 14:21:01 2020 From: martinrb at google.com (Martin Buchholz) Date: Fri, 3 Jul 2020 07:21:01 -0700 Subject: Will Java ever allow comments to nest? In-Reply-To: References: Message-ID: On Thu, Jul 2, 2020 at 7:17 AM Pavel Rappo wrote: > While experimenting with comments I found that IntelliJ IDEA thinks that these are valid comments: > > /* \u002a/ */ > /* *\u002f */ > > These comments are invalid for the same reason this is not a valid string literal: > > "Hello,\u000Aworld" I have a confession to make. My perl script has the same bug, and I was even aware of that when I wrote the word __reliably__ previously. Worse, I'm unlikely to go and fix that bug. But IDEA should fix its. From behrangsa at gmail.com Sun Jul 5 09:46:55 2020 From: behrangsa at gmail.com (Behrang Saeedzadeh) Date: Sun, 5 Jul 2020 19:46:55 +1000 Subject: A possibly novel construct for type-safe key/value pairs Message-ID: I was reading [1] on Reddit and thought about the topic of syntax sugar for maps that has been discussed many times before which would allow us write: User david = usersService.findBy("name" -> "David"); Instead of: User david = usersService.bind(1, "David").findBy("this.name = ?1"); Or if Java had symbols: User david = usersService.findBy(:name -> "David"); // or User david = usersService.findBy(name: "David"); But what if we could make this typesafe? Let's assume `User` is defined as: @Entity public class User { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Integer id; private String name; private String occupation; private LocalDateTime createdAt; private LocalDateTime updatedAt; public User() { } // Get/Set omitted by brevity } If Java had: * Symbols * And syntax sugar for key-value pairs And a "novel" [2] `Property` (or `Getter`) construct that we could only assign properties (getters) of type `T` to its instances, for example: Getter userId = User::getId; // compiles -- getId is a property of User Getter userId = :id; // syntax sugar for User::getId Getter invalid = User::getFirstName; // does not compile -- getId is not a property of User Then we could write a query method like this: public List find(Property... params) { ... } And call it like this: find(name: "David", occupation: "Programmer") // compiles -- name and occupation are properties of `User` find(firstName: "David") // does not compile -- firstName is not a property of `User` This can be expanded further to limit what properties can be assigned to a `Getter` instance. For example: public User findById(Getter id) { ... } findById(12); // compiles -- id is is integer findById("foo"); // does not compile -- id is not String Of course, if added to Java the final syntax and semantics could be very different, but what do you think? Is there a language that already has a similar construct? [1] https://www.reddit.com/r/java/comments/hlbw03/i_am_not_a_savage_for_stay_concatenating_jpql/ [2] Unless something similar already exists in another programming language -- Best regards, Behrang Saeedzadeh From stuart.marks at oracle.com Tue Jul 7 01:10:28 2020 From: stuart.marks at oracle.com (Stuart Marks) Date: Mon, 6 Jul 2020 18:10:28 -0700 Subject: Will Java ever allow comments to nest? In-Reply-To: References: Message-ID: On 7/1/20 1:49 PM, Pavel Rappo wrote: > Some modern languages allow comments to nest. For example, Swift, F#, and Haskell do that. Why doesn't Java do that? Will Java ever do that? Why doesn't Java do that? I'd guess, since Java is a descendant of C, and C doesn't allow comment nesting. Why doesn't C allow nesting? I'm not entirely sure, but I believe it could make lexical analysis easier. If you're in a comment, then the only thing you have to do is look for the */ comment terminator. Sure, you could write a bit more code to track nesting, but if you're running on a 24KB PDP-11, every bit counts. [1] > I can see cases where nesting would be useful: > > 1. Commenting out long blocks of code that possibly contain `/* ... */` comments. > 2. Having a character sequence resembling a comment terminator `*/`, for example, in a regex or a glob pattern. > 3. Having a `/* ... */` comment within a doc comment `/** ... */`. This is typically used in doc comments of language modeling APIs and, admittedly, is a niche case. > > All of the above can be done today, albeit with much friction. The best way to comment out a long block of code in Java is to prefix every line with //. This "nests" properly in that it handles complete /**/ blocks as well as blocks of //-commented lines. (Of course it won't work if you comment out an unpaired /* or */ token.) This is easily accomplished in NetBeans with a couple buttons dedicated to this task. I'm sure other IDEs have equivalent commands. In vi, :.,.+10s,^,//, :.,.+10s,^//,, will comment and uncomment a block of lines. In Emacs, you can use replace-regexp in a similar fashion. s'marks [1] https://www.bell-labs.com/usr/dmr/www/chist.html From info at j-kuhn.de Tue Jul 7 10:40:02 2020 From: info at j-kuhn.de (Johannes Kuhn) Date: Tue, 7 Jul 2020 12:40:02 +0200 Subject: Will Java ever allow comments to nest? In-Reply-To: References: Message-ID: <67b13f91-ec26-46ca-52bc-2e462657f103@j-kuhn.de> This is a source incompatible change. It would break /* inside comments: ??? /** ???? * Determines whether or not the tokenizer recognizes C-style comments. ???? * If the flag argument is {@code true}, this stream tokenizer ???? * recognizes C-style comments. All text between successive ???? * occurrences of {@code /*} and */ are discarded. ???? *

???? * If the flag argument is {@code false}, then C-style comments ???? * are not treated specially. ???? * ???? * @param?? flag?? {@code true} indicates to recognize and ignore ???? *???????????????? C-style comments. ???? */ That's the javadoc of StreamTokenizer.slashStarComments(boolean). With your proposed change, the javadoc comment would not be closed at the end. - Johannes From bikchurin2001 at gmail.com Tue Jul 7 10:55:45 2020 From: bikchurin2001 at gmail.com (Wow Lucky) Date: Tue, 7 Jul 2020 13:55:45 +0300 Subject: cross-compile openjdk 11u to Android device Message-ID: I am trying to cross-compile openjdk 11u to aarch64. I am using following command: *bash configure --openjdk-target=aarch64-linux-android21 --disable-warnings-as-errors CC=aarch64-linux-android21-clang CXX=aarch64-linux-android21-clang++* but i am getting output errors below: *checking for aarch64-linux-android21-clang... /mnt/c/Users/ACER/downloads/NDK/build/tools/toolchain/bin/aarch64-linux-android21-clang* *checking resolved symbolic links for CC... no symlink* *configure: The C compiler (located as /mnt/c/Users/ACER/downloads/NDK/build/tools/toolchain/bin/aarch64-linux-android21-clang) does not seem to be the required gcc compiler.* *configure: The result from running with --version was: ""* *configure: error: A gcc compiler is required. Try setting --with-tools-dir.* *configure exiting with result code 1* (all text in file) But if i use */mnt/c/Users/ACER/downloads/NDK/build/tools/toolchain/bin/aarch64-linux-android21-clang --version* The output is *Android (6454773 based on r365631c2) clang version 9.0.8 (https://android.googlesource.com/toolchain/llvm-project 98c855489587874b2a325e7a516b99d838599c6f) (based on LLVM 9.0.8svn)* *Target: aarch64-unknown-linux-android21* *Thread model: posix* *InstalledDir: /mnt/c/Users/ACER/downloads/NDK/build/tools/toolchain/bin* I don't know how to fix this error. From zen at freedbms.net Tue Jul 7 10:54:09 2020 From: zen at freedbms.net (Zenaan Harkness) Date: Tue, 7 Jul 2020 20:54:09 +1000 Subject: Java's strings, UTF-8 etc In-Reply-To: References: <20200319233527.wmuzlfit7nb4hx4l@eye.freedbms.net> Message-ID: <20200707105409.tdb5p6oyxpxrvxp7@eye.freedbms.net> Sounds like Java's String is well overdue for a medium term replacement plan then... Some of us have some rather swift envy =) On Fri, Apr 03, 2020 at 10:55:29AM -0400, Andrew Myers wrote: > Afundamental problem with UTF-8 strings is the String API itself. String > relies on being able to use integer indices as iterators and then using > charAt() to select characters. A UTF-8 string should be a different > abstraction that does not encourage programmers to do inefficient random > access into strings, and also is able to return characters larger than 16 bits > in size -- probably int/Integer rather than char/Character. > > -- Andrew > > Zenaan Harkness wrote: > > > > Hi Brian, in case it is of interest, I did an exploration over a week or > > two, and wrote up that journey here: > > > > https://zenaan.github.io/zen/javadoc/zen/lang/string.html > > > > See also of course: > > > > https://github.com/zenaan/zen > > > > And for reference, see also: > > > > https://mail.openjdk.java.net/pipermail/discuss/2016-November/004065.html > > > > https://mail.openjdk.java.net/pipermail/discuss/2016-November/004070.html > > > > https://mail.openjdk.java.net/pipermail/discuss/2016-November/004072.html > > > > > > (I was hoping to one day do a proof of concept for byte array backed UTF-8 > > strings in Java, but have not returned to this little project - in any > > case, I do believe this would be a fundamental improvement to the core of > > Java.) > > > > Best regards, > > Zenaan From david.holmes at oracle.com Tue Jul 7 11:41:37 2020 From: david.holmes at oracle.com (David Holmes) Date: Tue, 7 Jul 2020 21:41:37 +1000 Subject: cross-compile openjdk 11u to Android device In-Reply-To: References: Message-ID: <6e02562c-f620-198f-cb9a-10513a911af5@oracle.com> Hi, The discuss list is the wrong place to ask this question, so I'm redirecting to the mobile-dev list, as within the context of the mobile project is only place where cross-compilation of this kind might be supported. http://openjdk.java.net/projects/mobile/ Cheers, David ----- On 7/07/2020 8:55 pm, Wow Lucky wrote: > I am trying to cross-compile openjdk 11u to aarch64. I am using following > command: > *bash configure --openjdk-target=aarch64-linux-android21 > --disable-warnings-as-errors CC=aarch64-linux-android21-clang > CXX=aarch64-linux-android21-clang++* > > but i am getting output errors below: > *checking for aarch64-linux-android21-clang... > /mnt/c/Users/ACER/downloads/NDK/build/tools/toolchain/bin/aarch64-linux-android21-clang* > *checking resolved symbolic links for CC... no symlink* > *configure: The C compiler (located as > /mnt/c/Users/ACER/downloads/NDK/build/tools/toolchain/bin/aarch64-linux-android21-clang) > does not seem to be the required gcc compiler.* > *configure: The result from running with --version was: ""* > *configure: error: A gcc compiler is required. Try setting > --with-tools-dir.* > *configure exiting with result code 1* > (all text in file) > > But if i use > */mnt/c/Users/ACER/downloads/NDK/build/tools/toolchain/bin/aarch64-linux-android21-clang > --version* > The output is > *Android (6454773 based on r365631c2) clang version 9.0.8 > (https://android.googlesource.com/toolchain/llvm-project > > 98c855489587874b2a325e7a516b99d838599c6f) (based on LLVM 9.0.8svn)* > *Target: aarch64-unknown-linux-android21* > *Thread model: posix* > *InstalledDir: /mnt/c/Users/ACER/downloads/NDK/build/tools/toolchain/bin* > > I don't know how to fix this error. > From irina.arkhipets at gmail.com Tue Jul 14 09:40:15 2020 From: irina.arkhipets at gmail.com (Irina Arkhipets) Date: Tue, 14 Jul 2020 16:40:15 +0700 Subject: Introduction of Alhambra project Message-ID: Hi All, My name is Irina Arkhipets, I work for Unipro NCIT company located in Novosibirsk, Russia. We've just signed the OCA license, so I think now it's time to introduce ourselves here. Our company has a long history of work in core Java technologies since early days of the Java platform. In collaboration with Sun Microsystems we started developing certification tests for JDK in 1996; our engineers contributed to initial versions of the JVM specifications and later on took part in implementation of Apache Harmony runtime. Nowadays, the main specialization of our company continues to be compiler technologies, optimization and tuning various kinds of applications and computational libraries. Our particular interest is in finding most efficient ways of porting latest OpenJDK to new platforms, we assume it should be possible to port optimizing JIT compiler without introducing lots of platform specific helpers and custom codegens. Of course we're aware of Zero/Shark project experience, initially we considered to restore it and even implemented it for Java 8. After some experiments and performance analysis, we believe that a better solution would be to combine the Opto JIT front-end and its elaborated Java-specific platform-independent optimizations with power of modern LLVM back-end. Therefore, we propose the Alhambra project to develop such a JIT compiler. We are going to base it on OpenJDK 11 since it's a recent stable LTS version, however I am not quite sure that it's still open for the new features. If anybody else works in the same direction or just has some interest in the same area - we would be happy to cooperate. Cheers, Irina From rkennke at redhat.com Tue Jul 14 16:37:23 2020 From: rkennke at redhat.com (Roman Kennke) Date: Tue, 14 Jul 2020 18:37:23 +0200 Subject: Introduction of Alhambra project In-Reply-To: References: Message-ID: <9eea43b0d4309d6de058732455fbe2bb31126495.camel@redhat.com> Hi Irina, > Our particular interest is in finding most efficient ways of porting > latest > OpenJDK to new platforms, we assume it should be possible to port > optimizing JIT compiler without introducing lots of platform specific > helpers and custom codegens. Of course we're aware of Zero/Shark > project > experience, initially we considered to restore it and even > implemented it > for Java 8. After some experiments and performance analysis, we > believe > that a better solution would be to combine the Opto JIT front-end and > its > elaborated Java-specific platform-independent optimizations with > power of > modern LLVM back-end. Therefore, we propose the Alhambra project to > develop > such a JIT compiler. > I was one of the maintainers of Shark for a while, and I was also the one who eventually removed it from the source tree (JDK9 time frame, iirc). I still find this a very interesting project, and maybe the most pressing limitations in LLVM and OpenJDK have since been solved: 1. We now have JVMCI, the compiler interface that is used by Graal, and which seems like the obvious choice to also implement new JIT like the one you are proposing. There seems no need to directly interface with C2/opto compiler like Shark did. 2. The major problem with Shark was the lack of support for GC in LLVM back then (in particular, how GC can access and manage references on the stack). I've heard that this has immensely improved since then. 3. I am not sure what the status of JIT support in LLVM is. Might be worth to investigate. Back in the day, Shark used the 'regular' LLVM compiler, because JIT support was basically limited to x86. Maybe this has improved since then. 4. Also, the APIs of LLVM tended to evolve very rapidly, and it was difficult to keep up with it, and especially figuring out the correct version of LLVM to work with Shark was a nightmare. At some point we littered Shark with #ifdefs to figure out the LLVM version to compile against, and use the correct APIs for that. I hope that the situation is better now. > We are going to base it on OpenJDK 11 since it's a recent stable LTS > version, however I am not quite sure that it's still open for the new > features. If I were you, I'd base it on the development branch that is currently JDK16. That is where new features are developed and eventually integrated. https://hg.openjdk.java.net/jdk/jdk/ If the project comes through, you'd probably want your own repository that is based on jdk/jdk. Also, try to keep it under the JVMCI interfaces. If those are not sufficient, we shall work to make them a better fit. Better to keep it sane from the start. > If anybody else works in the same direction or just has some interest > in > the same area - we would be happy to cooperate. I am in favor of this project going forward, even though I doubt I can contribute very much to it due to lack of time. I'll be happy to assist though. Cheers, Roman From irina.arkhipets at gmail.com Mon Jul 20 06:22:47 2020 From: irina.arkhipets at gmail.com (Irina Arkhipets) Date: Mon, 20 Jul 2020 13:22:47 +0700 Subject: Introduction of Alhambra project In-Reply-To: <9eea43b0d4309d6de058732455fbe2bb31126495.camel@redhat.com> References: <9eea43b0d4309d6de058732455fbe2bb31126495.camel@redhat.com> Message-ID: Hi Roman, Thank you for the provided info! It sounds interesting to make the JIT using Graal front-end and LLVM. Now we are at the beginning of the road, so currently our progress is based on the Java 8 with LLVM support since it is the most used in production. Graal looks really interesting, but it is not quite clear if/when it will make its way to standard SDK and will it ever be accepted as default JRE. We will definitely take your comments into consideration and it would be great if you participate in the project in any role. Best regards, Irina On Tue, Jul 14, 2020 at 11:37 PM Roman Kennke wrote: > Hi Irina, > > > > Our particular interest is in finding most efficient ways of porting > > latest > > OpenJDK to new platforms, we assume it should be possible to port > > optimizing JIT compiler without introducing lots of platform specific > > helpers and custom codegens. Of course we're aware of Zero/Shark > > project > > experience, initially we considered to restore it and even > > implemented it > > for Java 8. After some experiments and performance analysis, we > > believe > > that a better solution would be to combine the Opto JIT front-end and > > its > > elaborated Java-specific platform-independent optimizations with > > power of > > modern LLVM back-end. Therefore, we propose the Alhambra project to > > develop > > such a JIT compiler. > > > > I was one of the maintainers of Shark for a while, and I was also the > one who eventually removed it from the source tree (JDK9 time frame, > iirc). > > I still find this a very interesting project, and maybe the most > pressing limitations in LLVM and OpenJDK have since been solved: > > 1. We now have JVMCI, the compiler interface that is used by Graal, and > which seems like the obvious choice to also implement new JIT like the > one you are proposing. There seems no need to directly interface with > C2/opto compiler like Shark did. > 2. The major problem with Shark was the lack of support for GC in LLVM > back then (in particular, how GC can access and manage references on > the stack). I've heard that this has immensely improved since then. > 3. I am not sure what the status of JIT support in LLVM is. Might be > worth to investigate. Back in the day, Shark used the 'regular' LLVM > compiler, because JIT support was basically limited to x86. Maybe this > has improved since then. > 4. Also, the APIs of LLVM tended to evolve very rapidly, and it was > difficult to keep up with it, and especially figuring out the correct > version of LLVM to work with Shark was a nightmare. At some point we > littered Shark with #ifdefs to figure out the LLVM version to compile > against, and use the correct APIs for that. I hope that the situation > is better now. > > > > We are going to base it on OpenJDK 11 since it's a recent stable LTS > > version, however I am not quite sure that it's still open for the new > > features. > > If I were you, I'd base it on the development branch that is currently > JDK16. That is where new features are developed and eventually > integrated. > > https://hg.openjdk.java.net/jdk/jdk/ > > If the project comes through, you'd probably want your own repository > that is based on jdk/jdk. > > Also, try to keep it under the JVMCI interfaces. If those are not > sufficient, we shall work to make them a better fit. Better to keep it > sane from the start. > > > If anybody else works in the same direction or just has some interest > > in > > the same area - we would be happy to cooperate. > > I am in favor of this project going forward, even though I doubt I can > contribute very much to it due to lack of time. I'll be happy to assist > though. > > Cheers, > Roman > > > From rkennke at redhat.com Mon Jul 20 08:00:07 2020 From: rkennke at redhat.com (Roman Kennke) Date: Mon, 20 Jul 2020 10:00:07 +0200 Subject: Introduction of Alhambra project In-Reply-To: References: <9eea43b0d4309d6de058732455fbe2bb31126495.camel@redhat.com> Message-ID: <73a5427e2ef1b6caf7f5cbe2809e51055226ced9.camel@redhat.com> Hi Irina, I didn't mean to suggest to use Graal as front-end, I only meant to suggest to use or extend JVMCI or build another reasonable compiler- interface for Hotspot. I'd also suggest to develop new features in the development branch (currently JDK16) - or a fork of it under your project umbrella once it is established. Thanks and best regards, Roman > Thank you for the provided info! > It sounds interesting to make the JIT using Graal front-end and LLVM. > Now we are at the beginning of the road, so currently our progress is > based on the Java 8 with LLVM support since it is the most used in > production. Graal looks really interesting, but it is not quite clear > if/when it will make its way to standard SDK and will it ever be > accepted as default JRE. > We will definitely take your comments into consideration and it would > be great if you participate in the project in any role. > Best regards, > Irina > > On Tue, Jul 14, 2020 at 11:37 PM Roman Kennke > wrote: > > Hi Irina, > > > > > > > Our particular interest is in finding most efficient ways of > > porting > > > latest > > > OpenJDK to new platforms, we assume it should be possible to port > > > optimizing JIT compiler without introducing lots of platform > > specific > > > helpers and custom codegens. Of course we're aware of Zero/Shark > > > project > > > experience, initially we considered to restore it and even > > > implemented it > > > for Java 8. After some experiments and performance analysis, we > > > believe > > > that a better solution would be to combine the Opto JIT front-end > > and > > > its > > > elaborated Java-specific platform-independent optimizations with > > > power of > > > modern LLVM back-end. Therefore, we propose the Alhambra project > > to > > > develop > > > such a JIT compiler. > > > > > > > I was one of the maintainers of Shark for a while, and I was also > > the > > one who eventually removed it from the source tree (JDK9 time > > frame, > > iirc). > > > > I still find this a very interesting project, and maybe the most > > pressing limitations in LLVM and OpenJDK have since been solved: > > > > 1. We now have JVMCI, the compiler interface that is used by Graal, > > and > > which seems like the obvious choice to also implement new JIT like > > the > > one you are proposing. There seems no need to directly interface > > with > > C2/opto compiler like Shark did. > > 2. The major problem with Shark was the lack of support for GC in > > LLVM > > back then (in particular, how GC can access and manage references > > on > > the stack). I've heard that this has immensely improved since then. > > 3. I am not sure what the status of JIT support in LLVM is. Might > > be > > worth to investigate. Back in the day, Shark used the 'regular' > > LLVM > > compiler, because JIT support was basically limited to x86. Maybe > > this > > has improved since then. > > 4. Also, the APIs of LLVM tended to evolve very rapidly, and it was > > difficult to keep up with it, and especially figuring out the > > correct > > version of LLVM to work with Shark was a nightmare. At some point > > we > > littered Shark with #ifdefs to figure out the LLVM version to > > compile > > against, and use the correct APIs for that. I hope that the > > situation > > is better now. > > > > > > > We are going to base it on OpenJDK 11 since it's a recent stable > > LTS > > > version, however I am not quite sure that it's still open for the > > new > > > features. > > > > If I were you, I'd base it on the development branch that is > > currently > > JDK16. That is where new features are developed and eventually > > integrated. > > > > https://hg.openjdk.java.net/jdk/jdk/ > > > > If the project comes through, you'd probably want your own > > repository > > that is based on jdk/jdk. > > > > Also, try to keep it under the JVMCI interfaces. If those are not > > sufficient, we shall work to make them a better fit. Better to keep > > it > > sane from the start. > > > > > If anybody else works in the same direction or just has some > > interest > > > in > > > the same area - we would be happy to cooperate. > > > > I am in favor of this project going forward, even though I doubt I > > can > > contribute very much to it due to lack of time. I'll be happy to > > assist > > though. > > > > Cheers, > > Roman > > > > From aph at redhat.com Mon Jul 20 10:51:04 2020 From: aph at redhat.com (Andrew Haley) Date: Mon, 20 Jul 2020 11:51:04 +0100 Subject: Introduction of Alhambra project In-Reply-To: <9eea43b0d4309d6de058732455fbe2bb31126495.camel@redhat.com> References: <9eea43b0d4309d6de058732455fbe2bb31126495.camel@redhat.com> Message-ID: <33d79852-5d1f-cfcd-e3aa-8c06631e9341@redhat.com> On 14/07/2020 17:37, Roman Kennke wrote: > 3. I am not sure what the status of JIT support in LLVM is. Might be > worth to investigate. Back in the day, Shark used the 'regular' LLVM > compiler, because JIT support was basically limited to x86. Maybe this > has improved since then. As far as I know it's now plenty good enough: Azul has a proprietary product based on the LLVM JIT, I have been told. > Also, try to keep it under the JVMCI interfaces. If those are not > sufficient, we shall work to make them a better fit. Better to keep it > sane from the start. JVMCI is rather designed to fit Graal, so it's in flux. I'm not sure that JVMCI is suitable for LLVM. -- Andrew Haley (he/him) Java Platform Lead Engineer Red Hat UK Ltd. https://keybase.io/andrewhaley EAC8 43EB D3EF DB98 CC77 2FAD A5CD 6035 332F A671 From behrangsa at gmail.com Wed Jul 22 07:20:37 2020 From: behrangsa at gmail.com (Behrang Saeedzadeh) Date: Wed, 22 Jul 2020 17:20:37 +1000 Subject: Which one of Linux, macOS, and Windows still don't have a native WatchService implementation? Message-ID: As it is mentioned in https://docs.oracle.com/en/java/javase/14/docs/api/java.base/java/nio/file/WatchService.html : *> The implementation that observes events from the file system is intended to map directly on to the native file event notification facility where available, or to use a primitive mechanism, such as polling, when a native facility is not available. Consequently, many of the details on how events are detected, their timeliness, and whether their ordering is preserved are highly implementation specific. For example, when a file in a watched directory is modified then it may result in a single ENTRY_MODIFY event in some implementations but several events in other implementations. Short-lived files (meaning files that are deleted very quickly after they are created) may not be detected by primitive implementations that periodically poll the file system to detect changes. * Does OpenJDK use a native implementation on any of Linux, macOS, and Windows operating systems? >From memory Java 8 on OS X didn't have a native implementation but things might have changed since then. I was thinking about writing a native implementation for those that don't and create a pull request to add it to OpenJDK. -- Best regards, Behrang Saeedzadeh From Alan.Bateman at oracle.com Wed Jul 22 07:46:46 2020 From: Alan.Bateman at oracle.com (Alan Bateman) Date: Wed, 22 Jul 2020 08:46:46 +0100 Subject: Which one of Linux, macOS, and Windows still don't have a native WatchService implementation? In-Reply-To: References: Message-ID: On 22/07/2020 08:20, Behrang Saeedzadeh wrote: > : > > > Does OpenJDK use a native implementation on any of Linux, macOS, and > Windows operating systems? > > From memory Java 8 on OS X didn't have a native implementation but things > might have changed since then. > > I was thinking about writing a native implementation for those that don't > and create a pull request to add it to OpenJDK. > There isn't currently a native implementation on macOS so it uses the portable "polling" implementation. nio-dev is the place to discuss this. Note that it has come up several times, and several people have developed implementations that aren't quite right (don't implement the spec correctly). It's one of these things that is doable, just needs time to work through some of the issues. -Alan From amitmishra.hcl at gmail.com Wed Jul 22 11:48:14 2020 From: amitmishra.hcl at gmail.com (Amit Mishra) Date: Wed, 22 Jul 2020 17:18:14 +0530 Subject: Link for OpenJDK 11.0.5 for Linux 64bit Message-ID: Hi, I didn?t get the link for OpenJDK 11.0.5 for Linux. (64 bit) Can you pls help me to locate? Regards, Amit M. From david.holmes at oracle.com Wed Jul 22 12:34:08 2020 From: david.holmes at oracle.com (David Holmes) Date: Wed, 22 Jul 2020 22:34:08 +1000 Subject: Link for OpenJDK 11.0.5 for Linux 64bit In-Reply-To: References: Message-ID: On 22/07/2020 9:48 pm, Amit Mishra wrote: > Hi, > > > > I didn?t get the link for OpenJDK 11.0.5 for Linux. (64 bit) > > Can you pls help me to locate? https://mail.openjdk.java.net/pipermail/jdk-updates-dev/2019-October/002026.html and follow the link. David > > > Regards, > > Amit M. > From sgehwolf at redhat.com Wed Jul 22 13:47:37 2020 From: sgehwolf at redhat.com (Severin Gehwolf) Date: Wed, 22 Jul 2020 15:47:37 +0200 Subject: Link for OpenJDK 11.0.5 for Linux 64bit In-Reply-To: References: Message-ID: <42566918973e2475069c57f86e8549028bf6c59a.camel@redhat.com> On Wed, 2020-07-22 at 22:34 +1000, David Holmes wrote: > On 22/07/2020 9:48 pm, Amit Mishra wrote: > > Hi, > > > > > > > > I didn?t get the link for OpenJDK 11.0.5 for Linux. (64 bit) > > > > Can you pls help me to locate? > > https://mail.openjdk.java.net/pipermail/jdk-updates-dev/2019-October/002026.html > > and follow the link. Or go to the Wiki page here: https://wiki.openjdk.java.net/display/JDKUpdates/JDK11u Search for "Releases" section. You'll find that 11.0.8+10 is latest and I'd recommend to use that. 11.0.5 is rather old and has known security vulnerabilities. If you must find it, you'll find a reference to it in the "archive" link. Thanks, Severin From Roger.Riggs at oracle.com Wed Jul 22 14:02:14 2020 From: Roger.Riggs at oracle.com (Roger Riggs) Date: Wed, 22 Jul 2020 10:02:14 -0400 Subject: Will Java ever allow comments to nest? In-Reply-To: <67b13f91-ec26-46ca-52bc-2e462657f103@j-kuhn.de> References: <67b13f91-ec26-46ca-52bc-2e462657f103@j-kuhn.de> Message-ID: Hi, It looks a lot like the quotes within quotes problem that has existed in shells forever and was addressed in text blocks with a different outer delimiter. The kind of encoding below "*/" is error prone and makes the developer encode the real intent. There's got to be a better way, even if it takes a new kind of doc comment delimiter for the outer. It will be a bigger change for javac and javadoc but makes it possible to redefine/reinterpret the delimiters. Maybe you can do something with: /*** /** * ... */ ***/ Regards, Roger On 7/7/20 6:40 AM, Johannes Kuhn wrote: > This is a source incompatible change. > > It would break /* inside comments: > > ??? /** > ???? * Determines whether or not the tokenizer recognizes C-style > comments. > ???? * If the flag argument is {@code true}, this stream tokenizer > ???? * recognizes C-style comments. All text between successive > ???? * occurrences of {@code /*} and */ are discarded. > ???? *

> ???? * If the flag argument is {@code false}, then C-style comments > ???? * are not treated specially. > ???? * > ???? * @param?? flag?? {@code true} indicates to recognize and ignore > ???? *???????????????? C-style comments. > ???? */ > > That's the javadoc of StreamTokenizer.slashStarComments(boolean). > With your proposed change, the javadoc comment would not be closed at > the end. > > - Johannes > From pavel.rappo at oracle.com Wed Jul 22 14:42:30 2020 From: pavel.rappo at oracle.com (Pavel Rappo) Date: Wed, 22 Jul 2020 15:42:30 +0100 Subject: Will Java ever allow comments to nest? In-Reply-To: References: <67b13f91-ec26-46ca-52bc-2e462657f103@j-kuhn.de> Message-ID: <910BE376-6BE3-49B9-AE26-4809A7B0C10F@oracle.com> Roger, No syntax based on block comments (/* ... */) will ever work. The JLS is very clear about that: whenever the compiler sees a */ in a block comment, the comment ends. The only practical solution here is to allow _an alternative_ doc-comment syntax based on end-of-line comments (//). Now, we can bikeshed on a form of the markers: for example, whether it's going to be /// // ... // The result of {@code "/home/".matches(".*/")} is {@code true}. // ... // @returns ... /// or /// ... /// The result of {@code "/home/".matches(".*/")} is {@code true}. /// ... /// @returns ... or something like //* ... //* The result of {@code "/home/".matches(".*/")} is {@code true}. //* ... //* @returns ... But `//` is the only practical way to go. -Pavel > On 22 Jul 2020, at 15:02, Roger Riggs wrote: > > Hi, > > It looks a lot like the quotes within quotes problem that has existed in shells forever and > was addressed in text blocks with a different outer delimiter. > > The kind of encoding below "*/" is error prone and makes the developer encode the real intent. > There's got to be a better way, even if it takes a new kind of doc comment delimiter for the outer. > It will be a bigger change for javac and javadoc but makes it possible to redefine/reinterpret the delimiters. > Maybe you can do something with: > > /*** > /** > * ... > */ > ***/ > > > > Regards, Roger > > On 7/7/20 6:40 AM, Johannes Kuhn wrote: >> This is a source incompatible change. >> >> It would break /* inside comments: >> >> /** >> * Determines whether or not the tokenizer recognizes C-style comments. >> * If the flag argument is {@code true}, this stream tokenizer >> * recognizes C-style comments. All text between successive >> * occurrences of {@code /*} and */ are discarded. >> *

>> * If the flag argument is {@code false}, then C-style comments >> * are not treated specially. >> * >> * @param flag {@code true} indicates to recognize and ignore >> * C-style comments. >> */ >> >> That's the javadoc of StreamTokenizer.slashStarComments(boolean). >> With your proposed change, the javadoc comment would not be closed at the end. >> >> - Johannes >> > From behrangsa at gmail.com Wed Jul 29 07:37:49 2020 From: behrangsa at gmail.com (Behrang Saeedzadeh) Date: Wed, 29 Jul 2020 17:37:49 +1000 Subject: A proposal (pre-proposal?) to add parameter groups to Java Message-ID: When we apply the Introduce Parameter Object [1 ] refactoring on methods that take many arguments we usually have to define a wrapper class for one or more of the arguments. For example, we can refactor: void line(int x1, int y1, int x2, int y2) { } line(0, 0, 10, 10); into: class Point { private final int x; private final int y; public Point(int x, int y) { this.x = x; this.y = y; } // getters } void line(Point p1, Point p2) { } line(new Point(0, 0), new Point(10, 10)); Wouldn't it be nicer if we could eliminate the need to define Point and creating p1 and p2 to wrap x1, y1, x2, and y2 and instead grouped parameters in the method declaration in a way similar to this: void line((int x, int y) p1, (int x, int y) p2) { System.out.println(p1.x + " " + p1.y); System.out.println(p2.x + " " + p2.y); } line((0, 0), (10, 10)); What do you think? P.S: Are there any existing languages with a similar feature? [1] https://refactoring.guru/introduce-parameter-object -- Best regards, Behrang Saeedzadeh From brian.goetz at oracle.com Wed Jul 29 19:18:54 2020 From: brian.goetz at oracle.com (Brian Goetz) Date: Wed, 29 Jul 2020 15:18:54 -0400 Subject: A proposal (pre-proposal?) to add parameter groups to Java In-Reply-To: References: Message-ID: <6a38dea1-750a-a137-9f26-6c44741a9eaf@oracle.com> This request is in a category that I like to call "please, can we have bad ad-hoc tuples."? ("Multiple return" is another one in this category.)? Which is to say, while it seems like it makes things better, it just moves the problem around. If you declare a method ??? void line((int x, int y) p1) { ... } what is the type of P1?? What can I do with it, besides extract x and y?? Can I return one?? Can I declare a local variable of that type?? (Your proposal suggests no to all of these, as you only mentioned method parameter grouping.) Which is to say, you are creating a new kind of structured literal `(a, b)`, but which _only_ can be used as a parameter to a method that wants one of these.? You can see how this would be limited.? The trouble with such "easy" proposals is that they help you move forward one step, and then are stuck in the exact same way as before, just one step farther. What you really want is structural tuples, where for any types T and U, `(T, U)` is a type which is an ordered pair of a `T` and `U`, and you'd be able to use this as a return type, parameter type, local variable type, array component type, type bound for generics, etc.? But, that's a much bigger thing than what you are asking.? Relatively few languages have succeed at mixing nominal and structural types very effectively (Java's nod to structural types is arrays, and there are visible seams where array types meet the rest of the type system.) Many languages (e.g, Haskell, ML) do have structural tuples. Such languages tend to integrate pattern matching into the language, so that destructuring is built into how we declare functions.? For example, in Haskell, I can define: ??? type IntInt = (Int, Int) which says IntInt is a tuple of Int and Int, and then declare a function like your line: ??? line :: IntInt -> IntInt -> () (which means "line is a function that takes two IntInt and returns void") and then I can declare a definition for line: ??? line p q = ... where each of p and q are of type IntInt.? Alternately, I can define line with a destructuring pattern match: ??? line (x1, y1) (x2, y2) = ... These two declarations are equivalent, since the type of `line` is that it takes two (int, int) pairs; the first binds p and q to pairs, and the latter matches structurally on the pairs and binds x1, y1, x2, y2 to the coordinates.? (I could do the same without having declared IntInt; it's just the equivalent of `typedef` in C.) So yes, there is precedent for such a thing -- but in languages that are pretty different from Java. What we do in the Java world, instead, is lean on _nominality_. Rather than structural types launching into being by simply uttering their structure, we declare them.? Java's nominal function types are functional interfaces; Java's nominal tuples are records. So you could declare your method as: ??? record Point(int x, int y) { } ??? void line(Point p1, Point p2) { ... } Within line(), you can (eventually) use pattern matching to destructure the point: ??? void line(Point p1, Point p2) { ??????? Point(var x1, var y1) = p1;? // destructure p1 with Point deconstructor into x1, y1 ??????? Point(var x2, var y2) = p2; ??? } (when we have destructuring patterns, which will come to records eventually.)? You might even be able to put the destructuring in the declaration (no promises!): ??? void line(Point(var x1, var y1) p1, ????????????? Point(var x2, var y2) p2) { } and then all of {x,y,p}{1,2} would be bound in the body.? This is a more general solution, since Point is an ordinary class type, so can be used anywhere. On 7/29/2020 3:37 AM, Behrang Saeedzadeh wrote: > When we apply the Introduce Parameter Object [1 > ] refactoring on methods that take many arguments we usually have to > define a wrapper class for one or more of the arguments. > > For example, we can refactor: > > void line(int x1, int y1, int x2, int y2) { > > } > > line(0, 0, 10, 10); > > > into: > > class Point { > private final int x; > private final int y; > > public Point(int x, int y) { > this.x = x; > this.y = y; > } > > // getters > } > > void line(Point p1, Point p2) { > > } > > line(new Point(0, 0), new Point(10, 10)); > > Wouldn't it be nicer if we could eliminate the need to define Point > and creating p1 and p2 to wrap x1, y1, x2, and y2 > and instead grouped parameters in the method declaration in a way similar > to this: > > void line((int x, int y) p1, (int x, int y) p2) { > System.out.println(p1.x + " " + p1.y); > System.out.println(p2.x + " " + p2.y); > } > > line((0, 0), (10, 10)); > > What do you think? > > P.S: Are there any existing languages with a similar feature? > > [1] https://refactoring.guru/introduce-parameter-object > From behrangsa at gmail.com Thu Jul 30 04:36:21 2020 From: behrangsa at gmail.com (Behrang Saeedzadeh) Date: Thu, 30 Jul 2020 14:36:21 +1000 Subject: A proposal (pre-proposal?) to add parameter groups to Java In-Reply-To: <6a38dea1-750a-a137-9f26-6c44741a9eaf@oracle.com> References: <6a38dea1-750a-a137-9f26-6c44741a9eaf@oracle.com> Message-ID: > This request is in a category that I like to call "please, can we have bad ad-hoc tuples." ("Multiple return" is another one in this category.) Which is to say, while it seems like it makes things better, it just moves the problem around. Every discussion has to start from somewhere... ?\_(?)_/? > If you declare a method > > void line((int x, int y) p1) { ... } > > what is the type of P1? What can I do with it, besides extract x and y? Can I return one? Can I declare a local variable of that type? (Your proposal suggests no to all of these, as you only mentioned method parameter grouping.) > > Which is to say, you are creating a new kind of structured literal `(a, b)`, but which _only_ can be used as a parameter to a method that wants one of these. You can see how this would be limited. The trouble with such "easy" proposals is that they help you move forward one step, and then are stuck in the exact same way as before, just one step farther. > > What you really want is structural tuples, where for any types T and U, `(T, U)` is a type which is an ordered pair of a `T` and `U`, and you'd be able to use this as a return type, parameter type, local variable type, array component type, type bound for generics, etc. But, that's a much bigger thing than what you are asking. Relatively few languages have succeed at mixing nominal and structural types very effectively (Java's nod to structural types is arrays, and there are visible seams where array types meet the rest of the type system.) > > Many languages (e.g, Haskell, ML) do have structural tuples. Such languages tend to integrate pattern matching into the language, so that destructuring is built into how we declare functions. For example, in Haskell, I can define: > > type IntInt = (Int, Int) > > which says IntInt is a tuple of Int and Int, and then declare a function like your line: > > line :: IntInt -> IntInt -> () > > (which means "line is a function that takes two IntInt and returns void") and then I can declare a definition for line: > > line p q = ... > > where each of p and q are of type IntInt. Alternately, I can define line with a destructuring pattern match: > > line (x1, y1) (x2, y2) = ... > > These two declarations are equivalent, since the type of `line` is that it takes two (int, int) pairs; the first binds p and q to pairs, and the latter matches structurally on the pairs and binds x1, y1, x2, y2 to the coordinates. (I could do the same without having declared IntInt; it's just the equivalent of `typedef` in C.) > > So yes, there is precedent for such a thing -- but in languages that are pretty different from Java. > > What we do in the Java world, instead, is lean on _nominality_. Rather than structural types launching into being by simply uttering their structure, we declare them. Java's nominal function types are functional interfaces; Java's nominal tuples are records. > > So you could declare your method as: > > record Point(int x, int y) { } > > void line(Point p1, Point p2) { ... } > > Within line(), you can (eventually) use pattern matching to destructure the point: > > void line(Point p1, Point p2) { > Point(var x1, var y1) = p1; // destructure p1 with Point deconstructor into x1, y1 > Point(var x2, var y2) = p2; > } > > (when we have destructuring patterns, which will come to records eventually.) You might even be able to put the destructuring in the declaration (no promises!): > > void line(Point(var x1, var y1) p1, > Point(var x2, var y2) p2) { } > and then all of {x,y,p}{1,2} would be bound in the body. This is a more general solution, since Point is an ordinary class type, so can be used anywhere. This would cover my use case too, if we could declare and instantiate anonymous records: void line((int x, int y) p1, (int x, int y) p2) { System.out.println(p1.x); System.out.println(p1.y); System.out.println(p2.x); System.out.println(p2.y); } line((0, 0), (10, 10)); Here `p1` and `p2` are anonymous records/tuples that have two `int` fields `x` and `y`. P.S: Is this mailing list the correct channel for us mere mortals to discuss topics like this? From david.holmes at oracle.com Thu Jul 30 05:34:41 2020 From: david.holmes at oracle.com (David Holmes) Date: Thu, 30 Jul 2020 15:34:41 +1000 Subject: A proposal (pre-proposal?) to add parameter groups to Java In-Reply-To: References: <6a38dea1-750a-a137-9f26-6c44741a9eaf@oracle.com> Message-ID: > P.S: Is this mailing list the correct channel for us mere mortals to discuss topics like this? No. This list is for "General discussion about the OpenJDK Community" [1]. Primarily new OpenJDK project proposals. I'd point you to a more appropriate list but I don't think the OpenJDK actively has such a list. Cheers, David ----- [1] https://mail.openjdk.java.net/mailman/listinfo/discuss On 30/07/2020 2:36 pm, Behrang Saeedzadeh wrote: >> This request is in a category that I like to call "please, can we have > bad ad-hoc tuples." ("Multiple return" is another one in this category.) > Which is to say, while it seems like it makes things better, it just moves > the problem around. > > Every discussion has to start from somewhere... ?\_(?)_/? > >> If you declare a method >> >> void line((int x, int y) p1) { ... } >> >> what is the type of P1? What can I do with it, besides extract x and y? > Can I return one? Can I declare a local variable of that type? (Your > proposal suggests no to all of these, as you only mentioned method > parameter grouping.) >> >> Which is to say, you are creating a new kind of structured literal `(a, > b)`, but which _only_ can be used as a parameter to a method that wants one > of these. You can see how this would be limited. The trouble with such > "easy" proposals is that they help you move forward one step, and then are > stuck in the exact same way as before, just one step farther. >> >> What you really want is structural tuples, where for any types T and U, > `(T, U)` is a type which is an ordered pair of a `T` and `U`, and you'd be > able to use this as a return type, parameter type, local variable type, > array component type, type bound for generics, etc. But, that's a much > bigger thing than what you are asking. Relatively few languages have > succeed at mixing nominal and structural types very effectively (Java's nod > to structural types is arrays, and there are visible seams where array > types meet the rest of the type system.) >> >> Many languages (e.g, Haskell, ML) do have structural tuples. Such > languages tend to integrate pattern matching into the language, so that > destructuring is built into how we declare functions. For example, in > Haskell, I can define: >> >> type IntInt = (Int, Int) >> >> which says IntInt is a tuple of Int and Int, and then declare a function > like your line: >> >> line :: IntInt -> IntInt -> () >> >> (which means "line is a function that takes two IntInt and returns void") > and then I can declare a definition for line: >> >> line p q = ... >> >> where each of p and q are of type IntInt. Alternately, I can define line > with a destructuring pattern match: >> >> line (x1, y1) (x2, y2) = ... >> >> These two declarations are equivalent, since the type of `line` is that > it takes two (int, int) pairs; the first binds p and q to pairs, and the > latter matches structurally on the pairs and binds x1, y1, x2, y2 to the > coordinates. (I could do the same without having declared IntInt; it's > just the equivalent of `typedef` in C.) >> >> So yes, there is precedent for such a thing -- but in languages that are > pretty different from Java. >> >> What we do in the Java world, instead, is lean on _nominality_. Rather > than structural types launching into being by simply uttering their > structure, we declare them. Java's nominal function types are functional > interfaces; Java's nominal tuples are records. >> >> So you could declare your method as: >> >> record Point(int x, int y) { } >> >> void line(Point p1, Point p2) { ... } >> >> Within line(), you can (eventually) use pattern matching to destructure > the point: >> >> void line(Point p1, Point p2) { >> Point(var x1, var y1) = p1; // destructure p1 with Point > deconstructor into x1, y1 >> Point(var x2, var y2) = p2; >> } >> >> (when we have destructuring patterns, which will come to records > eventually.) You might even be able to put the destructuring in the > declaration (no promises!): >> >> void line(Point(var x1, var y1) p1, >> Point(var x2, var y2) p2) { } >> and then all of {x,y,p}{1,2} would be bound in the body. This is a more > general solution, since Point is an ordinary class type, so can be used > anywhere. > > This would cover my use case too, if we could declare and instantiate > anonymous records: > > void line((int x, int y) p1, (int x, int y) p2) { > System.out.println(p1.x); > System.out.println(p1.y); > System.out.println(p2.x); > System.out.println(p2.y); > } > > line((0, 0), (10, 10)); > > Here `p1` and `p2` are anonymous records/tuples that have two `int` fields > `x` and `y`. > > P.S: Is this mailing list the correct channel for us mere mortals to > discuss topics like this? > From forax at univ-mlv.fr Thu Jul 30 07:17:38 2020 From: forax at univ-mlv.fr (Remi Forax) Date: Thu, 30 Jul 2020 09:17:38 +0200 (CEST) Subject: A proposal (pre-proposal?) to add parameter groups to Java In-Reply-To: <6a38dea1-750a-a137-9f26-6c44741a9eaf@oracle.com> References: <6a38dea1-750a-a137-9f26-6c44741a9eaf@oracle.com> Message-ID: <1050563676.63902.1596093458034.JavaMail.zimbra@u-pem.fr> ----- Mail original ----- > De: "Brian Goetz" > ?: "Behrang Saeedzadeh" , "discuss" > Envoy?: Mercredi 29 Juillet 2020 21:18:54 > Objet: Re: A proposal (pre-proposal?) to add parameter groups to Java > This request is in a category that I like to call "please, can we have > bad ad-hoc tuples."? ("Multiple return" is another one in this > category.)? Which is to say, while it seems like it makes things better, > it just moves the problem around. > > If you declare a method > > ??? void line((int x, int y) p1) { ... } > > what is the type of P1?? What can I do with it, besides extract x and > y?? Can I return one?? Can I declare a local variable of that type? > (Your proposal suggests no to all of these, as you only mentioned method > parameter grouping.) > > Which is to say, you are creating a new kind of structured literal `(a, > b)`, but which _only_ can be used as a parameter to a method that wants > one of these.? You can see how this would be limited.? The trouble with > such "easy" proposals is that they help you move forward one step, and > then are stuck in the exact same way as before, just one step farther. > > What you really want is structural tuples, where for any types T and U, > `(T, U)` is a type which is an ordered pair of a `T` and `U`, and you'd > be able to use this as a return type, parameter type, local variable > type, array component type, type bound for generics, etc.? But, that's a > much bigger thing than what you are asking.? Relatively few languages > have succeed at mixing nominal and structural types very effectively > (Java's nod to structural types is arrays, and there are visible seams > where array types meet the rest of the type system.) > > Many languages (e.g, Haskell, ML) do have structural tuples. Such > languages tend to integrate pattern matching into the language, so that > destructuring is built into how we declare functions.? For example, in > Haskell, I can define: > > ??? type IntInt = (Int, Int) > > which says IntInt is a tuple of Int and Int, and then declare a function > like your line: > > ??? line :: IntInt -> IntInt -> () > > (which means "line is a function that takes two IntInt and returns > void") and then I can declare a definition for line: > > ??? line p q = ... > > where each of p and q are of type IntInt.? Alternately, I can define > line with a destructuring pattern match: > > ??? line (x1, y1) (x2, y2) = ... > > These two declarations are equivalent, since the type of `line` is that > it takes two (int, int) pairs; the first binds p and q to pairs, and the > latter matches structurally on the pairs and binds x1, y1, x2, y2 to the > coordinates.? (I could do the same without having declared IntInt; it's > just the equivalent of `typedef` in C.) > > So yes, there is precedent for such a thing -- but in languages that are > pretty different from Java. > > What we do in the Java world, instead, is lean on _nominality_. Rather > than structural types launching into being by simply uttering their > structure, we declare them.? Java's nominal function types are > functional interfaces; Java's nominal tuples are records. > > So you could declare your method as: > > ??? record Point(int x, int y) { } > > ??? void line(Point p1, Point p2) { ... } > > Within line(), you can (eventually) use pattern matching to destructure > the point: > > ??? void line(Point p1, Point p2) { > ??????? Point(var x1, var y1) = p1;? // destructure p1 with Point > deconstructor into x1, y1 > ??????? Point(var x2, var y2) = p2; > ??? } > > (when we have destructuring patterns, which will come to records > eventually.)? You might even be able to put the destructuring in the > declaration (no promises!): > > ??? void line(Point(var x1, var y1) p1, > ????????????? Point(var x2, var y2) p2) { } > > and then all of {x,y,p}{1,2} would be bound in the body.? This is a more > general solution, since Point is an ordinary class type, so can be used > anywhere. which can be simplified to (no need to declare p1 and p2) void line(Point(var x1, var y1), Point(var x2, var y2)) { } one interesting thing is that like lambdas with functional interfaces, a record is a nominal type that can be used by inference as a structural type, so at call site, instead of writing line(new Point(1, 2), new Point(3, 4)) one can write line((1, 2), (3, 4)) and with a pinch of valhalla, if the record is declared inline inline record Point(int x, int y) { } the compiler see the method line declared as line(Point, Point) but the VM see it as line(int, int, int, int) so you get the abstraction of using Point without the cost of allocating the two Point on the heap. R?mi > > > > On 7/29/2020 3:37 AM, Behrang Saeedzadeh wrote: >> When we apply the Introduce Parameter Object [1 >> ] refactoring on methods that take many arguments we usually have to >> define a wrapper class for one or more of the arguments. >> >> For example, we can refactor: >> >> void line(int x1, int y1, int x2, int y2) { >> >> } >> >> line(0, 0, 10, 10); >> >> >> into: >> >> class Point { >> private final int x; >> private final int y; >> >> public Point(int x, int y) { >> this.x = x; >> this.y = y; >> } >> >> // getters >> } >> >> void line(Point p1, Point p2) { >> >> } >> >> line(new Point(0, 0), new Point(10, 10)); >> >> Wouldn't it be nicer if we could eliminate the need to define Point >> and creating p1 and p2 to wrap x1, y1, x2, and y2 >> and instead grouped parameters in the method declaration in a way similar >> to this: >> >> void line((int x, int y) p1, (int x, int y) p2) { >> System.out.println(p1.x + " " + p1.y); >> System.out.println(p2.x + " " + p2.y); >> } >> >> line((0, 0), (10, 10)); >> >> What do you think? >> >> P.S: Are there any existing languages with a similar feature? >> >> [1] https://refactoring.guru/introduce-parameter-object From behrangsa at gmail.com Thu Jul 30 07:54:28 2020 From: behrangsa at gmail.com (Behrang Saeedzadeh) Date: Thu, 30 Jul 2020 17:54:28 +1000 Subject: A proposal (pre-proposal?) to add parameter groups to Java In-Reply-To: <1050563676.63902.1596093458034.JavaMail.zimbra@u-pem.fr> References: <6a38dea1-750a-a137-9f26-6c44741a9eaf@oracle.com> <1050563676.63902.1596093458034.JavaMail.zimbra@u-pem.fr> Message-ID: Sweet! Best regards, Behrang Saeedzadeh (Sent from my cellphone.) On Thu, Jul 30, 2020, 5:17 PM Remi Forax wrote: > ----- Mail original ----- > > De: "Brian Goetz" > > ?: "Behrang Saeedzadeh" , "discuss" < > discuss at openjdk.java.net> > > Envoy?: Mercredi 29 Juillet 2020 21:18:54 > > Objet: Re: A proposal (pre-proposal?) to add parameter groups to Java > > > This request is in a category that I like to call "please, can we have > > bad ad-hoc tuples." ("Multiple return" is another one in this > > category.) Which is to say, while it seems like it makes things better, > > it just moves the problem around. > > > > If you declare a method > > > > void line((int x, int y) p1) { ... } > > > > what is the type of P1? What can I do with it, besides extract x and > > y? Can I return one? Can I declare a local variable of that type? > > (Your proposal suggests no to all of these, as you only mentioned method > > parameter grouping.) > > > > Which is to say, you are creating a new kind of structured literal `(a, > > b)`, but which _only_ can be used as a parameter to a method that wants > > one of these. You can see how this would be limited. The trouble with > > such "easy" proposals is that they help you move forward one step, and > > then are stuck in the exact same way as before, just one step farther. > > > > What you really want is structural tuples, where for any types T and U, > > `(T, U)` is a type which is an ordered pair of a `T` and `U`, and you'd > > be able to use this as a return type, parameter type, local variable > > type, array component type, type bound for generics, etc. But, that's a > > much bigger thing than what you are asking. Relatively few languages > > have succeed at mixing nominal and structural types very effectively > > (Java's nod to structural types is arrays, and there are visible seams > > where array types meet the rest of the type system.) > > > > Many languages (e.g, Haskell, ML) do have structural tuples. Such > > languages tend to integrate pattern matching into the language, so that > > destructuring is built into how we declare functions. For example, in > > Haskell, I can define: > > > > type IntInt = (Int, Int) > > > > which says IntInt is a tuple of Int and Int, and then declare a function > > like your line: > > > > line :: IntInt -> IntInt -> () > > > > (which means "line is a function that takes two IntInt and returns > > void") and then I can declare a definition for line: > > > > line p q = ... > > > > where each of p and q are of type IntInt. Alternately, I can define > > line with a destructuring pattern match: > > > > line (x1, y1) (x2, y2) = ... > > > > These two declarations are equivalent, since the type of `line` is that > > it takes two (int, int) pairs; the first binds p and q to pairs, and the > > latter matches structurally on the pairs and binds x1, y1, x2, y2 to the > > coordinates. (I could do the same without having declared IntInt; it's > > just the equivalent of `typedef` in C.) > > > > So yes, there is precedent for such a thing -- but in languages that are > > pretty different from Java. > > > > What we do in the Java world, instead, is lean on _nominality_. Rather > > than structural types launching into being by simply uttering their > > structure, we declare them. Java's nominal function types are > > functional interfaces; Java's nominal tuples are records. > > > > So you could declare your method as: > > > > record Point(int x, int y) { } > > > > void line(Point p1, Point p2) { ... } > > > > Within line(), you can (eventually) use pattern matching to destructure > > the point: > > > > void line(Point p1, Point p2) { > > Point(var x1, var y1) = p1; // destructure p1 with Point > > deconstructor into x1, y1 > > Point(var x2, var y2) = p2; > > } > > > > (when we have destructuring patterns, which will come to records > > eventually.) You might even be able to put the destructuring in the > > declaration (no promises!): > > > > void line(Point(var x1, var y1) p1, > > Point(var x2, var y2) p2) { } > > > > and then all of {x,y,p}{1,2} would be bound in the body. This is a more > > general solution, since Point is an ordinary class type, so can be used > > anywhere. > > which can be simplified to (no need to declare p1 and p2) > > void line(Point(var x1, var y1), Point(var x2, var y2)) { } > > one interesting thing is that like lambdas with functional interfaces, a > record is a nominal type that can be used by inference as a structural > type, so at call site, instead of writing > line(new Point(1, 2), new Point(3, 4)) > one can write > line((1, 2), (3, 4)) > > and with a pinch of valhalla, if the record is declared inline > inline record Point(int x, int y) { } > > the compiler see the method line declared as line(Point, Point) but the VM > see it as line(int, int, int, int) so you get the abstraction of using > Point without the cost of allocating the two Point on the heap. > > R?mi > > > > > > > > > On 7/29/2020 3:37 AM, Behrang Saeedzadeh wrote: > >> When we apply the Introduce Parameter Object [1 > >> ] refactoring on methods that take many arguments we usually have to > >> define a wrapper class for one or more of the arguments. > >> > >> For example, we can refactor: > >> > >> void line(int x1, int y1, int x2, int y2) { > >> > >> } > >> > >> line(0, 0, 10, 10); > >> > >> > >> into: > >> > >> class Point { > >> private final int x; > >> private final int y; > >> > >> public Point(int x, int y) { > >> this.x = x; > >> this.y = y; > >> } > >> > >> // getters > >> } > >> > >> void line(Point p1, Point p2) { > >> > >> } > >> > >> line(new Point(0, 0), new Point(10, 10)); > >> > >> Wouldn't it be nicer if we could eliminate the need to define Point > >> and creating p1 and p2 to wrap x1, y1, x2, and y2 > >> and instead grouped parameters in the method declaration in a way > similar > >> to this: > >> > >> void line((int x, int y) p1, (int x, int y) p2) { > >> System.out.println(p1.x + " " + p1.y); > >> System.out.println(p2.x + " " + p2.y); > >> } > >> > >> line((0, 0), (10, 10)); > >> > >> What do you think? > >> > >> P.S: Are there any existing languages with a similar feature? > >> > >> [1] https://refactoring.guru/introduce-parameter-object > From sebastian.sickelmann at gmx.de Fri Jul 31 14:29:06 2020 From: sebastian.sickelmann at gmx.de (Sebastian Sickelmann) Date: Fri, 31 Jul 2020 16:29:06 +0200 Subject: possible inconsistency for non-final static fields in JVMS Message-ID: Hi, I am not sure if I oversee something but from my point of view it looks like that there is a small inconsistency regarding non-final static fields. The paragraphs in question are: 4.7.2. The ConstantValue Attribute The ConstantValue attribute is a fixed-length attribute in the attributes table of a field_info structure (?4.5). A ConstantValue attribute represents the value of a constant field. There can be no more than one ConstantValue attribute in the attributes table of a given field_info structure. If the field is static (that is, the ACC_STATIC flag (Table 4.4) in the access_flags item of the field_info structure is set) then the constant field represented by the field_info structure is assigned the value referenced by its ConstantValue attribute as part of the initialization of the class or interface declaring the constant field (?5.5). This occurs prior to the invocation of the class or interface initialization method (?2.9) of that class or interface. 5.5 Initialization ... 6. ......... Then, initialize each final static field of C with the constant value in its ConstantValue attribute (?4.7.2), in the order the fields appear in the ClassFile structure. ... When you generate a class and create a non-final static fields that uses ConstantValue Attribute for initialization with no further initialization code in the static-initializing-code-block. It seems that the field is initialized as sprecified by 4.7.2. Also javac seems to create access instructions when it compiles other sources that accessed the field. (Btw. Eclipse ECJ does not, which is the reason i looked it up in the spec. It just copies the value as it would be static and final) What is the desired behavior that should be documented? Is it feasible to use the ConstantValue Attribute for non-final fields? Or should we create static initialization instructions for non-final static fields, Like javac? How should a Compiler / ClassInitializer / ClassVerifier react to non-final static fields with ConstantValue Attribute? I personally like it the way I observed it: * ConstantValue Attribute can also used for non-final fields at the field is initialized with the value. * javac compiler creates access instructions instead of copiying the value into the other class. I was only confused by the intructions generated by ECJ. What do you think? Should we clarify it in the JVMS, or is there a chapter I did not found? Kind regards Sebastian From alex.buckley at oracle.com Fri Jul 31 17:21:39 2020 From: alex.buckley at oracle.com (Alex Buckley) Date: Fri, 31 Jul 2020 10:21:39 -0700 Subject: possible inconsistency for non-final static fields in JVMS In-Reply-To: References: Message-ID: <972eb53a-295c-3efc-ac27-9c01c1f671f4@oracle.com> On 7/31/2020 7:29 AM, Sebastian Sickelmann wrote: > When you generate a class and create a non-final static field that > uses ConstantValue Attribute for initialization with no further > initialization code in the static-initializing-code-block. It seems > that the field is initialized as specified by 4.7.2. JVMS 5.5 is clear that only final static fields are auto-initialized by a JVM implementation based on their ConstantValue attributes. However, I can believe that HotSpot also auto-initializes non-final static fields based on ConstantValue. This is because JVMS 4.7.2 conceived of ConstantValue as storing values for "constant fields" -- an undefined term, though we may suppose it meant "final static fields" -- but merely required a field to be static in order to receive auto-initialization based on ConstantValue. I detected this and other incongruities in how ConstantValue is used in JDK-8013650, but the thrust of that bug was the JLS, not the JVMS; I did not want to risk incompatibilities by tightening JVMS 4.7.2 to require a field be static _and final_ field to receive auto-initialization. > What is the desired behavior that should be documented? Is it > feasible to use the ConstantValue Attribute for non-final fields? Or > should we create static initialization instructions for non-final > static fields, Like javac? How should a Compiler / ClassInitializer / > ClassVerifier react to non-final static fields with ConstantValue > Attribute? > > I personally like it the way I observed it: > * ConstantValue Attribute can also used for non-final fields at the field is initialized with the value. > * javac compiler creates access instructions instead of copiying the value into the other class. > > I was only confused by the intructions generated by ECJ. > > What do you think? > Should we clarify it in the JVMS, or is there a chapter I did not found? You should rely primarily on JVMS 5.5 -- only final static fields are auto-initialized. ConstantValue may be emitted by a compiler to store the value of a non-final static field, or the value of a final non-static field, but those are not JVMS-defined topics. Alex From brian.goetz at oracle.com Fri Jul 31 20:34:24 2020 From: brian.goetz at oracle.com (Brian Goetz) Date: Fri, 31 Jul 2020 16:34:24 -0400 Subject: A proposal (pre-proposal?) to add parameter groups to Java In-Reply-To: <1050563676.63902.1596093458034.JavaMail.zimbra@u-pem.fr> References: <6a38dea1-750a-a137-9f26-6c44741a9eaf@oracle.com> <1050563676.63902.1596093458034.JavaMail.zimbra@u-pem.fr> Message-ID: <5e6a2c1c-52b1-9faf-a055-b97c88c708a8@oracle.com> > which can be simplified to (no need to declare p1 and p2) > > void line(Point(var x1, var y1), Point(var x2, var y2)) { } > > one interesting thing is that like lambdas with functional interfaces, a record is a nominal type that can be used by inference as a structural type, so at call site, instead of writing > line(new Point(1, 2), new Point(3, 4)) > one can write > line((1, 2), (3, 4)) > > Indeed, just as functional interfaces are "nominal function types", records are "nominal tuples".? And as lambdas can be considered literals for functional interfaces, one could _imagine_ a similar conversion for records. But, before we close down this thread, I just want to clarify that Remi meant "one can write" as leaning on that imagination -- that it was imaginable that, in some future language, such a conversion is possible -- not that this is currently on the plan.