-3
 int a; // why can't I put this in the condition itself
 if((a = readData()) > 0){ 
     // do something..
 }

I'm wondering why java and javascript don't allow me to declare my variable in the (condition). I understand that it has to do with the fact that a variable declaration has to be the first thing on the line -except for for loops- but what is the underlying reason ? In C++ it seems like they can do it. I don't know C++ so apologizes if I misunderstood.

Community
  • 1
  • 1
Ced
  • 15,847
  • 14
  • 87
  • 146
  • 1
    Java is unrelated to Javascript, and the language simply doesn't allow you to declare a variable in an `if`. – Elliott Frisch Jan 09 '17 at 01:19
  • @ElliottFrisch I mentioned both languages because those are two languages I know and I expect the underlying reason to be the same for both of them. Sorry if that wasn't clear. My question is why don't they allow it ? – Ced Jan 09 '17 at 01:22
  • I think you need to ask James Gosling why he didn't include it. What's wrong with `int a = readData(); if (a > 0) ...`? It's more readable than trying to cram too much stuff onto one line. – ajb Jan 09 '17 at 01:24
  • @ajb It would be useful to restrict the scope. – shmosel Jan 09 '17 at 01:25
  • 1
    @shmosel `{int a = readData(); if (a > 0) ... }` – Elliott Frisch Jan 09 '17 at 01:28
  • I'm not saying it's a requirement obviously. But surely you would agree the proposed syntax would be cleaner. – shmosel Jan 09 '17 at 01:29
  • May be initialization expression doesn't return any value . – passion Jan 09 '17 at 01:30
  • @shmosel If you're saying the syntax in the question would be cleaner--no, I don't agree. I don't think it's "clean" to combine an assignment and an `if` in the same statement. To my eyes, that makes things too complicated. – ajb Jan 09 '17 at 02:02
  • @ajb I'm saying it would be cleaner than @ElliotFrisch's approach. It wouldn't be very different from a `for` IMO. – shmosel Jan 09 '17 at 02:20
  • @Ced If they are different languages why would the underlying reason necessarily be the same? – user207421 Jan 09 '17 at 02:49
  • @ElliottFrisch You could have answered the question instead of saying it just doesn't allow me to do that. Now that my brain fart is gone I see the obvious reason. Check my answer, that tells a lot about the state of stackoverflow if I had to go to such length to understand something that I should have understood in minutes. – Ced Jan 09 '17 at 10:13

4 Answers4

3

The reason is simplicity of scope rules. If you allowed variable declaration within a condition, you'd have to define the scope of such a variable, and what it means for a declaration to have a value. Neither is straightforward. Requiring variables in an expression to be already defined is simple, and has no downside. Allowing that is complicated, and would obfuscate the source. That is a posteriori reasoning, of course. It might just be that the language designers had other reasons in the moment.

Why do you care? Bottom line: because the JLS says so.

Lew Bloch
  • 3,364
  • 1
  • 16
  • 10
0

According to the Java Language Specification (https://docs.oracle.com/javase/specs/jls/se8/html/jls-14.html#jls-14.9), an if statement has the following form:

if ( Expression ) Statement [else ...]

A variable assignment, aka an AssignmentExpression, is just one of many sub-types of the abstract Expression (https://docs.oracle.com/javase/specs/jls/se8/html/jls-15.html#jls-15.26), so you can use its result (which happens to be the value that was assigned) in your if statement.

Michael P
  • 153
  • 9
-1

Its simpel: A If-statement ist defined as:

if (Boolean) {...

We can now substitute:

if (var1 operator var2){... // with "_ operator _" => Boolean

If we now put i=1 as var1 we would get:

if ((i=1) operator var2){... // compile error: i cannot resolved to a local variable

or int i = 1:

if ((int i = 1) operator var2){...

The obvious problem is: int i = 1 is a type declaration and not a variable and we learned above thet the if clause only accept Boolean variables or expression which lead to a Boolean vaiable...!

Thomas Meyer
  • 384
  • 1
  • 11
  • I don't think this is an answer. It looks to me like you're restating what the OP already knows. The question is, _why_ isn't that syntax allowed, which the answer doesn't address at all. – ajb Jan 09 '17 at 02:04
-1

I wasn't satisfied with the answer here, so like any normal person would do, I learned java byte code. Well, sort of... the rudimentary. So if anyone read this keep in mind that my findings have some extrapolations in them and could be inaccurate.. However it makes sens why it doesn't happen java (much less in javascript where my head was at when asking this) and it is ho so simple.


So now the byte code part:

here is what I got for this:

    int a = 9;
    System.out.println(a);  // just here to prevent some optimization
    if((a = 18) > 15){
        System.out.println(a);
    }


Code:
   0: bipush        9
   2: istore_1
                          // -- removed the System.out.print -- 
  10: bipush        18
  12: dup
  13: istore_1
  14: bipush        15
  16: if_icmple     26

Here is what happens:

0: push 9 onto the stack
2: store it in the var a
10: push 18 onto stack
12: duplicate 18 on top of the stack
13: store it in var a
14 : push 15
16: the if statement if value1 is less than or equal to value2, branch to instruction at branchoffset.

So since the content of the condition is evaluated before the if statement itself, if we declared int a in the condition, depending on where we define the scope of int a to be, there would be scoping issues.


If it was inside the if block:

If we suppose int a would be scoped into the if block, it must still be evaluated before reaching it and thus being out of scope !

In other words:

while((int a = 9) > 15)

int a = 9 would be evaluated before reaching the while condition, thus being out of the scope we just defined. We wouldn't enter the while block, but the value of a is well defined! Makes sens why it doesn't happen, doesn't it ?


If we go the other way and says that it is just a shortcut for this:

 int a;
 while((a = 9) > 15)

Then the language wouldn't be consistent and would bring many confusing code! See the for loop, the variable defined in it is scoped in it not outside for example.

It still doesn't make any sens why it's not possible to do in javascript though. However I don't care enough to find out.

I hope I made it clear, at least it makes some sens to me and I learned something. On a side note, I don't think my question really warranted so much down votes, even tho the answer seems obvious to me now. Not every question on stackoverflow has to be a practical one..

Ced
  • 15,847
  • 14
  • 87
  • 146
  • You're confusing 3 things which have little to do with each other: scope, bytecode, and syntax. The first comment on your question was the correct answer. – shmosel Jan 10 '17 at 22:08