Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 6 years ago.
Improve this question
I'm looking for the best way to implement three-valued logic.
I googled and found three different approaches:
Use null value for Boolean variable as undefined
This variant looks to dangerous for me because it can unexpectedly cause NullPointerException
Use Optional<Boolean> type
This variant still is a bit dangerous. To avoid NoSuchElementException you should use constructions like this:
Optional<Boolean> amIRight = Optional.empty();
if (Optional.of(true).equals(amIRight ) {
doSome();
}
It looks too wordy for me
Implement your own enum
The last variant seems to be the best. Almost safe, very simple in undefstanding. But I haven't find any of such enums in widely spread java libriaries such as Apache, Google Guava and so on. It looks strange for me everybody avoids the simpler and safest implementation.
May be I missed something and there are serious reason not to implement three-valued logic enum.
If enum works for you, go for it.
Don't use that Boolean, it is ugly and destroy readability ... I also can't imagine how horrible it would be if you want it to support 4 values later...
Other cautions / advise :
Are you sure that you will use only 3 values?
In many situation, design tends to change, and enum will be no longer enough.
Using a class that encapsulate enum (or int) can provide better flexibility.
However, you can change from enum to class later.
In my program, I extensively use enum.
You shouldn't care much about what popular libraries do, just pick the best that work for you!
About the very interesting hypothesis :
... there are serious reason not to implement three-valued logic enum. ...
Suppose that I am Java language designer.
You ask for a 3-logic enum.
I accept you proposal.
Then, Mr.2D ask "We have 3-logic enum. Why don't you provide 4-logic enum to support +x -x +y -y?".
I give him what he want.
After that, Mr.LoveFive Mr.ObsessiveSick ..... I think you got the point.
There has to be a threshold (when to stop) and the demand for 3-enum is relatively very low compared to 2-enum (boolean).
I agree that enums is by far the safest and best solution to your problem. Perhaps enums are not widely used in projects like Apache because enums are relatively new in Java (I think they came along in Java 1.5).
If you want 3 valued logic, you are no longer talking about simple true/false conditions, you are talking about a state machine. Arguably state machines are among the most powerful paradigms in programming. If you aren't conversant with automata theory, look it up.
Related
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 1 year ago.
Improve this question
I'm trying to learn design patterns as good coding practices and I would like to know if a HashSet is considered a well-written class? eg:
To construct a LinkedHashSet we use the following constructor
public LinkedHashSet(int initialCapacity, float loadFactor) {
super(initialCapacity, loadFactor, true);
}
Which calls this one:
HashSet(int initialCapacity, float loadFactor, boolean dummy) {
map = new LinkedHashMap<>(initialCapacity, loadFactor);
}
So there is a useless param, is it correct to do that?
Also, I see that LinkedHashSet extends HashSet
LinkedHashSet<E> extends HashSet
and HashSet references LinkedHashSet in its code, why there is nothing like a compile time recursion there?
// Create backing HashMap
map = (((HashSet<?>)this) instanceof LinkedHashSet ?
new LinkedHashMap<E,Object>(capacity, loadFactor) :
new HashMap<E,Object>(capacity, loadFactor));
This is severely optinion based.
And in a lot of situations, the programmers had to make hard choices. And there has been so many teams at work, that it's natural that some of the following problems occur.
However, here's my opinion on that topic:
Most of the JDK code is a mess. Unnecessary code, convoluted code that modern Java JIT compilers easily will do better
There's lots of micro optimizations, but in the end a lot of implementations can rewritten to be much faster, cleaner, more compatible.
Simple classes like ArrayList are already a mess, and if you write your own implementation, it will be twice as fast.
The Input/OuputStream system is a mess, should have had an interface at the very top.
A lot of solutions like ThreadLocal are inherently unsafe to use and can cause leaks if not worse problems.
There's a lot of repetition of code where there shouldn't be
a huge lacking support for default conversions, especially String to something else, should have default methods like s.toInt(int default)-like methods
The java.util. functions and FunctionalInterfaces are a mess, with lots of different names that could have been constructed in a far more logical and intuitive way, alsong with all the Collectors and stuff. Could be so much easier.
On the other hand:
The Collections structures (inheritance, Interfaces etc) are over all pretty well implemented, with only very few features missing
the java.nio stuff is really good
The Exceptions (RuntimeException, Throwable) hierarchies are quite good and provide a stable basis for additional custom classes (that one might prefer to / should use)
Some aspects that to not target the implementation of classes, but the language specification:
how they introduced and integrated Lambdas and Streams (the whole functional show)
Generics and Covariance/Contravariance
Reflection and Annotations
All in all, if you give your default Java a little boost with libraries like Project Lombok (adding AOP and stuff), it is awesome. I really love it, and so far no other language could un-favorite Java (even tho I hated Java when I had to learn it)
So, as others have stated:
learn from the code (some techniques are REALLY good)
improve upon them (some are obviously BAD)
And finally to the points you addressed:
The dummy parameter. This is a very rare occurrence, and even then mostly only occurs for quality-of-life: instead of having only one CTOR with 3 arguments, also have another CTOR with 2 arguments
concerning the compile time recursion: Java compiler can be compared to a multi-pass compiler, so the 'recursion' does not play a role. What is a little bad about this implementation - a very theoretical/academic complaint - is that HashSet and LinkedHashSet are now statically bound in BOTH directions. LinkedHashSet -> HashSet would be fine (how else would inheritance be implemented!?), but HashSet -> LinkedHashSet is a bit of a bugger. But, well, academic, because those two classes are in the same package, and not even the new Modules system will rip them apart. So unless you write a packaging tool that discerns on such a low level (like I did), this point has no practical impact.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 6 years ago.
Improve this question
Came across this coding standard from Oracle:
Do not use a static array of strings.
What is the reason for this recommendation?
Arrays are mutable containers. Global mutable container without built-in synchronisation is multi-threaded horror waiting to happen. You can store reference to that array in some local context and then have it's content changed at any time without you knowing it. Or vice versa you may assume that this is convenient global state, but then every client must know the exact correct way to synchronise its access to that state. And somebody will forget and bug will be born.
I believe it's due to developers using String as a replacement (most likely unintentionally) for enumeration, and the static String[] was a way to group these types.
It could be targetting design flaws that were common at the time the article was written
For all we know, this article could be targetting the Java 4- code base.
Not saying this was written during Java 4, but that most production code existing at the time may have been written in Java 4. The lack of autoboxing pitfalls (which are quite common) and no mentions of generics (raw types) lead me to believe this.
Why would Oracle enforce such a cryptic principle?
I don't believe it has to do with global state, since I'm sure singletons would have been mentioned (being the pinnicle of global state).
I doubt concurrency is the issue, since the article does not mention anything else about sharing data across threads, or even using multiple threads. You would assume they would have mentioned SOMETHING about the thread environment.
Misusing String for type enumeration purposes was common back in the day, so I'm sure this statement (if related to what I think it is) was a lot easier to understand back then. I find it to be quite a stretch that this statement was just as cryptic back then, yet no one has cared to question it, resulting in the lack of google results when digging into this.
My Answer
Developers to this day still misuse String for type information. With the lack of enumeration, I could see how a developer may be tempted to do something along the lines of:
class Card {
static String HEARTS = "HEARTS";
static String DIAMONDS = "DIAMONDS";
static String CLUBS = "CLUBS";
static String SPADES = "SPADES";
static String[] CARD_TYPE = {
HEARTS, DIAMONDS, CLUBS, SPADES
};
private String type;
//...
}
Using the array for easy looping (as one would do with Enum.values()).
Using String as enums is frowned upon:
It's not type safe. If MAGE can be passed to a method, ANY String could be passed in it's place. This leads us to...
Mistakes are easier to make. It's possible for a typo to go unnoticed, which may seem small for the average developer, but could be catastrophic for businesses with large code bases and many consumers (such as Oracle). For example: a hidden typo results in a comparison returning false. This prevents a service from launching. The lack of this service results in a bug. If not found before users notice the bug, it could lead to exploits.
This could be fix by using Java's built-in type system:
abstract class CardType {
}
class Hearts extends CardType {
}
....
Or
enum CardType {
HEARTS, DIAMONDS, ...;
}
Not only is this less error-prone, but it allows you to use polymorphism, which prevents the need to check the value in order to trigger a specific behavior. The behavior can be contained in the type itself.
Although I can't promise this is the correct answer, it seems to be the only answer that does not depend on the use of modifiers that weren't mentioned in the statement.
Yes, the example above does not use proper constants (lacks the final). But although constants should be preferred, they are not required to benefit from this design (being able to use String for type information) nor does the design require it to work . Since people may not have always used constants for this, they could have left out the final or "array of constants" for this purpose.
This way undermines the object oriented paradigm. Moreover it's a security hole, because the final keyword assures only reference value and leaves the content to be changed easily.
Some of them are arbitrary. For example, having a single return statement is a matter of style (maybe related to some analysis tool that in the past couldn't handle multiple return paths?).
Some of them are outdated. Like the one about StringBuilding.
I'd assume that these are a mixture of old performance recommendations and style guides. I'd reckon the String static array one falls in the latter category, with maybe a hint towards what others have said about the possible link with the introduction of enums (maybe that's why Strings in particular).
Some of them are actually completely unfeasible when you try to apply them to modern frameworks: "Do not use a switch to make a call based on the object type.", for example, is at the core of Akka Java (onReceive) method and in general in any type of pattern matching in Java...
While I admit it's curious, I'd say it's probably something related to some specific tool they used in the past or to the enum possibility mentioned. But it's just my opinion, not a definitive answer.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 7 years ago.
Improve this question
I am familiar with "Scala coding styles and conventions?"
I also have read this article which states that a programmer is able to produce only so many lines of code per day and therefore a language with a "better" syntax can only help in this direction.
As there is nothing perfect in the world, the syntax of Scala has its disadvantages (of course someone can see these as pure advantages). I am talking about stuff like:
def someMethod(someParameter: Int): Boolean = {
// import here in the middle of nowhere
import com.example.bad.VeryBad._
// semicolon here? maybe?
val two = 1+1;
// nested function here
def boo(a: Int) = a+1;
// now do something useful
println(boo(two))
// for God's sake don't use return!!!
two == 2
}
If one has Java background (or even C++, C#, etc.) it is kind of weird to have import statements in the middle of a function, to have nested functions and I am not even going into other language constructs.
I am a bit sceptical about the real productivity gain coming with Scala. How do you experience this? Do you apply all (as much as possible) of the coding conventions and is this a real benefit? Is there a better way to wrap ones head around this style of code?
P.S. maybe this whole post can be moved to Programmers or similar...
I can share only my experience and I don't know whether other people's experiences are similar. It certainly depends on personal preferences.
Imports in blocks
I came to Scala from Java, so my preference in general is to have all imports at the top of the file. This makes it easier for me to faster see the dependencies of the files. Sometimes however I do use local import in places where I want to import a name only locally and not to pollute the namespace of the whole file.
Semicolons
After few weeks in Scala I really enjoy the the lack of mandatory semicolons. In Scala they are mostly not needed, but they can be helpful when you want to write more short statements on one line. Scala actually changes my attitude towards semicolons and now in new projects I don't use semicolons even in JavaScript.
Nested functions
This is one of the best features of Scala: Functional programming. It allows to write much simpler code consisting of small easily understandable functions working with immutable data. This decreases the complexity of the code, reduces bugs and increases the productivity.
Returns
Again, lack of return statements feels just natural. The function returns the value of its expression, where the value of a sequence of statements/expressions is the last one of them. Return statements just feel very unnatural in Scala.
Productivity
Scala has a learning curve and of course when I have started my productivity had a dent caused by my lack of familiarity with the language and the standard library. Now, after few months of Java and Scala work, I can say that I am in more productive in Scala than in Java. Even though I consider myself a Java expert but only a Scala novice.
I'll go step by step, although some points could be subject to personal opinion:
Imports:
there are some cases where this is pretty useful, for example to shorten you code in case of constants:
object Constants { val someConstant = "123" }
def someMethod(someParameter: Int): Boolean = {
import Constants._
doSomething(someConstant)
}
this also gives the reader a hint on where is that someConstant coming from, having it in the top declaration can be not so explicit.
Semicolon: nobody uses them in scala, the only useful application which comes to mind is if you want to write multiple statement in one line
val a = 1; val b= 2
Not that useful in the end.
Nested methods: these are perfectly fine, wether you should use it or not vary on your use case, also there are around many example of recursive or tail recursive functions which use nested methods.
There's no need to use return, I've never seen it used in my experience plus it can be quite confusing in some cases.
Using such imports for implicits is useful in many cases.
For this usage, importing makes code safer and more readable.
Second case would be ambiguous class and package names (can be solved via aliases). Showing explicite which one is using can be helpful.
In Scala you can do many things in many ways, a little bit like with C++. You have more responsibility for your coding style. Watch this: https://www.youtube.com/watch?v=kkTFx3-duc8&feature=share
Nested methods are great for recurrence and when such method should not be used even as private at class level. With nesting you can also reduce amount of passed arguments.
If you can you then you should place you nested methods on the top of method body. Giving comments on where is constructor body at big class is also helpful.
Scala gives to community the ability to develop the language, scala can change in fundamental ways due to our experiments, good practices.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 8 years ago.
Improve this question
I've seen some legacy code that uses lengthproperty on some objects and others that uses length() method. Currently I'm working with a NodeList from the org.w3c.dom package and I found that it have the getLength() method to get the numbers of elements.
My Question is how as Java developer I can know how to determine when to use length, length(), size(), getLength()? obviously it depends of the object type and the API is there for read... but the point is how the Java Development select which of that implements in their classes.
Note: In the Question When to use .length vs .length() Makoto answer's indicates that .length is a property on arrays. That isn't a method call, and length() is a method call on String. But, why is the reason? why not use ever a method or ever a property for maintain the consistency around all the API.
how would Java developers select which of [the methods] to implement in their classes?
When you implement classes that contain other objects, it's almost always going to be size(), the method provided by theCollection interface.
As far as other choices go, you should avoid exposing member variables, even final ones, because they cannot be accessed through an interface. Java gets away with it for arrays because of some JVM trickery, but you cannot do the same. Hence, length should be out: it remains in Java because it's not possible to change something that fundamental that has been in the language from day one, but it's definitely not something one should consider when designing new classes.
When you implement your own type that has length (say, a rectangle or a line segment) you should prefer getLength() to length() because of Java Beans naming conventions.
obviously it depends of the object type and the API is there for read...
You already have answered your question yourself: look in the API documentation of whatever class you are using.
but the point is how the Java Development select which of that implements in their classes.
The classes in Java's standard library have been developed over a long period of time by different people, which do not always make the same choice for the name of methods, so there are inconsistencies and unfortunately you'll just have to live with that.
There is no clear rule, otherwise we wouldn't see such a mixup in the jdk itself. But here are some things to consider when making such a design decision.
Don't worry to much. It is a minor thing and won't make to much of a difference. So when you think longer then 5 minutes about this, you are probably wasting money already.
Use getters when a frameworks need them. Many frameworks depend on the getter style. If you need or want such frameworks to work nicely with your class it might be beneficial to use that style.
Shorter is better. the 'get' part doesn't increase clarity. It just generates to characters of noise to the source code, so if you don't need it for some reason, don't use it.
Methods are easier to evolve. Length is often a quantity that is not set directly but somehow computed. If you hide that behind a method it gives you the flexibility to change that implementation later on, without changing the API.
Direct field accesses should be a tiny bit faster, but if you aren't working on high volume online trading or something, the difference isn't even worth thinking about. And if you do you should do your own measurements before making a decision. The hotspot compiler will almost for sure inline the method call anyways.
So if there aren't any external forces driving you in a different direction I would go with 'length()'
According to OOPS principles, length should be attribute and getLength() should be method. Also length attribute should be encapsulated should be exposed through methods, so getLength() sounds more appropriate.
Unfortunately not all Java library classes follow standards. There are some exceptions and this is one among them.
In a pure OO language it should be probably always a method like length(). So in a class hierarchy you can override the attribute length.
But Java is not pure OO. And the main reason for fields (.length) vs method (length()) is/was performance issues.
And even Sun/Oracle programmers did some bad class design.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 8 years ago.
Improve this question
I've been using Java almost since it first came out but have over the last five years gotten burnt out with how complex it's become to get even the simplest things done. I'm starting to learn Ruby at the recommendation of my psychiatrist, uh, I mean my coworkers (younger, cooler coworkers - they use Macs!). Anyway, one of the things they keep repeating is that Ruby is a "flexible" language compared to older, more beaten-up languages like Java but I really have no idea what that means. Could someone explain what makes one language "more flexible" than another? Please. I kind of get the point about dynamic typing and can see how that could be of benefit for conciseness. And the Ruby syntax is, well, beautiful. What else? Is dynamic typing the main reason?
Dynamic typing doesn't come close to covering it. For one big example, Ruby makes metaprogramming easy in a lot of cases. In Java, metaprogramming is either painful or impossible.
For example, take Ruby's normal way of declaring properties:
class SoftDrink
attr_accessor :name, :sugar_content
end
# Now we can do...
can = SoftDrink.new
can.name = 'Coke' # Not a direct ivar access — calls can.name=('Coke')
can.sugar_content = 9001 # Ditto
This isn't some special language syntax — it's a method on the Module class, and it's easy to implement. Here's a sample implementation of attr_accessor:
class Module
def attr_accessor(*symbols)
symbols.each do |symbol|
define_method(symbol) {instance_variable_get "##{symbol}"}
define_method("#{symbol}=") {|val| instance_varible_set("##{symbol}", val)}
end
end
end
This kind of functionality allows you a lot of, yes, flexibility in how you express your programs.
A lot of what seem like language features (and which would be language features in most languages) are just normal methods in Ruby. For another example, here we dynamically load dependencies whose names we store in an array:
dependencies = %w(yaml haml hpricot sinatra couchfoo)
block_list %w(couchfoo) # Wait, we don't really want CouchDB!
dependencies.each {|mod| require mod unless block_list.include? mod}
It's also because it's a classless (in the Java sense) but totally object oriented (properties pattern) so you can call any method, even if not defined, and you still get a last chance to dynamically respond to the call, for example creating methods as necessarry on the fly. Also Ruby doesn't need compilation so you can update a running application easily if you wanted to. Also an object can suddenly inherit from another class/object at anytime during it's lifetime through mixins so it's another point of flexibility. Anyways I agree with the kids that this language called Ruby , which has actually been around as long as Java, is very flexible and great in many ways, but I still haven't been able to agree it's beatiful (syntax wise), C is more beatiful IMHO (I'm a sucker for brackets), but beauty is subjective, the other qualities of Ruby are objective
Blocks, closures, many things. I'm sure some much better answers will appear in the morning, but for one example here's some code I wrote ten minutes ago - I have an array of scheduled_collections, some of which have already happened, others which have been voided, canceled, etc. I want to return an array of only those that are pending. I'm not sure what the equivalent Java would be, but I imagine it's not this one-line method:
def get_all_pending
scheduled_collections.select{ |sc| sc.is_pending? }
end
A simpler example of the same thing is:
[0,1,2,3].select{|x| x > 1}
Which will produce [2,3]
Things I like
less code to get your point across
passing around code blocks (Proc, lambdas) is fun and can result in tinier code. e.g. [1, 2, 3].each{|x| puts "Next element #{x}"}
has the scripting roots of PERL.. very nice to slice n dice routine stuff like parsing files with regexps, et. all
the core data structure class API like Hash and Array is nicely done.
Metaprogramming (owing to its dynamic nature) - ability to create custom DSLs (e.g. Rails can be termed a DSL for WebApps written in Ruby)
the community that is spawning gems for just about anything.
Mixins. Altering a Ruby class to add new functionality is trivially easy.
Duck typing refers to the fact when types are considered equivalent by what methods them implement, not based on their declared type. To take a concrete example, many methods in Ruby take a IO-like object to operate on a stream. This means that the object has to implement enough functions to be able to pass as an IO type object (it has to sound enough like a duck).
In the end it means that you have to write less code than in Java to do the same thing. Everything is not great about dynamic languages, though. You more or less give up all of the compile-time typechecking that Java (and other strongly/statically typed languages) gives you. Ruby simply has no idea if you're about to pass the wrong object to a method; that will give you a runtime error. Also, it won't give you a runtime error until the code is actually called.
Just for laughs, a fairly nasty example of the flexibility of the language:
class Fixnum
def +(other)
self - other
end
end
puts 5 + 3
# => 2