Tag Info

New answers tagged

2

In a nutshell, Scala can do it because the Scala compiler is a master in code transformation/generation. Which means Java could do it too (maybe it does already). The trick is not made at the bytecode level but at the source level. Could you guess the output of this code: def test[T](f : => Any) : T = { try { val x = f.asInstanceOf[T] ...


2

Reified generics do not require JVM support. Yes, they would be easier and most performant with JVM support, but JVM support is not necessary. For instance, a Scala compiler could, for every class featuring a type variable, add a field that stores the corresponding object: class List<T> { } void test() { List<?> list = new ...


11

To address the specific issue that you raise, of reified generics . . . In many contexts, type parameters are actually saved in class-files and exploitable via reflection, even despite erasure. For example, the following program prints class java.lang.String: import java.lang.reflect.Field; import java.lang.reflect.ParameterizedType; import ...


7

JVM bytecode pretends to be a kind of generic machine code, and it is indeed, so... what makes you think it couldn't support any other language? JVM bytecode is a Turing complete language, and thus, every program, no matter in which language is written, can be compiled/translated into bytecode. There are a lot of languages which already have a bytecode ...


26

"All" programming languages run on x86, so how can they be much different from each other? Brainfuck and Haskell are both Turing complete, so they can both do the exact same tasks. There's a bit of room for syntax changes, syntax sugar and compiler magic in between. You can do quite a lot in there, but there is always a limit. In your case, it's JVM byte ...


6

One of the most important characteristics that make a programming language efficient is the closeness of the supported data types to the native data types of the underlying hardware. An int primitive directly corresponds to a machine word; it does not get any better than that. The moment you turn the int primitive into an Integer object you have degraded ...


0

Writing a compiler to produce machine code may not be much more difficult than writing one which produces C (in some cases it may be easier), but a compiler which produces machine code will only be able to produce runnable programs on the particular platform for which it was written; a compiler that produces C code, by contrast, may be able to produce ...


0

Think of extending as broadening the range of behavioural description and implementation as the concrete behaviour. Say you have an interface quacking. This would be applicable to frogs as well as ducks. You could extend this general interface to swimming and flying which would then only be applicaple to the duck. The mechanism how a duck or frog swims is ...


0

Interface implementation implies a finality that cannot be created by another interface - by their nature, an interface is meant to be incomplete. The only reason you would extend an interface with another interface is if you need to change the defaults in the first one significantly, while still preserving the structure of the original. As an example, ...


10

An interface is a contract. It does not implement anything (properly-used default methods are a small exception). What would it mean for one interface to "implement" another, anyway? It would need to have method bodies for some or all methods on the superinterface, making it a class.


0

In general, you will encounter value types and reference types. With a value type, you don't care about the object that represents it, you care about the value. If I give you a value, you expect that value to stay the same. You don't want it to change suddenly. The number 5 is a value. You don't expect it to change to 6 suddenly. The string "Hello" is a ...


5

There are few possible reasons for this sort of thing: As in JacquesB's answer it may simply be convenience for the library user to call a single method rather than two methods and keep their code more succinct. Performance may be a consideration. Calling .substring(3) will result in a new string being created, and therefore you are looping over the string ...


4

These are called convenience functions. They are included so users can write shorter and simpler code. Note that almost every library is "redundant" in the sense that users could write the same code themselves outside of the library. However the point of using libraries is that you save time and code, and you can reuses the knowledge of the library in ...


11

Let's let Eric Lippert answer this one: The obvious question at this point is: if CPS is so awesome then why don’t we use it all the time? Why have most professional developers never heard of it, or, those who have, think of it as something only those crazy Scheme programmers do? First of all, it is simply hard for most people who are used to ...


1

Null is evil. However, the lack of a null can be a greater evil. The problem is that in the real world you often have a situation where you do not have data. Your example of the version without nulls can still blow up--either you made a logic mistake and forgot to check for Goodman or perhaps Goodman got married between when you checked and when you ...


-3

NULL is a problem because it conceptually represents data that may or may not exist. Data that may not exist is assumed not to exist (because assuming the opposite crashes your program so you always have to assume the value could be NULL). Data that doesn't exist is not worth reasoning about, and is not very useful. If your program is mostly not useful, you ...


1

Assuming the language is dynamically typed, I can see two different ways this could be handled without knowing at compile time if a call is async. One approach would be to assume every call could be async. However, this would be incredibly inefficient and produce a lot of extra code. This is essentially what you are doing in option 2. Another option is to ...



Top 50 recent answers are included