<boc_tothefuture[>
@headius. I pushed the example in that gist I referenced above. It must be something OpenHab is doing with the script engine that in some way impacts JRuby, but not Jython... Just not sure what that would be.
<byteit101[m]>
Ah yes, retraining muscle memory for new keyboards :-)
<headius[m]>
unfortunately the config software is windows only so it will just be on RGB chase sequence for a while
<byteit101[m]>
Fancy! a bendy one
<headius[m]>
yeah hopefully it isn't too hard to get used to
<headius[m]>
looking at your pr now
<byteit101[m]>
I'm sorry in advance :-)
<headius[m]>
do you have a description of the current init sequence?
<byteit101[m]>
There's several options for my impl, but if you are referring tot the current 9.2.x, see 449 (linked at top)
<byteit101[m]>
*to
<byteit101[m]>
(it's the diagram in 449)
<headius[m]>
first thing I wondered is whether running the ruby init after the java constructor is a change
<byteit101[m]>
(sans the java side, as that was the proposal)
<byteit101[m]>
Yes, it is
<headius[m]>
ok that diagram right
<byteit101[m]>
that was one of my major questions: should java init sequence == ruby init sequence
<headius[m]>
I am not sure from your diagram whether the ruby init can manipulate args passed to the java constructor
<headius[m]>
currently
<byteit101[m]>
in 9.2.x, it can
<headius[m]>
my concern then is that if someone is extending a class they probably want to control when and how the parent constructor is called and we lose that here
<headius[m]>
trying now to think through how we can do both though and it is hard
<byteit101[m]>
Yes, that is what the super splitter proposal and demo is for
<byteit101[m]>
yes, I was looking at project loom :-)
<byteit101[m]>
I used a lambda in the demo
<headius[m]>
better mabe to just make a set of explicit stages in construction that can be hooked
<byteit101[m]>
yea, the only downside is if you compute something for super, how do you pass it on if you don't want to stuff it in an @ivar (as I mention in one of the samples on 449). That was what I was attempting to see
<byteit101[m]>
and in the part you pasted, "continuation" is anything that does the rest of init, be that a new hook, an actual contionation, a lambea, etc. I'm not wed to true continuations
<byteit101[m]>
*lambda
<headius[m]>
I am coming around to the idea of the ruby init just being a standalone non-superable method if there's another mechanism to get in front of the java super constructor call
<headius[m]>
ok i see
<headius[m]>
so it is allowing a way to defer a part of init in this sequence
<byteit101[m]>
yes, from the perspective of a traditional init sequence
<byteit101[m]>
The pre+post seperation is because we can't pass an uninitializedThis object around in bytecode
<byteit101[m]>
so the <init> method MUST be the one to call invokespecial <init>, ....
<byteit101[m]>
on the superclass
<headius[m]>
reify code does not regenerate on purpose because you are explicitly sayong at that moment in time to generate the java type
<byteit101[m]>
ah!
<headius[m]>
limiting regeneration is totally acceptable to me as long as redefined methods (e.g. monkey patched) still get invoked
<headius[m]>
the type we create can be a one shot deal
<headius[m]>
I doubt anyone has ever really taken advantage of that regen
<byteit101[m]>
caveat: #new implicity reifies
<headius[m]>
right, which is how interface extension works anyway... once you start making instances the type is set
<byteit101[m]>
cool
<headius[m]>
I think there is an error in the diagram
<headius[m]>
java object is inited on the far left and later in that sequence shows as initing?
<byteit101[m]>
Ah, yes, should both be initing
<headius[m]>
because the java obj constructor calls the ruby init, ok
<byteit101[m]>
added correction note above
<headius[m]>
ok
<byteit101[m]>
for future reference
<headius[m]>
yeah so I come back to the "new api" idea and not using initialize in this sequence because maybe it will just be confusing
<headius[m]>
looking at idea in 449 now
<headius[m]>
java_init
<byteit101[m]>
so you are fine with the idea that ruby classes that extends java classes will behave differently from pure ruby classes?
<headius[m]>
in general yes because it seems unavoidable anyway
<headius[m]>
looking at this more like scripting a new java subclass rather than trying to pretend there's no separation
<headius[m]>
I mean in an extreme API it might b
<headius[m]>
be like a DSL
<headius[m]>
but that is probably not necessary
<byteit101[m]>
Because aside from the caviats of nested blocks (avoidable if we go java-style and say super must be at top level?), it is doable to re-use initialize, I think.
<headius[m]>
thinking of use cases here...
<byteit101[m]>
Also, avoiding initialize would break the current API
<headius[m]>
why do people extend... one is to override behavior and inherit the reset
<byteit101[m]>
though if you are saying to break it, I'm not going to argue :-)
<headius[m]>
well this is where I have a problem... wondering how much will break if the old stuff goes away completely
<headius[m]>
then we end up adding rather than replacing and as you have seen there's too much of that
<headius[m]>
wanting to
<headius[m]>
be able to construct from java is a very specific use case
<headius[m]>
It would be nice to know how many users are calling super
<byteit101[m]>
that was one question I was going to ask: is there an easily downloadable corpus of jruby ruby code?
<headius[m]>
ok so bottom line, yes I think it is fine for the sequence to differ on the two sides
<headius[m]>
it is a limitation we can't really get around
<headius[m]>
if you can't super from initialize, though, I am reluctant to call it initialize, but as you say that breaks current API
<headius[m]>
but breaking super does too
<headius[m]>
so that is a question of impact
<byteit101[m]>
eww, ok, first project I checked of mine does this: class NBWrap < Java::JavaIo::InputStream
<byteit101[m]>
def initialize(io)
<byteit101[m]>
super(io.to_java.getInStream)
<headius[m]>
yeah I fear it may be fairly common
<byteit101[m]>
Initialized from PTY.open
<headius[m]>
so I asked about new because maybe we change the sequence there to better match the java side
<headius[m]>
really the only thing it would do is <init> the java object and the java constructor would call initialize
<byteit101[m]>
> but breaking super does too
<byteit101[m]>
wait, sorry, which proposal breaks super, and how?
<headius[m]>
I mean making the initialize super now be a no-op
<byteit101[m]>
Ah, right, ok!
<headius[m]>
if we wanted to or needed to keep that intact then why not completely divorce the ruby new from the typical ruby sequence
<byteit101[m]>
> really the only thing it would do is <init> the java object and the java constructor would call initialize
<byteit101[m]>
The PR implements this right now for some configurations as it's essential for the super-splitting to work
<headius[m]>
new would construct java object by calling java init, which would construct ruby proxy and call its initialize
<headius[m]>
ok
<headius[m]>
I am trying to avoid the splitting... if we conceptually treated initialize as though it were the body of the java constructor there is nothing to split, right?
<byteit101[m]>
that is, in fact, " a way around not being able to call super directly"
<headius[m]>
so this case allows ruby to xform the args on the way but no super because we can't
<byteit101[m]>
correct
ur5us has joined #jruby
<headius[m]>
existing code avoids this by generating a special java init that does the java super init call and initialize calling super just triggers the java object construction along that path
<byteit101[m]>
correct
<headius[m]>
sorry if I am going around in circles a bit
<byteit101[m]>
not at all!
<byteit101[m]>
It's a tricky thing to get right, and I'd prefer to get it right
<headius[m]>
so open question is whether we can invoke java super init from outside java init, like in response to a ruby initialize with super
<byteit101[m]>
any good/easy indy playgrounds so I can verify if indy super is viable?
<headius[m]>
in normal bytecode we cannot but indy handle might make it possible
<headius[m]>
sure on MethodHandles.Lookup class there is a way to get handle to "special" calls
<headius[m]>
generate the Ruby initialize body directly into the Java init
<headius[m]>
no dispatch
<byteit101[m]>
> *another option is to JIT the method, but then you loose dynamism, so I haven't suggested that
<byteit101[m]>
^
<headius[m]>
right
<headius[m]>
it may be fine for initialize though
<headius[m]>
it simplifies this sequence quite a bit
<byteit101[m]>
quite!
<headius[m]>
also in order to handle arg conversion it would translate ruby super to a java this() call that does the converting and eventual super()
<headius[m]>
so initialize calls super, which does invokespecial of this.<init>(ruby arguments) and that eventually does java super with java args
<headius[m]>
just spitballing here
<headius[m]>
this is more work obviously but it would eliminate the split construction
<headius[m]>
IR transform would change super in these initialize methods into something like JavaSuperInstr
<byteit101[m]>
yes. I haven't investigated, as I didn't like the loss of dynamism (and the jit code looked scary :-P)
<headius[m]>
yeah it is a challenge but I think it would basically unify the two sides of construction finally
<headius[m]>
outside of that option I think the arg-massaging path might be simplest... explicitly show that it is not initialize but it participates in init sequence
<headius[m]>
the java_init style or the continuation that happens later
<byteit101[m]>
yes
<headius[m]>
hmmm
<byteit101[m]>
well, simplest to implement? It's not the simplest conceptually from a users point of view
<headius[m]>
one tricky bit is that the jit currently generates static methods but that can be adjusted
<headius[m]>
yeah simplest to implement
<headius[m]>
because it makes the sequence explicit
<headius[m]>
you just hook in at appropriate stages
<headius[m]>
ok so lets call the jit version a stretch goal for now
<byteit101[m]>
breaking change with that: see balloon example (scroll up) and `p self` will fail to compile
<byteit101[m]>
6:16pm
<byteit101[m]>
as it's before super
<byteit101[m]>
oh hmm, actually that is safe
<byteit101[m]>
but if it was `p self.to_java` it might change
<byteit101[m]>
no, still NPE as today, ok NVM
<headius[m]>
how does the balloon example work on PR now?
<byteit101[m]>
as you expect, works fine
<headius[m]>
what happens at the super call I mean