This question already has answers here:
(Compiler) else if(true) vs else scenario
(8 answers)
Closed 4 years ago.
The following code does not give the compile-error Unreachable statement.
if(true)return;
int x;
For years I believed that it's because the compiler does not pay much attention to the conditions given.
Today I found that the compiler understands the conditions,
int x;
if (true) {
x = 0;
}
int y = x;
because if not this should result in another compile-error variable x might not have been initialized. Which in fact compiles and runs perfectly. So,
Does the java compiler understand conditions given in if statements?
Unreachable Statements is devoted to a precise explanation of the word "reachable." The idea is that there must be some possible execution path from the beginning of the constructor, method, instance initializer, or static initializer that contains the statement to the statement itself. The analysis takes into account the structure of statements. Except for the special treatment of while, do, and for statements whose condition expression has the constant value true, the values of expressions are not taken into account in the flow analysis.
For example, a Java compiler will accept the code:
int n = 5;
while (n > 7) k = 2;
even though the value of n is known at compile time and in principle it can be known at compile time that the assignment to k can never be executed.
The rules in this section define two technical terms:
whether a statement is reachable
whether a statement can complete normally
The definitions here allow a statement to complete normally only if it is reachable.
To shorten the description of the rules, the customary abbreviation "iff" is used to mean "if and only if."
Source :
Java Language Specification (SE 7 Edition)
Chapter 14 - Blocks and Statements
Section 14.21 - Unreachable Statements
This occured while I was tackling a 'Cracking the Coding interview' question:
Write a function to swap a number in place (that is, without temporary variables)
I decided to write up my solution in Java (because I plan on using Java in my internship interviews.)
I came up with a solution that I was almost confident was the right answer (because I did it in one line):
public static void main(String args[]) {
int a = 5;
int b = 7;
a = b - a + (b = a);
System.out.println("a: " + a + " b: " + b);
}
Surely enough, this code executes the desired result. a == 7 and b == 5.
Now here's the funny part.
This code won't run in C++ nor is this solution in the back of the book.
So my question is: Why exactly does my solution work? I am assuming Java does things differently than other languages?
Looks at the Java Language Specification, section 15.7 (Evaluation Order):
The Java programming language guarantees that the operands of
operators appear to be evaluated in a specific evaluation order,
namely, from left to right.
So in Java the evaluation order is well-defined and does what you expect.
The C++ specification doesn't provide such a guarantee; in fact it's Undefined Behavior so the program could literally do anything.
Quoting from the cppreference, noting that no sequencing rule exists for sequencing operands to arithmetic operators:
If a side effect on a scalar object is unsequenced relative to a value
computation using the value of the same scalar object, the behavior is
undefined.
The following blockquote is taken from http://www.oracle.com/technetwork/java/javase/documentation/codeconventions-137265.html
Do not use the assignment operator in a place where it can be easily confused with the equality operator. Example:
if (c++ = d++) { // AVOID! (Java disallows)
...
}
should be written as
if ((c++ = d++) != 0) {
...
}
I am confused by the line
if ((c++ = d++) != 0) {
Any clarification on this would be appreciated.
At the very beginning of the page I can see -
This page is not being actively maintained. Links within the documentation may not work and the information itself may no longer be valid. The last revision to this document was made on April 20, 1999
if ((c++ = d++) != 0) {
//logic
}
Syntax is not even valid (Using Java6). It gives me
The left-hand side of an assignment must be a variable
You need to assign c++ to some variable.
In contrast with other languages like C, Java's scalar primitives (integers, etc.) cannot be used as booleans. In other words, 0 is in no sense either true or false. Only whether something is equal to 0 can be true or false.
They're just trying to say that the compiler requires the condition of an if statement to evaluate to a boolean value. If you know what you're doing, and decide to put actual code with side effects as the condition, you're required to make the expression evaluate to a value of type boolean.
Whereas the anti-pattern code in the example would work out in a programming language like C where boolean values are actually integers (where zero is false, and non-zero is true), the proper way to do this in Java is to actually compare the result to 0.
(c++ = d++) is an integer expression, not a boolean expression. It evaluates to whatever integer c got assigned to in the c++ = d++ assignment. Hence if (c++ = d++) { is a non starter in java.
So the comparison with 0 is what it takes to convert the integer expression to boolean.
And I think it goes without saying. Code written as follows:
if ((c++ = d++) != 0) {
is just bad coding. First, the the inner assignment within a comparison. Then the postfix operators within it. Both contribute to a block of code that is difficult to read, easy opportunities for bugs, difficult to maintain etc... Better written as follows:
c = d;
c++;
d++;
if (c == d) {
But you already knew that. :)
A couple of my friends are working on a simple recursive function in SML, and so far have failed to create it due to a lack of documentation of SML and its syntax. I've tried to find something myself in order to help them, but have been unsuccessful so far.
Here's the function I made in Java. It works and I'd like to convert the concept of this function into SML.
private static int shift;
private static boolean firstRun = true;
private static void crackThatThing(int clearText, int cryptoText) {
if (firstRun) { // Make sure that the shift is only set once
firstRun = false;
shift = ((cryptoText % 10) - (clearText % 10)) % 10;
crackThatThing((clearText / 10), (cryptoText / 10));
} else {
if (clearText > 0 && cryptoText > 0) {
if (shift != ((cryptoText % 10) - (clearText % 10)) % 10) {
// The shift value changed - this is not a valid encryption!
System.out.println("This is not a valid encryption!");
} else {
// If the shift value is the same as before, continue with the next number
crackThatThing((clearText / 10), (cryptoText / 10));
}
} else {
// The encryption is valid
System.out.println("The encryption is valid. The shift is: " + shift);
}
}
}
Any ideas?
Edit: Here's what I think it should be
The following code is based on absolutely no previous experience with SML whatsoever, and since I actually deleted the code I had written, this is based on the bits I can remember. I know it's wrong and very likely hideous code, but please bear with me on this one.
var notValid = "This is not a valid encryption!";
var valid = "The encryption is valid. The shift is: ";
var shift = 11; (* This is just to initialize it *)
var firstRun = true;
fun crackThatThing(clearText, cryptoText) =
if firstRun = true then
firstRun = false andalso
shift = ((cryptoText mod 10) - (clearText mod 10) mod 10) andalso
crackThatThing(clearText div 10, cryptoText div 10)
else
if clearText > 0 andalso cryptoText > 0 then
if not (shift = ((cryptoText mod 10) - (clearText mod 10) mod 10)) then
notValid
else
crackThatThing(clearText div 10, cryptoText div 10)
else
valid;
There exists plenty of books and resources on the net (See below).
You need the functions div and mod and then some general functional principles, such as recursion to solve this.
I'm not going to give you any code for this as it is a weekly assignment. However I'll be more than happy to help on more specific issues not related to this assignment.
Links
A Gentle Introduction to ML
Tips for Computer Scientists on Standard ML (Revised)
The Standard ML Basis Library
Programming in Standard ML '97
Danish text: Supplerende noter i funktionsprogrammering (I can't find a link to the newest version)
All the examples I've seen only cover very simple if-else statements
Then I would dare to say that you haven't looked properly! See the list of links above, at least a few of them contains introductions to SML on different levels.
the documentation of SML is ridiculous compared to other languages.
You are not really referring to which documentation you are talking about, but I can only guess that it is not the definition/commentary. Anyways it seems you don't know what you are talking about!
My friends have been able to "convert" it to SML using two functions instead of just one, but it seems stupid to do that when it should be really simple.
Indeed, and it is actually really simple once you understand the functional principles. Again I will be happy to give pointers on specific issues.
From looking at your code, the main thing that I see is that you're trying to assign to variables (you wrote something like firstRun = false, but = is actually the equality operator). Variables in ML cannot be assigned to (so "variable" is a misnomer; they are actually constants in a sense). You can either re-write your code to not use mutation, or you can use explicit mutable cells (call "references"). For mutable cells, basically, you use the ref function to create a mutable cell with a given initial value. You use the ! operator to get the value of the cell; and you use the := operator to change the value inside the cell.
However, I think it would be a bad idea in your case to use mutable global state. It is bad style and it seems it would make your function not usable more than once. From what I can see, you use global variables to keep track of information as you make recursive calls to your function. You can instead define an inner function (local to the outer function) that does the recursion, and that way you can keep track of stuff in local variables of the outer function and/or pass additional variables when you recurse the inner function, without exposing state to the global scope.
Also you don't declare variables with var; you probably want val
I've been writing Java for the last couple of years , and now I've started to write in python (in addition).
The problem is that when I look at my Python code it looks like someone tried to hammer Java code into a python format , and it comes out crappy because - well , python ain't Java.
Any tips on how to escape this pattern of "Writing Java in Python"?
Thanks!
You might consider immersing yourself in the Python paradigms. The best way is to first know what they are then explore the best practices by reading some literature and reviewing some code samples. I recommend Learning Python by Mark Lutz; great for beginners and advanced users.
You'll do yourself a great injustice if you program with Python and fail to leverage all of the built-in, developer-friendly, Pythonic syntax.
As my French teacher used to say, "French isn't just English with different words."
If you are new to Python and coming from Java (or C#, or other similar statically typed OO language), these classic articles from PJ Eby and Ryan Tomayko are necessary reading:
Python Is Not Java (PJE)
Java is not Python, either (PJE)
Python Interfaces are not Java Interfaces (PJE)
The Static Method Thing (Tomayko)
Getters/Setters/Fuxors (Tomayko)
You could start by reading The Zen of Python. It'll give you some insight into how Python code is supposed to be written, provided you understand the language enough to understand what it's talking about. :-)
Some of the major ways in which Python differs from C/Java-like languages are:
List comprehensions.
Support for functional programming.
The use of certain Pythonic constructs instead of similar C-like constructs although both seem to work (list comprehensions can be argued to be a part of this, but there are others).
There are others, but these are the main ones that bugged me when I first started Python (and I had come from years of Java like you).
Before using any of these, it is helpful to understand why you should go for pythonic code rather than the usual C/Java way in Python, although both give you the same output.
For starters, Python provides some powerful features not available in C/Java that makes your code much clearer and simpler (although this is subjective, and might not look any better to someone coming from Java at first). The first two points fall into this category.
For example, support for functions as first class objects and closures makes it easy to do things that would need all kinds of weird acrobatics with inner classes in Java.
But a major reason is that Python is an interpreted language, and certain constructs are much faster than the equivalent C/Java-like code. For example, list comprehensions are usually a lot faster than an equivalent for-loop that iterates over the indices of a list and accesses each item by index. This is a very objective benefit, and IMHO a lot of the "Python in way too slow" way of thinking comes from using Java-style code shoe-horned into Python.
One of the best ways to learn about pythonic code is to read other people's code. I actually learnt a lot by looking at Python code posted in answers to SO questions. These often come with explanations and it is usually obvious why it is better than non-pythonic code (speed, clarity, etc.).
Edit:
Of course, there are other ways of getting other people's code. You can also download and look through the code of any good open source Python project. Books are also a good resource, I would recommend O'Reilly Python Cookbook. It has lots of useful code examples and very detailed explanations.
1) Python supports many (but not all) aspects of
object-oriented programming; but it is
possible to write a Python program without
making any use of OO concepts.
1) Java supports only object-oriented
programming.
2) Python is designed to be used interpretively.
A Python statement may be entered at the
interpreter prompt
(>>>)
, and will be executed
immediately. (Implementations make some
use of automatic compilation into bytecodes
(.pyc files).
2) Programs written in Java must be explicitly
compiled into bytecodes (.class files),
though an IDE may do this automatically in a
way that is transparent to the user. Java does
not support direct execution of statements -
though there are tools like Dr. Java that
support this.
3) Python is dynamically typed:
• A variable is introduced by assigning a
value to it. Example:
someVariable = 42
• A variable that has been assigned a value of
a given type may later be assigned a value
of a different type. Example:
someVariable = 42
someVariable = 'Hello, world'
3) Java is
statically typed
:
• A variable must be explicitly declared to be
of some type before assigning a value to it,
though declaration and assignment may be
done at the same time. Examples:
int someVariable;
int someVariable = 42;
• A variable that has been declared to be of a
particular type may not be assigned a value
of a different type.
4) Python supports the following built-in data
types:
Plain integers (normally 32-bit integers in
the range -2147483648 through
2147483647).
• Long integers (size limited only by memory
size of the machine running on)
• Booleans (False and True).
• Real numbers.
• Complex numbers.
In addition, Python supports a number of
types that represent a collection of values -
including strings, lists, and dictionaries.
4) Java has two kinds of data types: primitive
types and reference types. Java supports the
following primitive data types:
• byte - 8-bit integers
• short - 16-bit integers
• int - 32-bit integers
• long - 64-bit integers (Java also supports a
class java.math.BigInteger to represent
integers whose size is limited only by
memory)
• float - 32-bit real numbers.
• double - 32-bit real numbers.
• boolean - (false and true).
• char - a single character.
In addition, Java supports arrays of any type
as the reference types, and the API includes
the class String and a large number of classes
used for collections of values.
5)
Python is line-oriented:
statements end at the
end of a line unless the line break is explicitly
escaped with . There is no way to put more
than one statement on a single line.
Examples:
this is a statement
this is another statement
this is a long statement that extends over more \
than one line
5)
Statements in Java always end with a
semicolon (;)
. It is possible for a statement to
run over more than one line, or to have
multiple statements on a single line.
Examples:
this is a statement;
this is another statement;
this is a long statement that extends over more
than one line;
a statement; another; another;
6)
Python comments begin with #
and extend to
the end of the line. Example:
This is a comment
A new statement starts here
6) Java has two kinds of comments. A comment
beginning with // extend to the end of the
line (like Python comments). Comments can
also begin with /* and end with */. These
can extend over multiple lines or be
embedded within a single line. Examples:
// This is a comment
A new statement starts here
/* This is also a comment */
/* And this is also a comment, which is
long enough to require several lines
to say it. */
Statement starts /* comment */ then continues
7) Python strings can be enclosed in either single
or double quotes (' or ""). A character is
represented by a string of length 1. Examples:
'This is a string'
"This is also a string" # Equivalent
'c' # A string
"c" # An equivalent string
Python uses the following operators for
constructing compound boolean expressions:
and, or and not. Example:
not(x > 0 and y > 0) or z > 0
7) Java strings must be enclosed in double
quotes (""). A character is a different type of
object and is enclosed in single quotes (').
Examples:
"This is a String"
'c' // A character, but not a String
Java uses the following operators for
constructing compound boolean expressions:
&&, ||, ! and ^ (meaning exclusive or)
Example:
! (x > 0 && y > 0) || z > 0 ^ w > 0
8) In Python, the comparison operators
(>, <, >=, <=, == and !=) can be applied to numbers
,
strings, and other types of objects), and
compare values in some appropriate way (e.g.
numeric order, lexical order) where possible.
8) In Java, most of the comparison operators
( >, <, >=, and <=) can be applied only to
primitive types. Two (== and !=) can be
applied to any object, but when applied to
reference types they test for same (different)
object rather than same (different) value.
9) There is no universally-accepted Python
convention for naming classes, variables,
functions etc.
9) By convention, most names in Java use mixed
case. Class names begin with an uppercase
letter; variable and function names begin with
a lowercase letter. Class constants are named
using all uppercase letters with underscores.
Examples:
AClassName
aVariableName
aFunctionName()
A_CLASS_CONSTANT
10) Python definite looping statements have the
form for variable in expression: Example:
for p in pixels:
something
10) Java has two kinds of definite looping
statements. One has the form
for (variable in collection) Example:
for (p in pixels)
something;
11) Python uses the built-in function range() with
for to loop over a range of integers.
Examples:
for i in range(1, 10)
something
(i takes on values 1, 2, 3, 4, 5, 6, 7, 8, 9)
for i in range(1, 10, 2)
something
(i takes on values 1, 3, 5, 7, 9)
11) Java uses a different form of the for to loop
over a range of integers. Examples:
for (int i = 1; i < 10; i ++)
something;
(i takes on values 1, 2, 3, 4, 5, 6, 7, 8, 9)
for (int i = 1; i < 10; i += 2)
something;
(i takes on values 1, 3, 5, 7, 9)
12) Python conditional statements have the form
if condition: and an optional else part has the
form else:. The form elif condition: is
allowed as an alternative to an else:
immediately followed by an if. Examples:
if x < 0:
something
if x < 0:
something
else:
something different
if x < 0:
something
elif x > 0:
something different
else:
yet another thing
12) Java conditional statements have the form
if (condition) and an optional else part has
the form else (no colon) There is no elif
form - else if is used directly. Examples:
if (x < 0)
something;
if (x < 0)
something;
else
something different;
if (x < 0)
something;
else if (x > 0)
something different;
else
yet another thing;
13) The scope of a Python conditional or looping
statement is denoted by indentation. (If
multiple lines are to be included, care must be
used to be sure every line is indented
identically). Examples:
if x < 0:
do something
do another thing regardless of the value of x
if x < 0:
do something
do something else
do yet a third thing
do another thing regardless of the value of x
13) The scope of a Java conditional or looping
statement is normally just the next statement.
Indentation is ignored by the compiler
(though stylistically it is still highly desirable
for the benefit of a human reader). If
multiple lines are to be included, the scope
must be delimited by curly braces ({ , }).
(Optionally, these can be used even if the
scope is a single line.) Examples:
if (x < 0)
do something;
do another thing regardless of the value of x;
if (x < 0)
do something; // Bad style-don't do this!
do another thing regardless of the value of x;
if (x < 0)
{
do something;
do something else;
do yet a third thing;
}
do another thing regardless of the value of x;
if (x < 0)
{
do something;
}
do another thing regardless of the value of x;
If you want to see some fairly idiomatic Python that does non-trivial stuff, there's Dive Into Python, although Dive Into Python 3 is newer and might be a better source of style tips. If you're looking more for some points to review, there's Code Like a Pythonista.
You could post your code at Refactor my code to see if someone can show you a more Pythonic way to do it.
Definitely not a panacea but I think you should try some code golf in Python. Obviously nobody should write "golfed" code IRL, but finding the most terse way to express something really forces you to exploit the built in functionality of the language.
Someone provided me with this list of how "Python is not Java" when I started Python after Java, and it was very helpful.
Also, check out this similar SO question that I posted a short time ago when in a similar position.
Try to find algorithms that you understand well and see how they are implemented in python standard libraries.
Persist. :)
Learn a few other languages. It will help you make the difference between algorithms (the structure of processing, unchanged between languages) and the local syntaxic features of the language. Then you can "write Foo in Bar" for any combination of languages "Foo" and "Bar".
Eat Python, Sleep Python and Drink Python. That is the only way........
This is useful if you want to understand how to code to python in a more pythonic or correct way: http://www.python.org/dev/peps/pep-0008/