I used to write a very strong type language, for example, java. I need to tell the complier what type of variable I will put in... for example...
public static void sayHello(String aName)
I can ensure that the user will pass a string to me...
But if I use php, I can do that...
function sayHello($aName)
I still can call the sayHello, but I don't know what the param type......I can let the name more informative like this:
function sayHelloWithString($aName)
But I can't stop the user pass in a int to me..... the user can still pass the int to me... ...it may cause lot of errors....How can I stop it? any ideas or experience shared? Thank you.
How about not stopping the user from passing in an int?
In php, you could check is_string, but of course, you'll miss out on objects that have __toString set, or the implicit conversion of numbers to strings.
If you must make your program cry in pain when a developer tries something different, you could specify a type in the later versions of PHP (i.e. function foo(ObjectType $bar)...)*
In most loosely typed languages, you want to set up fall-backs for the major types:
number
array
string
generic object
Be liberal in what you accept, be strict in what you send.
* Primitive types are not supported for type hinting
There's a few ways to deal with this...
Use an IDE that supports docblocks. This deals with the pre-runtime type checking when writing code.
Use type checking within your function This only helps with the runtime type checking, and you won't know when writing your code.
Depending on the type you can use built-in type hinting. This however only works for non-scalar values, specifically array and a class name.
1 - To implement #1 using a good IDE, you can docblock your function as such:
/**
* Say hello to someone.
*
* #param string $aName
**/
public function sayHello($aName) {
2 - To implement #2 use the is_ methods..
public function sayHello($aName) {
if (!is_string($aName)) {
throw new ArgumentException("Type not correct.");
}
// Normal execution
3 - You can't do this with your method above, but something like this.. Kindof the same as #2 apart from will throw a catchable fatal error rather than ArgumentException.
public function manipulateArray(array $anArray) {
It's worth noting that most of this is pretty irrelevant unless you're writing publicly usable library code.. You should know what your methods accept, and if you're trying to write good quality code in the first place, you should be checking this before hand.
Using a good IDE (I recommend phpStorm a thousand times over) you can and should utilise DocBlocks everywhere you can for all of your classes. Not only will it help when writing APIs and normal code, but you can use it to document your code, what if you need to look at the code 6 months later, chances are you're not going to remember it 100% :-)
Additionally, there's a lot more you can do with docblocks than just define parameter types, look it up.
You can check if what they passed is a string using:
http://php.net/manual/en/function.is-string.php
Then provide appropriate error handling.
function sayHello($aName) {
if (is_string($aName)) {
//string OK!
} else {
echo "sayHello() only takes strings!";
}
}
In PHP you can check whether the variable that has been passes is a string by using the is_string function:
<?php
if (is_string($aName)) {
echo "Yes";
} else {
echo "No";
}
?>
Hope that helps.
Or alternatively /additionally use Type Casting to convert the variable to the required type
http://us3.php.net/manual/en/language.types.type-juggling.php
You have the option of checking to make sure the parameter is of the right type. However, it's worth considering what you'd do if it isn't. If you're just going to throw an exception, you might be better off just assuming it's the right type and the the exception be thrown when something you do isn't allowed. If you're not going to add any more useful information to the exception/error that would already be thrown, then there's not much point in checking it in the first place.
As to giving the user an indication of what type you want, I generally stick with including it in the variable name:
function sayHello($aNameStr)
function addItems($itemList)
...etc...
That, plus reasonable documentation, will mean the user can look at the function and figure out what they should be passing in in the first place.
Some scripting languages have tools that can help you. For example use strict in perl requires declaration of each variable before using. But still the language is weakly typed by definition.
Sometimes naming conventions help. For example we inherited from good old Fortran tradition that int variables' names should start from i, j, k, l, m, n. And this convention is used now at least for indexes.
Related
I am curious about this, why would kotlin designers think this would be a good idea to drop explicit typing in Kotlin ?
To me, explicit typing is not a "pain" to write in Java (or any other strongly typed language) : all IDE can assist me to automaticaly type my variable.
It adds great understanding of the code (that's why I don't like weakly-typed languages, I have no idea what kind of variables I'm dealing with).
Also, and this is my main issue with that, it makes the code more bug-prone.
Example :
Java : Easily identified as a String, all good
String myPrice = someRepository.getPrice(); // Returns a String
myTextView.setText(myPrice);
Java : Easily identified as an int, code smell with setText()
int myPrice = someRepository.getPrice(); // Returns an int, code smell !!
myTextView.setText(String.valueOf(myPrice)); // Problem avoided
Kotlin : ????
val myPrice = someRepository.getPrice(); // What does it return ?
myTextView.setText(myPrice); // Possible hidden bug with setText(#StringRes int) instead of setText(String) !!
No explicit typing in Kotlin is the biggest drawback in Kotlin imo. I try to understand this design choice.
I'm not really looking for "patches" to fix the example / avoid the presented code smell, I try to understand the main reason behind the removal of explicit typing. It has to be more than "less typing / easier to read". It only removes a couple of characters (one still have to write val / var), and explicit typing in Kotlin adds some caracters anyway...
Static typing without explicit typing is, to me, the worst case scenario to deal with hidden bugs / spaghetti bugs : if one class (let's say "Repository") changes it return type (from String to int for example). With explicit typing, compilation would fail at the class calling "Repository". Without explicit typing, compilation may not fail and the wrong type of variable may "travel" through classes and change the behavior of the classes because of its type. This is dangerous and undetected.
The fix is easy ; explicitly type the variable. But this is Kotlin we're speaking, a language made for code golfers : people won't explicitely type their variables, as it takes even more time to do so in kotlin than turtle-java. Yikes!
First of all: Kotlin has static typing. The compiler knows exactly which type goes or comes where. And you are always free to write that down, like
fun sum(a: Int, b: Int): Int {
val c: Int = 1
The point is: you can write a lot of code that simply relies on the fact that anything you do is statically typed, and type checked, too!
Do you really need to know whether you are adding two doubles or two ints or two longs, when all you "care" to look at is a + b?
In the end, this is about balancing different requirements. Leaving out the type can be helpful: less code that needs to be read and understood by human readers.
Of course: if you write code so that people constantly turn to their IDE for the IDE to tell them the actual, inferred type of something, then you turned a helpful feature into a problem!
The real answer here is: it depends. I have been in many code reviews where C++ people discussed the use of the auto keyword. There were a lot of situations, where using auto did make the code much easier to read and understand, because you could focus on "what happens with the variable", instead of looking 1 minute at its declaration, trying to understand its type. But there were also occasional examples where auto achieved the exact opposite, and a "fully typed" declaration was easier to follow.
And given the comment by the OP: you should know what you are doing in the first place. Meaning: when you write code, you don't just invoke "any" method that you find on some object. You call a method because you have to. You better know what it does, and what it returns to you. I agree, when someone is in a rush, you quickly var-assign and then pass that thing along, that might lead to errors. But for each situation where var helps with creating a bug, there might be 10 incidents where it helps writing easier to read code. As said: life is about balancing.
Finally: languages shouldn't add features for no reason. And the Kotlin people are carefully balancing features they add. They didn't add type inference because C++ has it. They added it because they carefully researched other languages and found it to be useful to be part of the language. Any language feature can be misused. It is always up to the programmer to write code that is easy to read and understand. And when your methods have unclear signatures, so "reading" their names alone doesn't tell you what is gong on, then blame that on the method name, not on type inference!
To quote Java's Local-Variable Type Inference JEP:
In a call chain like:
int maxWeight = blocks.stream()
.filter(b -> b.getColor() == BLUE)
.mapToInt(Block::getWeight)
.max();
no one is bothered (or even notices) that the intermediate types Stream<Block> and IntStream, as well as the type of the lambda formal b, do not appear explicitly in the source code.
Are you bothered about it?
if one class (let's say "Repository") changes it return type (from String to int for example). With explicit typing, compilation would fail at the class calling "Repository".
If you have overloads like setText in your example, then
Repository repository = ...;
myTextView.setText(repository.getFormerlyStringNowInt());
won't fail without type inference either. To make it fail, your code standard has to require every operation's result to be assigned to a local variable, as in
Stream<Block> stream1 = blocks.stream();
Predicate<Block> pred = b -> {
Color c = b.getColor();
return c == BLUE;
};
Stream<Block> stream2 = stream1.filter(pred);
ToIntFunction<Block> getWeight = Block::getWeight;
IntStream stream3 = stream2.mapToInt(getWeight);
int maxWeight = stream3.max();
And at this point you make bugs easier just from decreased readability and the chance to accidentally use the wrong variable.
Finally, Kotlin wasn't created in a vacuum: the designers could see that when C# introduced local type inference in 2007, it didn't lead to significant problems. Or they could look at Scala, which had it since the beginning in 2004; it had (and has) plenty of user complaints, but local type inference isn't one of them.
In c++, I'd usually pass a byRef variable as a parameter to the function to get the information that I need returned, and I'd return a boolean or int value from the function to determine if the function was executed successfully (no errors occurred at any point).
I can't do that in Java since you can only pass byVal, and can get one thing returned.
I guess you can return some array or list, but I feel like that's bad coding practice.
What are some proper ways to deal with this problem?
If you want to do it exactly like in c++, you can pass a primitive by reference via its wrapper-class (e.g. class Integer for primitive int). But I agree with the comments below the question that the 'proper way' of doing this in Java is to throw an exception in case of failure. In case you do not like both ideas, you can still use static variables in the class that implements the method you are executing, let them be set by that method and read by the invoking method/class, but this is no good coding practice either and should not be done unless there is no other option for whatever reasons.
Which of the following is best practice according to Java coding standards
public void function1(){
boolean valid = false;
//many lines of code
valid = validateInputs();
//many lines of code
}
or
public void function1(){
//many lines of code
boolean valid = validateInputs();
//many lines of code
}
Here 'valid' will not be for returning. Its scope is internal to the function only. Sometimes only in one if condition
I usually code similar to the second case. It seems my superior does not like this and modifies the code when I put it for review. Is there some specific reason that my approach is not correct?
The disadvantage I see for the first approach is that it is very difficult to refactor the method to multiple methods at a later point.
I would go for the second approach - not much a matter of Java coding standards here, but a matter of clean and readable code. Also, you assign the value false to valid in the first case, but that's not really correct as valid shouldn't have any value at that point.
On a side note, I won't expect a method called validateInputs() to return a boolean. There's no parameter passed, and the name is not giving an hint that the method would return something. What about refactoring your code to something like boolean validInput = isValid(input)?
I would prefer to only declare variables within the scope they are used. This avoid accidentally using it when you shouldn't and means you can see both the declaration and the usage together, instead of having to jump to the start of your code to find it.
In the C days, you had to use the first form, because the compilers were not very smart. But the second form was added as it made the code easier to understand AFAIK.
Whichever is better is a matter of personal taste. Every place has its own standards, so you should follow it at work.
That's one more reason I think every programmer should have their own personal projects. That way you can also code in your own style at home, so you don't get your mind stuck with just one style.
There should always be reasoning behind a decision.
The second example is better because it is good to initialize values in the declaration.
Google has a good set of standards that is applicable to many C-type languages. The example you are referring to is shown in the 'local variables' section.
I've been looking around to try to find what the reasoning is behind not including default parameters for functions in Java.
I'm aware that it's possible to simulate the behavior, either with varargs or else by creating several overloaded functions that accept fewer parameters, and call the real function that takes all parameters. However, neither of these options match the clarity and ease-of-use of, e.g. C++'s syntax.
Does anyone know if there's a solid technical reason that would make something like
void myFunc(int a=1, int b=2) {...}
undesirable or undo-able in a new version of Java?
It was not in the initial version of Java because they decided they did not need it, probably to keep things simple.
Adding it now would be tricky, because it needs to be done in a backwards-compatible fashion. Adding varargs, autoboxing and generics in Java5 was a major undertaking, and it could only be done with limited functionality (such as type erasure) and at the cost of increased complexity (the new method resolution rules make for good exam trick questions).
Your best shot would be with a non-Java language on the JVM. Maybe one of them already has this.
I am not aware of a technical reason, apart from it being complicated which values are being omitted and which ones are not.
For example, in your sample, if only one integer was passed through then is it a or b that should be defaulted? Most probably a but it does add that level of ambiguity.
A simple solution would be to
void myFunc(Integer a, Integer b) {
if (a == null) a = 1;
if (b == null) b = 2;
}
Yes it is more long winded, and yes it hides the defaulting within the code, rather than the method signature (which could then be shown in JavaDoc), but it does enforce the consistency.
I agree that optional arguments would add huge clarity and save the huge work of defining loads of overloaded methods (called telescoping), which do nothing than call each other. However, the enabler for this neat feature is passing arguments by name.
Named association is self-documenting. In contrast, positional argument association is concise but it makes you to refer the definition of method all the time to check which argument is expected in nth position at every invocation. This is ridiculous and motivates us to search for solutions like Builder pattern. The Builder actually solves both problems at once because named association is a synonym for optional arguments. But Builder is useful only for user. API designer still must waste space/time to create the Builder class. Pattern bigots might disagree but it is an overkill to create a Builder class for every method with named/optional arguments. Language design should obviate this stupid pattern. But, I do not know how compatible they are with the variable argument list.
To Avoid Ambiguity. Java Support Method Override.
We assume the code below:
public int add(int a) {
// do something
}
public int add(int a, int b = 0) {
// do something
}
When we call add(12), Can you tell me which function is invoked?
[Later: Still can't figure out if Groovy has static typing (seems that it does not) or if the bytecode generated using explicit typing is different (seems that it is). Anyway, on to the question]
One of the main differences between Groovy and other dynamic languages -- or at least Ruby -- is that you can statically explicitly type variables when you want to.
That said, when should you use static typing in Groovy? Here are some possible answers I can think of:
Only when there's a performance problem. Statically typed variables are faster in Groovy. (or are they? some questions about this link)
On public interfaces (methods, fields) for classes, so you get autocomplete. Is this possible/true/totally wrong?
Never, it just clutters up code and defeats the purpose of using Groovy.
Yes when your classes will be inherited or used
I'm not just interested in what YOU do but more importantly what you've seen around in projects coded in Groovy. What's the norm?
Note: If this question is somehow wrong or misses some categories of static-dynamic, let me know and I'll fix it.
In my experience, there is no norm. Some use types a lot, some never use them. Personally, I always try to use types in my method signatures (for params and return values). For example I always write a method like this
Boolean doLogin(User user) {
// implementation omitted
}
Even though I could write it like this
def doLogin(user) {
// implementation omitted
}
I do this for these reasons:
Documentation: other developers (and myself) know what types will be provided and returned by the method without reading the implementation
Type Safety: although there is no compile-time checking in Groovy, if I call the statically typed version of doLogin with a non-User parameter it will fail immediately, so the problem is likely to be easy to fix. If I call the dynamically typed version, it will fail some time after the method is invoked, and the cause of the failure may not be immediately obvious.
Code Completion: this is particularly useful when using a good IDE (i.e. IntelliJ) as it can even provide completion for dynamically added methods such as domain class' dynamic finders
I also use types quite a bit within the implementation of my methods for the same reasons. In fact the only times I don't use types are:
I really want to support a wide range of types. For example, a method that converts a string to a number could also covert a collection or array of strings to numbers
Laziness! If the scope of a variable is very short, I already know which methods I want to call, and I don't already have the class imported, then declaring the type seems like more trouble than it's worth.
BTW, I wouldn't put too much faith in that blog post you've linked to claiming that typed Groovy is much faster than untyped Groovy. I've never heard that before, and I didn't find the evidence very convincing.
I worked on a several Groovy projects and we stuck to such conventions:
All types in public methods must be specified.
public int getAgeOfUser(String userName){
...
}
All private variables are declared using the def keyword.
These conventions allow you to achieve many things.
First of all, if you use joint compilation your java code will be able to interact with your groovy code easily. Secondly, such explicit declarations make code in large projects more readable and sustainable. And of-course auto-completion is an important benefit too.
On the other hand, the scope of a method is usually quite small that you don't need to declare types explicitly. By the way, modern IDEs can auto-complete your local variables even if you use defs.
I have seen type information used primarily in service classes for public methods. Depending on how complex the parameter list is, even here I usually see just the return type typed. For example:
class WorkflowService {
....
WorkItem getWorkItem(processNbr) throws WorkflowException {
...
...
}
}
I think this is useful because it explicitly tells the user of the service what type they will be dealing with and does help with code assist in IDE's.
Groovy does not support static typing. See it for yourself:
public Foo func(Bar bar) {
return bar
}
println("no static typing")
Save and compile that file and run it.