"Small" Program Challenge.

D

Daniel Pitts

Daniel Pitts said:
I've got mine down to 61 characters. See if you can match that.

Here is a new variant of the above challenge:

Write a java program (source code) with less than 4000
characters and a java command line with less than 1000
characters that writes »Hello World« followed by a newline
character and nothing else, but does so in a somewhat
surprising or unusual way.

My entry:

public class Main
{ public static void main( final java.lang.String[] args )
{ System.out.println(); System.out.print( '\n' ); }}

java -Dline.separator="Hello World" Main
Any one more:
enum Hello{Hello,World;public static void
main(String[]a){System.out.println(String.valueOf(java.util.Arrays.asList(values())).replaceAll("\\p{Punct}",""));}}
 
K

Kevin McMurtrie

Daniel Pitts said:
I saw a challenge Roedy posted on cljh, and I thought I might have a
slightly more interesting one.

Write a Java program which outputs "Hello World" followed by a new line
(and nothing else).

Now, do it using as few characters in the .java source code as possible.

I've got mine down to 61 characters. See if you can match that.

Without putting "Hello World" in the environment or using assembly:

class A{static{System.out.println("Hello World");System.exit(0);}}
 
D

Daniel Pitts

Without putting "Hello World" in the environment or using assembly:

class A{static{System.out.println("Hello World");System.exit(0);}}
Note, that doesn't work on Java 7.

You can get rid of the static with a few other tricks. You can also trim
the usage of System. to something shorter.
 
A

Arne Vajhøj

"Everyone else"? As in, all seven billion of us?!

In theory if he wait X days, then a good chunk of those 7 B would
have had a chance to go on the internet, read and reply.

In practice it will be a very small subset, but ...

Arne
 
J

javax.swing.JSnarker

In theory if he wait X days, then a good chunk of those 7 B would
have had a chance to go on the internet, read and reply.

In practice it will be a very small subset, but ...

The problem is, he said "everyone else" rather than "almost everyone
else". So "a good chunk" won't cut it.
 
A

Arne Vajhøj

I've got mine down to 61 characters. See if you can match that.

here's the obvious solution at 88 chars:

public class C{public static void main(String[]
a){System.out.println("Hello World");}}

Daniel already posted the obvious solution.

Arne
 
D

Daniel Pitts

The problem is, he said "everyone else" rather than "almost everyone
else". So "a good chunk" won't cut it.
Well, while you took me literally, my intent was to wait "for enough
people that wished to contribute to this conversation to do so."

Or for someone to find the same (or better) solution.

I suppose that a date deadline would have been more appropriate.

In any case, I think the other challenge was more interesting. My
solution to the "shortest" source is 60 characters long. The first two
lines are simply a ruler, and not part of the source code.

1 2 3 4 4 6
123456789012345678901234567890123456789012345678901234567890
enum H{W;System s;{s.out.println("Hello World");s.exit(0);}}

