After being very excited and optimistic about Java 8 "extension"/defender methods I am finding myself disappointed. In reading what it does I was expecting to, like with C# or Scala, to be able to "insert" my own methods "onto" final/sealed classes.
One very simple requirement is to be able to "extend" String with my own method mid - in order to do something like this:
"123456".mid(2,2) => "34"
I really don't want to get into an academic argument about why this code design is bad. It works for C#, it works for Scala, so why would this argument be any different for Java - rhetorically asking?
Currently one option to alleviate this is by doing the StringUtils.mid("123456", 2, 2)... which is really counter-intuitive imho.
I known lombok does this - but unfortunately it is not compatible with this specific feature for my IDE (IntelliJ).
Can somebody please direct me to code of where such a defender was done successfully if possible? Googling it only gives examples of Collection API where the code is already written "into" JDK 8 or examples from the ground up for non-JDK or Sealed classes.
Regards,
Gawie
Related
Are Enum classes in Kotlin "expensive" for Android as Java?.
Is it still stand to use #IntDefs or #StringDefs in Kotlin?.
When I decompile Kotlin Enum class to Java class, there still used Java Enums in the low level, which are not recommended for use in Android Development, and this made me think about this.
Are Enum classes in Kotlin "expensive" for Android as Java?. Could be. I doubt whether kotlin will be able to do any optimization that java cannot.
Is it still stand to use #IntDefs or #StringDefs in Kotlin?. - Not really. This is a polarising subject and many in the Android world(including me) believe that using enums should be the preferred way. I encourage you to read the following links to get a better idea.
Twitter thread by Jake Wharton
An article by Diane Hackborn and the comments
Somwhat witty reddit thread talking about optimization of enums and such
And the following answers by Jake Wharton are interesting.
Does lint support kotlin typedefs? (Lint for Kotlin won't be fully
supported until AS 3.1, and we're on 3.0 still)
Do you mean typealias? If so, yes.
Will I get a lint warning for an exhaustive when when I do a return
when(intDef) { .. } and accidentally omit one of the the possible
types?
An else will always be required here. Not sure about the lint warning
though.
Does AS have an intention (alt + enter to quickly add all variants of
the intDef?
Yes.
Like right now, instead of shipping features, we're discussing when
this micro-optimization should be used!
Summation of the entire enum conversation since about 2012!
I'm also wondering if a sealed class where each implementation is an
object has some perf gains over an enum
None. It's effectively the exact same thing as an enum.
I've been programming in R for around a year now, and am just starting to teach myself Java. One thing I've loved about R is the family of apply() functions (e.g. sapply, mapply, apply etc.).
I was wondering if Java had equivalent functions, or if anyone had written these up in Java - I may be able to give some of these a basic go myself, but I wouldn't be able to do much in terms of the optimisation they seem to have (i.e. sapply(FUN, X) seems much faster than for(i in 1:length(X)) FUN(X[i]) in many cases).
If not, am I thinking about this badly e.g. perhaps you don't tend to need to apply some function, FUN to each element of a vector often since Java is object-oriented, so in typical problems where you'd want to use these, Java's not your best bet, or there are other ways of approaching it?
The functional additions in Java 8 should address your concerns.
Previous to java 8 java is not a functional language.
A functional language is a language where it is possible to pass a function as an argument to another function.
The introduction of Lamba expressions solve this problem.
If you can't use java 8 the only possibility is to create an interface with only one method (apply for example) and manually call the apply method when needed (see for example how swing works to handle events like click).
Hi the following post says there is "built in dependency injection" in scala
"As a Scala and Java developer, I am not even slightly tempted to
replace Scala as my main language for my next project with Java 8. If
I'm forced to write Java, it might better be Java 8, but if I have a
choice, there are so many things (as the OP correctly states) that
make Scala compelling for me beyond Lambdas that just adding that
feature to Java doesn't really mean anything to me. Ruby has Lambdas,
so does Python and JavaScript, Dart and I'm sure any other modern
language. I like Scala because of so many other things other than
lambdas that a single comment is not enough.
But to name a few (some were referenced by the OP)
Everything is an expression, For
comprehensions (especially with multiple futures, resolving the
callback triangle of death in a beautiful syntax IMHO), Implicit
conversions, Case classes, Pattern Matching, Tuples, The fact that
everything has equals and hashcode already correctly implemented (so I
can put a tuple, or even an Array as a key in a map), string
interpolation, multiline string, default parameters, named parameters,
built in dependency injection, most complex yet most powerful type
system in any language I know of, type inference (not as good as
Haskell, but better than the non existent in Java). The fact I always
get the right type returned from a set of "monadic" actions thanks to
infamous things like CanBuildFrom (which are pure genius). Let's not
forget pass by name arguments and the ability to construct a DSL.
Extractors (via pattern matching). And many more.
I think Scala is
here to stay, at least for Scala developers, I am 100% sure you will
not find a single Scala developer that will say: "Java 8 got lambdas?
great, goodbye scala forever!". Only reason I can think of is compile
time and binary compatibility. If we ignore those two, all I can say
is that this just proves how Scala is in the right direction (since
Java 8 lambdas and default interface methods and steams are so clearly
influenced)
I do wish however that Scala will improve Java 8
interoperability, e.g. support functional interfaces the same way. and
add new implicit conversions to Java 8 collections as well as take
advantage to improvements in the JVM.
I will replace Scala as soon as
I find a language that gives me what Scala does and does it better. So
far I didn't find such a language (examined Haskell, Clojure, Go,
Kotlin, Ceylon, Dart, TypeScript, Rust, Julia, D and Nimrod, Ruby
Python, JavaScript and C#, some of them were very promising but since
I need a JVM language, and preferably a statically typed one, it
narrowed down the choices pretty quickly)
Java 8 is by far not even
close, sorry. Great improvement, I'm very happy for Java developers
that will get "permission" to use it (might be easier to adopt than
Scala in an enterprise) but this is not a reason for a Scala shop to
consider moving back to Java." [1]
what is exactly the built in dependency injection in scala?
It's not a discrete language feature. I think the author was referring to the fact that Scala's feature set is flexible enough to support a number of techniques that could be said to accomplish DI:
the cake pattern, building on the trait system
the Reader monad, building on higher-kinded types
DI through currying, building on functional techniques
using implicit class parameters, building on Scala's concept of implicits
in my own project, we accomplish DI by requiring function values in the class constructor explicitly
This diversity is rather emblematic of Scala. The language was designed to implement a number of very powerful concepts, mostly orthogonally, resulting in multiple valid ways to solve many problems. The challenge as a Scala programmer is to understand this breadth and then make an intelligent choice for your project. A lot of times, that choice depends on what paradigms are being used internally to implement your components.
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 9 years ago.
Improve this question
Much of my programming background is in Java, and I'm still doing most of my programming in Java. However, I'm starting to learn Python for some side projects at work, and I'd like to learn it as independent of my Java background as possible - i.e. I don't want to just program Java in Python. What are some things I should look out for?
A quick example - when looking through the Python tutorial, I came across the fact that defaulted mutable parameters of a function (such as a list) are persisted (remembered from call to call). This was counter-intuitive to me as a Java programmer and hard to get my head around. (See here and here if you don't understand the example.)
Someone also provided me with this list, which I found helpful, but short. Anyone have any other examples of how a Java programmer might tend to misuse Python...? Or things a Java programmer would falsely assume or have trouble understanding?
Edit: Ok, a brief overview of the reasons addressed by the article I linked to to prevent duplicates in the answers (as suggested by Bill the Lizard). (Please let me know if I make a mistake in phrasing, I've only just started with Python so I may not understand all the concepts fully. And a disclaimer - these are going to be very brief, so if you don't understand what it's getting at check out the link.)
A static method in Java does not translate to a Python classmethod
A switch statement in Java translates to a hash table in Python
Don't use XML
Getters and setters are evil (hey, I'm just quoting :) )
Code duplication is often a necessary evil in Java (e.g. method overloading), but not in Python
(And if you find this question at all interesting, check out the link anyway. :) It's quite good.)
Don't put everything into classes. Python's built-in list and dictionaries will take you far.
Don't worry about keeping one class per module. Divide modules by purpose, not by class.
Use inheritance for behavior, not interfaces. Don't create an "Animal" class for "Dog" and "Cat" to inherit from, just so you can have a generic "make_sound" method.
Just do this:
class Dog(object):
def make_sound(self):
return "woof!"
class Cat(object):
def make_sound(self):
return "meow!"
class LolCat(object):
def make_sound(self):
return "i can has cheezburger?"
The referenced article has some good advice that can easily be misquoted and misunderstood. And some bad advice.
Leave Java behind. Start fresh. "do not trust your [Java-based] instincts". Saying things are "counter-intuitive" is a bad habit in any programming discipline. When learning a new language, start fresh, and drop your habits. Your intuition must be wrong.
Languages are different. Otherwise, they'd be the same language with different syntax, and there'd be simple translators. Because there are not simple translators, there's no simple mapping. That means that intuition is unhelpful and dangerous.
"A static method in Java does not translate to a Python classmethod." This kind of thing is really limited and unhelpful. Python has a staticmethod decorator. It also has a classmethod decorator, for which Java has no equivalent.
This point, BTW, also included the much more helpful advice on not needlessly wrapping everything in a class. "The idiomatic translation of a Java static method is usually a module-level function".
The Java switch statement in Java can be implemented several ways. First, and foremost, it's usually an if elif elif elif construct. The article is unhelpful in this respect. If you're absolutely sure this is too slow (and can prove it) you can use a Python dictionary as a slightly faster mapping from value to block of code. Blindly translating switch to dictionary (without thinking) is really bad advice.
Don't use XML. Doesn't make sense when taken out of context. In context it means don't rely on XML to add flexibility. Java relies on describing stuff in XML; WSDL files, for example, repeat information that's obvious from inspecting the code. Python relies on introspection instead of restating everything in XML.
But Python has excellent XML processing libraries. Several.
Getters and setters are not required in Python they way they're required in Java. First, you have better introspection in Python, so you don't need getters and setters to help make dynamic bean objects. (For that, you use collections.namedtuple).
However, you have the property decorator which will bundle getters (and setters) into an attribute-like construct. The point is that Python prefers naked attributes; when necessary, we can bundle getters and setters to appear as if there's a simple attribute.
Also, Python has descriptor classes if properties aren't sophisticated enough.
Code duplication is often a necessary evil in Java (e.g. method overloading), but not in Python. Correct. Python uses optional arguments instead of method overloading.
The bullet point went on to talk about closure; that isn't as helpful as the simple advice to use default argument values wisely.
One thing you might be used to in Java that you won't find in Python is strict privacy. This is not so much something to look out for as it is something not to look for (I am embarrassed by how long I searched for a Python equivalent to 'private' when I started out!). Instead, Python has much more transparency and easier introspection than Java. This falls under what is sometimes described as the "we're all consenting adults here" philosophy. There are a few conventions and language mechanisms to help prevent accidental use of "unpublic" methods and so forth, but the whole mindset of information hiding is virtually absent in Python.
The biggest one I can think of is not understanding or not fully utilizing duck typing. In Java you're required to specify very explicit and detailed type information upfront. In Python typing is both dynamic and largely implicit. The philosophy is that you should be thinking about your program at a higher level than nominal types. For example, in Python, you don't use inheritance to model substitutability. Substitutability comes by default as a result of duck typing. Inheritance is only a programmer convenience for reusing implementation.
Similarly, the Pythonic idiom is "beg forgiveness, don't ask permission". Explicit typing is considered evil. Don't check whether a parameter is a certain type upfront. Just try to do whatever you need to do with the parameter. If it doesn't conform to the proper interface, it will throw a very clear exception and you will be able to find the problem very quickly. If someone passes a parameter of a type that was nominally unexpected but has the same interface as what you expected, then you've gained flexibility for free.
The most important thing, from a Java POV, is that it's perfectly ok to not make classes for everything. There are many situations where a procedural approach is simpler and shorter.
The next most important thing is that you will have to get over the notion that the type of an object controls what it may do; rather, the code controls what objects must be able to support at runtime (this is by virtue of duck-typing).
Oh, and use native lists and dicts (not customized descendants) as far as possible.
The way exceptions are treated in Python is different from
how they are treated in Java. While in Java the advice
is to use exceptions only for exceptional conditions this is not
so with Python.
In Python things like Iterator makes use of exception mechanism to signal that there are no more items.But such a design is not considered as good practice in Java.
As Alex Martelli puts in his book Python in a Nutshell
the exception mechanism with other languages (and applicable to Java)
is LBYL (Look Before You Leap) :
is to check in advance, before attempting an operation, for all circumstances that might make the operation invalid.
Where as with Python the approach is EAFP (it's easier to Ask for forgiveness than permission)
A corrollary to "Don't use classes for everything": callbacks.
The Java way for doing callbacks relies on passing objects that implement the callback interface (for example ActionListener with its actionPerformed() method). Nothing of this sort is necessary in Python, you can directly pass methods or even locally defined functions:
def handler():
print("click!")
button.onclick(handler)
Or even lambdas:
button.onclick(lambda: print("click!\n"))
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