API^ABI: java++

See also posts on jvm portability including What’s so special about jvm portability cf python/perl, briefly@@, which introduced SCP/BCP

  • — Breaking API change is a decision by a library supplier/maintainer.
  • clients are required to make source code change just to compile against the library.
  • clients are free to use previous compiler
  • — Breaking ABI change is a decision by a compiler supplier.
  • clients are free to keep source code unchanged.
  • clients are often required to recompile all source code including library source code

API is source-level compatibility; ABI is binary-level compatibility. I feel

  1. jar file’s compile-once-run-anywhere is kind of ABI portability
  2. python, perl… offer API portability at source level

Beneath these simplified rules of thumb, there are many exceptions and subtleties.

— some important scenarios in java

library upgrade — https://stackoverflow.com/questions/536971/do-i-have-to-recompile-my-application-when-i-upgrade-a-third-party-jar

jdk upgrade — https://stackoverflow.com/questions/18254177/do-we-need-to-compile-jar-for-jdk-upgrade

double-ptr is rare@@

  • c# ref-param (on a class type, not a Value data type) is really a double ptr. No other ways to achieve this purpose.
  • java offers absolutely no such support or any support for double-ptr
  • python? not sure. Not common

In conclusion, I now feel

  1. the need for double-ptr is prevalent across languages. One of the most common need is — main() passes into my method a String or List object, and I want to reseat that pointer so that main() will operate on the new String
  2. Despite these common needs, java and probably many new languages were designed from ground up to live without double pointers. It’s a conscious decision, an active refusal. I have not, but you may need to find workarounds.
  3. Workarounds are plenty and never too ugly too convoluted too complex
  4. In fact, many would consider (practically) all double-pointers as ugly and dangerous for the average programmers. If you are more than an average programmer and want to use double-pointers, then those workarounds are rather easy for you.
  5. Conclusion — in this new era, double-pointers are rarely needed.

method == func ptr with an implicit this-ptr

A Microsoft/TwoSigma developer revealed to me that basic OO features can be implemented in C with func ptr. A non-static method is

basically a C function whose first parameter is a ptr to the host object. The func's address is then saved as a func ptr field of

the struct. See also P342 [[headfirstC]]

I also read that in the early days of C++, every C++ source file was once converted to C source code and then compiled as C. That

means all c++ syntax features supported then were like sugar coating over C syntax, and some combination of C language features

(mostly pointers) could emulate all C++ features known then. This was the C++ early days. No longer possible.

pbref^pbclone DEFINED : 3QnA any lang, Part1

pbref include 2 categories – pbcref (const-ref) and pbrref (regular ref). It’s best to update all posts …

  lhs_var =: rhs_var // pseudo code

Reading this assignment in ANY language, we face the same fundamental question –

Q1: copying object address (assume 32 bit) or are we cloning the object? Note input/output for a function call is a trickier form of assignment. In most languages, this is essentially identical to regular LHS/RHS assignments. [1]
Q2: “Is LHS memory pre-allocated (to be bulldozed) or yet to be allocated (malloc)?”
Q3: does the variable occupy a different storage than the referent/pointee object? See http://bigblog.tanbin.com/2011/10/rooted-vs-reseat-able-variables-c-c.html

With these questions,  we will see 2 different types of assignment. I call the them pass-by-reference — pbref vs pbclone — pass-by-cloning (including op= and copy-ctor). These questions are part of my Lesson 1 in Python and C++. Here are some answers

java primitives – pbclone
java non-primitives – pbref
c# value types – pbclone
c# reference types – pbref
c++ nonref by default – pbclone
c++ nonref passing into function ref-param — pbref
c++ pointer – usually pbclone on the 32-bit pointer
c++ literal – pbclone?
c++ literal passing into function ref-param?
php func by default – pbclone
php func ref-param – pbref
php func ref-return – pbref
perl subroutine using my $newVar — pbcloneperl subroutine using $_[0] — pbref
python immutables (string, tuple, literals, frozenset) – pbref — copy-on-write
** python primitive — no such thing. “myInt=3” is implemented same as string. See post on Immutable, initialize etc
python list, dict, set …- pbref

Q: what if RHS of pbref is a literal?
A: then pbref makes no sense.

Q: what if RHS is a function returning by reference?
A: you can get pbref or pbclone

[1] C++ and Perl parameter passing is multifaceted.

Methods are implemented as Fields — function pointer Fields

(It would be great to go back to the earliest OO language, but let’s just start from C++.) The class concept is very similar to the C struct. Now if you add a func ptr as a struct field, then Whoa! A method is born (Today happens to be Christmas…)

Note python treats both fields and methods as “attributes”.

Suppose your struct is named MyStruct and has methods m1(), m2(). You may need to add a pointer-to-MyStruct as a hidden field (named “this”) to MyStruct. You have to pass “this” to m1() as a first argument. Consequently, m1() can reach all the fields of the host MyStruct INSTANCE. Without such an argument, m1() doesn’t know which object it belongs to. Remember all C++ methods are free functions in disguise.

Let me repeat — each method has the same first parameter of type (HostClass*)

That’s the basic idea of a c++ class, but we need some efficiency improvements. If you instantiate 999 instances of MyStruct, then are you going to allocate 999 func-pointers for m1() and 999 func-pointers for m2()?

No. I think you can just add a single pointer-to-MyStruct-class-object as another hidden field to MyStruct. In the singleton MyStruct class object, you keep the addresses of m1() and m2(). Therefore, ARM said the struct instance holds no info about m1().

The vtbl is also part of this singleton object.

Note java puts MyStruct class object in the permanent generation.

Another optimization is where to stored the “this” pointer. Brutal force solution is to add a ptr-to-MyStruct field to MyStruct but  C++ and java compilers all avoid this. I think the compiler treats “this” as a pointer Variable not a pointer Object (like vptr). Implicit conversion —

    myStructInstnace.m1(otherArgs) // becomes
    m1(&myStructInstance, otherArgs); // [aaa]

The [aaa] form isn’t really what compiler does. In MultipleInheritance “this” isn’t the same across Base objects and Derived object.

each method call has a customer-object

J4: fundamental concept for design-pattern. This could be a simple concept, but it’s important to be thoroughly familiar until you can spot the pattern without thinking.

A method call [2] usually has a primary [1] “customer object”, ie the object to consult, to enrich, to read or to modify. This object can be
– the call’s hosting object. eg: student.setAge()
– the call’s argument object. eg: increaseCreditLimit(customer)
– the call’s initiator object. eg: this.amount = product.discount();
– some other object. eg: remoteControl.setCommand(TVon); # TVon object has-a TV object, which is the customer object.

For each method call, You need to quickly spot the customer object when you communicate with other people. Communicate during design, documentation, coaching, …

[1] rarely 2.
[2] we are talking about a call, not a method. Only when you use the method in a business logic can you put your finger on the customer objects.