You would compile whatever file H was in (it needn't be in H.java since
it isn't public). Then execute with "java H"

Note, this no longer works in Java 7. It appears a method with the
signature "public static void main(String[])" is now required, where it
could have been omitted in the past (as in my example).
 
J

javax.swing.JSnarker

In any case, I think the other challenge was more interesting. My
solution to the "shortest" source is 60 characters long. The first two
lines are simply a ruler, and not part of the source code.

1 2 3 4 4 6
123456789012345678901234567890123456789012345678901234567890
enum H{W;System s;{s.out.println("Hello World");s.exit(0);}}

You would compile whatever file H was in (it needn't be in H.java since
it isn't public). Then execute with "java H"

Note, this no longer works in Java 7. It appears a method with the
signature "public static void main(String[])" is now required, where it
could have been omitted in the past (as in my example).

That's pretty silly.

Of course, if you don't require it to terminate, only to not print
anything else after "Hello World", you can use
1 2 3 4 5
123456789012345678901234567890123456789012345678901234
enum H{W;{System.out.println("Hello World");for(;;);}}

;)
 
L

Lew

The problem is, he said "everyone else" rather than "almost everyone
else". So "a good chunk" won't cut it.
Well, while you took me literally, my intent was to wait "for enough people
that wished to contribute to this conversation to do so."

Or for someone to find the same (or better) solution.

I suppose that a date deadline would have been more appropriate.

In any case, I think the other challenge was more interesting. My solution to
the "shortest" source is 60 characters long. The first two lines are simply a
ruler, and not part of the source code.

1 2 3 4 4 6
123456789012345678901234567890123456789012345678901234567890
enum H{W;System s;{s.out.println("Hello World");s.exit(0);}}

You would compile whatever file H was in (it needn't be in H.java since it
isn't public). Then execute with "java H"

Note, this no longer works in Java 7. It appears a method with the signature
"public static void main(String[])" is now required, where it could have been
omitted in the past (as in my example).

You aren't supposed to rely on a bug.

The JLS 3rd ed., which covers Java 5 and Java 6, says,
"A Java virtual machine starts up by loading a specified class and then
invoking the method main in this specified class."
<http://docs.oracle.com/javase/specs/jls/se5.0/html/execution.html>

and
"A Java virtual machine starts execution by invoking the method main of some
specified class, passing it a single argument, which is an array of strings."
<http://docs.oracle.com/javase/specs/jls/se5.0/html/execution.html#44444>

If you got it to start a different way, that was unreliable behavior and not
actually correct.

Since your proposed solution is in contravention of the Java spec, it cannot
be accepted.

Java 7 might not be the only version it fails on. How many Java systems did
you try it on? IBM's? Oracle mainframe? HP? Oracle on Solaris? IBM on Z
System? Can you be sure that Oracle's Java 6u34 will support this
non-compliant bug?

You simply cannot legitimately propose a non-compliant "solution".
 
J

javax.swing.JSnarker

You aren't supposed to rely on a bug.

It's not a bug.
The JLS 3rd ed., which covers Java 5 and Java 6, says,
"A Java virtual machine starts up by loading a specified class and then
invoking the method main in this specified class."

Exactly. It loads the specified class, as part of which that class's
static initializer runs. And if it's an enum, the enum elements'
initializers run too.

If one of those calls System.exit(0) you could argue, theoretically,
that there's an ambiguity in what the spec says should be the behavior.
On the one hand, System.exit(0) should terminate the running VM instance
when invoked. On the other hand, that precludes "and then invoking the
method main in this specified class".

However, the observed behavior seems to be out of spec. The main
method's absence should prompt an error upon the attempt to invoke it,
and did. The error being generated before the main method should be
being invoked is dissimilar from any other JVM behavior. For example, if
you create code that attempts to invoke Foo.quux() by reflection, and
there's no quux static method in class Foo, there won't be any error
until the reflection attempt, which will throw an exception when it occurs.

More generally, "and then invoking the method main" can mean one of two
things, given that main itself is static: the call to main is statically
compiled in, in which case javac should complain when compiling the call
site, or the call to main is reflective, in which case the error should
not occur until runtime and should not occur until the running code
reaches the location of the reflective invocation. We're now seeing an
error later than compile time and earlier than the running code reaches
the location of the reflective invocation, which behavior is
inconsistent with *each* static-method call semantic.
 
D

Daniel Pitts

On 17/06/2012 8:31 PM, Arne Vajhøj wrote:
On 6/17/2012 6:25 PM, javax.swing.JSnarker wrote:
On 17/06/2012 6:24 PM, Daniel Pitts wrote:
I will post my solution, once everyone else has had a chance to
attempt
the problem.

"Everyone else"? As in, all seven billion of us?!

In theory if he wait X days, then a good chunk of those 7 B would
have had a chance to go on the internet, read and reply.

In practice it will be a very small subset, but ...

The problem is, he said "everyone else" rather than "almost everyone
else". So "a good chunk" won't cut it.
Well, while you took me literally, my intent was to wait "for enough
people
that wished to contribute to this conversation to do so."

Or for someone to find the same (or better) solution.

I suppose that a date deadline would have been more appropriate.

In any case, I think the other challenge was more interesting. My
solution to
the "shortest" source is 60 characters long. The first two lines are
simply a
ruler, and not part of the source code.

1 2 3 4 4 6
123456789012345678901234567890123456789012345678901234567890
enum H{W;System s;{s.out.println("Hello World");s.exit(0);}}

You would compile whatever file H was in (it needn't be in H.java
since it
isn't public). Then execute with "java H"

Note, this no longer works in Java 7. It appears a method with the
signature
"public static void main(String[])" is now required, where it could
have been
omitted in the past (as in my example).

You aren't supposed to rely on a bug.

The JLS 3rd ed., which covers Java 5 and Java 6, says,
"A Java virtual machine starts up by loading a specified class and then
invoking the method main in this specified class."
<http://docs.oracle.com/javase/specs/jls/se5.0/html/execution.html>
My program wasn't a bug, it relied on loading the specified class, which
has the (documented) side-effect of initializing the class, which causes
the initializers to run.
and
"A Java virtual machine starts execution by invoking the method main of
some specified class, passing it a single argument, which is an array of
strings."
<http://docs.oracle.com/javase/specs/jls/se5.0/html/execution.html#44444>

If you got it to start a different way, that was unreliable behavior and
not actually correct.
The wording in the 3rd edition is different enough to explain the
difference in behavior, and so Java 6 in fact has the required behavior
of loading the class. Java 7 doesn't require the class be loaded before
invoking the method.
Since your proposed solution is in contravention of the Java spec, it
cannot be accepted.
For Java 7, I agree. Java 6 it meets the spec.
Java 7 might not be the only version it fails on. How many Java systems
did you try it on? IBM's? Oracle mainframe? HP? Oracle on Solaris? IBM
on Z System? Can you be sure that Oracle's Java 6u34 will support this
non-compliant bug?
Those wouldn't be compliant to JLS 2nd edition then.
You simply cannot legitimately propose a non-compliant "solution".
The idea of this "Challenge" was to think outside the box. If it works,
its a solution.
 
J

javax.swing.JSnarker

The wording in the 3rd edition is different enough to explain the
difference in behavior, and so Java 6 in fact has the required behavior
of loading the class. Java 7 doesn't require the class be loaded before
invoking the method.

Sounds like a bug in the spec, to me. How can invoking a method *ever*
not require the class containing that method be loaded first?
 
J

javax.swing.JSnarker

Before the code was:

1. Load class with initialization.
2. Run 'main' method.

Now, they do the special step of loading without initialization:

1. Load class without initialization.
2. Verify 'main' method, throw error if not present
3. Initialize class
4. Run 'main' method.

You can see how the new method takes more effort.

What was the purpose of such a change? It now is a special case
dissimilar to all other instances of JVM classloading.
 
L

Lew

On 6/17/12 5:55 PM, javax.swing.JSnarker wrote:
On 17/06/2012 8:31 PM, Arne Vajhøj wrote:
On 6/17/2012 6:25 PM, javax.swing.JSnarker wrote:
On 17/06/2012 6:24 PM, Daniel Pitts wrote:
I will post my solution, once everyone else has had a chance to
attempt
the problem.

"Everyone else"? As in, all seven billion of us?!

In theory if he wait X days, then a good chunk of those 7 B would
have had a chance to go on the internet, read and reply.

In practice it will be a very small subset, but ...

The problem is, he said "everyone else" rather than "almost everyone
else". So "a good chunk" won't cut it.

Well, while you took me literally, my intent was to wait "for enough
people
that wished to contribute to this conversation to do so."

Or for someone to find the same (or better) solution.

I suppose that a date deadline would have been more appropriate.

In any case, I think the other challenge was more interesting. My
solution to
the "shortest" source is 60 characters long. The first two lines are
simply a
ruler, and not part of the source code.

1 2 3 4 4 6
123456789012345678901234567890123456789012345678901234567890
enum H{W;System s;{s.out.println("Hello World");s.exit(0);}}

You would compile whatever file H was in (it needn't be in H.java
since it
isn't public). Then execute with "java H"

Note, this no longer works in Java 7. It appears a method with the
signature
"public static void main(String[])" is now required, where it could
have been
omitted in the past (as in my example).

You aren't supposed to rely on a bug.

The JLS 3rd ed., which covers Java 5 and Java 6, says,
"A Java virtual machine starts up by loading a specified class and then
invoking the method main in this specified class."
<http://docs.oracle.com/javase/specs/jls/se5.0/html/execution.html>
My program wasn't a bug, it relied on loading the specified class, which
has the (documented) side-effect of initializing the class, which causes
the initializers to run.

Not true.
The wording in the 3rd edition is different enough to explain the

How, exactly?
difference in behavior, and so Java 6 in fact has the required behavior
of loading the class. Java 7 doesn't require the class be loaded before
invoking the method.

Java never required initialization upon load, and in fact was very specificabout
the circumstances under which a class initializes.

<http://docs.oracle.com/javase/specs/jls/se5.0/html/execution.html#12.4.1>
"A class or interface type T will be initialized immediately before the first occurrence of any one of the following:

- T is a class and an instance of T is created.
- T is a class and a static method declared by T is invoked.
- A static field declared by T is assigned.
- A static field declared by T is used and the field is not a constant variable (§4.12.4).
- T is a top-level class, and an assert statement (§14.10) lexically nested within T is executed.

Invocation of certain reflective methods in class Class and in package java..lang.reflect also
causes class or interface initialization. A class or interface will not be initialized under any
other circumstance."

You are saying that the first case applies, an instance is created because of
the third case, a static field is assigned. But that assignment shouldn't happen
yet because nothing has invoked the class legally, i.e., the sequence to invoke
'main()' didn't happen. It is, in fact, the invocation of 'main()' that is supposed to
trigger the initialization.

Historically Sun's JVMs have had bugs in this area, by their own admission.

I read the JLS 3rd edition as not allowing the behavior you claim as a solution.
There has been no change in the language regarding how a JVM starts.

So if the trick violates Java 7, and the language hasn't changed, it must also violate
Java 6, and that it worked was a bug.

Perhaps if you could quote the exact differences in wording to which you refer?
 
L

Lew

It's not a bug.


Exactly. It loads the specified class, as part of which that class's
static initializer runs. And if it's an enum, the enum elements'
initializers run too.

Loading does not imply initialization, and in fact cannot.

The JVM is forbidden to initialize a class except under specific
circumstances, a
If one of those calls System.exit(0) you could argue, theoretically,
that there's an ambiguity in what the spec says should be the behavior.
On the one hand, System.exit(0) should terminate the running VM instance
when invoked. On the other hand, that precludes "and then invoking the
method main in this specified class".

However, the observed behavior seems to be out of spec. The main
method's absence should prompt an error upon the attempt to invoke it,
and did. The error being generated before the main method should be
being invoked is dissimilar from any other JVM behavior. For example, if
you create code that attempts to invoke Foo.quux() by reflection, and
there's no quux static method in class Foo, there won't be any error
until the reflection attempt, which will throw an exception when it occurs.

More generally, "and then invoking the method main" can mean one of two
things, given that main itself is static: the call to main is statically
compiled in, in which case javac should complain when compiling the call
site, or the call to main is reflective, in which case the error should
not occur until runtime and should not occur until the running code
reaches the location of the reflective invocation. We're now seeing an
error later than compile time and earlier than the running code reaches
the location of the reflective invocation, which behavior is
inconsistent with *each* static-method call semantic.

--
public final class JSnarker
extends JComponent
A JSnarker is an NNTP-aware component that asynchronously provides
snarky output when the Ego.needsPuncturing() event is fired in cljp.





It's not a bug.


Exactly. It loads the specified class, as part of which that class's
static initializer runs. And if it's an enum, the enum elements'
initializers run too.

If one of those calls System.exit(0) you could argue, theoretically,
that there's an ambiguity in what the spec says should be the behavior.
On the one hand, System.exit(0) should terminate the running VM instance
when invoked. On the other hand, that precludes "and then invoking the
method main in this specified class".

However, the observed behavior seems to be out of spec. The main
method's absence should prompt an error upon the attempt to invoke it,
and did. The error being generated before the main method should be
being invoked is dissimilar from any other JVM behavior. For example, if
you create code that attempts to invoke Foo.quux() by reflection, and
there's no quux static method in class Foo, there won't be any error
until the reflection attempt, which will throw an exception when it occurs.

More generally, "and then invoking the method main" can mean one of two
things, given that main itself is static: the call to main is statically
compiled in, in which case javac should complain when compiling the call
site, or the call to main is reflective, in which case the error should
not occur until runtime and should not occur until the running code
reaches the location of the reflective invocation. We're now seeing an
error later than compile time and earlier than the running code reaches
the location of the reflective invocation, which behavior is
inconsistent with *each* static-method call semantic.

--
public final class JSnarker
extends JComponent
A JSnarker is an NNTP-aware component that asynchronously provides
snarky output when the Ego.needsPuncturing() event is fired in cljp.





It's not a bug.


Exactly. It loads the specified class, as part of which that class's
static initializer runs. And if it's an enum, the enum elements'
initializers run too.

Not true. Loading does not imply initialization, and in fact is forbidden to.

The initializers only run under specific circumstances, separately from
loading.

I have cited the relevant JLS sections.
If one of those calls System.exit(0) you could argue, theoretically,
that there's an ambiguity in what the spec says should be the behavior.
On the one hand, System.exit(0) should terminate the running VM instance
when invoked. On the other hand, that precludes "and then invoking the
method main in this specified class".

False premise, unreliable conclusion. Loading does not imply initialization.
However, the observed behavior seems to be out of spec. The main
method's absence should prompt an error upon the attempt to invoke it,

Indeed.
 
J

javax.swing.JSnarker

Loading does not imply initialization, and in fact cannot.

Wrong. Loading and initialization go hand-in-hand.
The JVM is forbidden to initialize a class except under specific
circumstances, a
What?


Not true. Loading does not imply initialization, and in fact is forbidden to.

Wrong. Loading and initialization go hand-in-hand.
The initializers only run under specific circumstances, separately from
loading.

I have cited the relevant JLS sections.

You haven't cited anything except my own post, and your quotation of
*that* was a jumbled mess with some sections repeated for some reason.
False premise, unreliable conclusion.

On your part, Lew.
Loading does not imply initialization.

Wrong. Loading and initialization go hand-in-hand.

And not before.

When invoking a static method of a non-loaded class, the standard
procedure always has been:

Load the class.
Initialize the class.
Invoke the method.

In particular, the spec requires that in this:

class A {
static int x;

static { x = 100; }

static int foo () { return x; }
}

a call to A.foo() should return 100, not 0. If it can attempt to invoke
foo before the static initializer has executed that would be violated.

On the other hand, it complaining that a reflective call to A.bar()
can't be resolved sooner than the loading and initializing of A as part
of trying to resolve bar is equally anomalous. If it hasn't loaded and
initialized A yet, how can it be sure whether or not it has a method
bar? On the other hand, if it's a non-reflective call the code calling
bar won't even compile.
 
J

javax.swing.JSnarker

"A class or interface type T will be initialized immediately before the first occurrence of any one of the following:

- T is a class and a static method declared by T is invoked.

This is the case that seems to be applicable here. It should not be
erroring out trying to invoke main until after initialization, because
the initialization must occur immediately *before* the invocation
attempt (since it must have occurred if that attempt succeeds or again
the spec is violated).
You are saying that the first case applies, an instance is created because of
the third case, a static field is assigned. But that assignment shouldn't happen
yet because nothing has invoked the class legally, i.e., the sequence to invoke
'main()' didn't happen. It is, in fact, the invocation of 'main()' that is supposed to
trigger the initialization.

That's backwards. Initialization must *precede* the invocation, not
*follow* it. The JVM is required to initialize the class just *before*
attempting to invoke the main method, and indeed up through Java 6 that
is precisely what it did.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads

Programming Challenge 2
Virtuous Hacking challenge 13
Tutorial challenge program help 19
small program 49
JFrame stays unusably small in applet 5
Tasks 1
[Challenge] Cookie Monster! 6
Html download challenge 25

Members online

No members online now.

Forum statistics

Threads
473,768
Messages
2,569,574
Members
45,048
Latest member
verona

Latest Threads

Top