<enebo[m]>
oh wow I totally missed what this was for
<headius[m]>
and then pray that expensive_thing() can never raise an error nor has any other side effect
<enebo[m]>
this is almost exactly like wants_array in perl
<headius[m]>
figures perl would have something
<enebo[m]>
that is for returning different type but similar in nature
<enebo[m]>
that is so you can tailor a method for scalar or array
<enebo[m]>
It has existed as long as Perl has as far as I can remember but it is the only language I know which does something like that
<headius[m]>
it's basically another hidden frame field
<enebo[m]>
I thought it was culling real return values if nothing consumed them which was confusing :)
<headius[m]>
what you just said seems like the same thing to me
<enebo[m]>
since you would still need to make them but you would save having to return them
<enebo[m]>
well I guess in my version create_report would still happen but it would not bother pushing the result
<headius[m]>
right, the "value" of this is not creating the report
<enebo[m]>
yeah understood now
<enebo[m]>
My only complaint right now understanding the feature is largely that it is RubyVM
<headius[m]>
in the case of methods that are typically called just for their side effects, it might have some value... but for just about everything else I feel like it will promote bad code
<chrisseaton[m]>
A concrete example could be using `read` to skip bytes, but not wanting a string to be created.
<headius[m]>
it's going to make people use mostly side effects and this trick to eliminate return values
<headius[m]>
chrisseaton: I would argue that should be a different method
<enebo[m]>
Perhaps no overloading + no void is what this is meant to help
<headius[m]>
it's not even that
<headius[m]>
void is explicit
<enebo[m]>
oh I know
<enebo[m]>
I am just trying to think of why you would decide to do this
<headius[m]>
I guess it would amount to a "void call" but you have to query to find out if you were void called
<enebo[m]>
they are trying to combine more behavior into a single def
<headius[m]>
so you'll have methods bifurcate into side effecty and returny
<enebo[m]>
having a pure side-effect method and a valud returning one is what this sort of replaces. It has the wrinkle that the site determines which one you want
<headius[m]>
rather than just providing the right method for each
<enebo[m]>
but so would picking a method name
<headius[m]>
right
<enebo[m]>
So I will stick with a void method syntax would probably be a better solution
<enebo[m]>
then you do need two methods or at least a calling syntax if you want the same name but then you would not be putting a conditional in Ruby itself
<headius[m]>
mmm so you might have defv bar that doesn't do expensive_thing
<enebo[m]>
maybe but then you also need the calling syntax
<headius[m]>
without overloading it would have to be called something else
<headius[m]>
or you add overloading and a way to specify the void version
<enebo[m]>
yeah I think the making two methods thing is the thing they think they are solving
<enebo[m]>
but it also eliminates this discussion of calling altogether
<enebo[m]>
which would probably be harder to get by matz
<enebo[m]>
but if I have learned anything about Ruby is people tend to avoid dispatching in Ruby itself for performance :)
<enebo[m]>
Everything in Ruby is an expression and returns a value. Making a calling syntax which violates that perhaps is a bridge too far
<enebo[m]>
although a void method call could still assign nil if someone assigned to it
<enebo[m]>
with a warn
<headius[m]>
yeah that's a good point
<enebo[m]>
I would not argue too much about this as a Ruby feature but it feels more like a hack than a solution
<enebo[m]>
APIs will be litered with if statements because rubocop will say it is faster and the Ruby way. More ifs is something no language needs
<enebo[m]>
To play devil's advocate with myself I wonder how many methods will really apply to this pattern
<enebo[m]>
If it ends up being very limited then perhaps my concern is not a very big one
<enebo[m]>
@io.read(30) is an interesting use case though
<enebo[m]>
How do we know it even read 30
<enebo[m]>
so in cases like this no return should raise and then the feature will be used to catch runtime coding errors
<headius[m]>
well you'd have to be really careful about using this inside read
<headius[m]>
it has to still do everything BUT the string creation
<headius[m]>
but the logic to do read needs a buffer to read into, usually, so you'll have to split the logic in two for the non-return version
<enebo[m]>
I would say any resource with side-effects using this is probably dangerous
<headius[m]>
over and over again
<enebo[m]>
but it could be used to signal bad coding
<enebo[m]>
if you do not handle the read return you could raise
<enebo[m]>
That actually feels useful
<headius[m]>
it feels like the only safe cases will be the ones that are just a simple allocation, and in such cases you'd be better off inlining and eliding
<headius[m]>
rather than having users sprinkle this all over their code
<enebo[m]>
but I suppose then people will add code like that in places where you really do not need to care and it will piss you off that you need to make a bogus variable
<headius[m]>
in chrisseaton example of generating a report... the report generation may trigger errors, or may have other side effects on the database or in-memory data model
<headius[m]>
if you simply don't do it you're changing behavior depending on how you make the call
<enebo[m]>
yeah semantically by not doing assignment you will get different behavior
<headius[m]>
again, the only safe case is the simple allocation, which could be elided safer ways
<enebo[m]>
so the signature of the method is whether you assign or not
<headius[m]>
I think shyouhei wants this to fix small cases, but it will be abused like mad
<enebo[m]>
I think most people expect the method to do the same thing whether you assign or don't
<headius[m]>
and what if the call is the last one in the caller? but the caller of that method doesn't use it? now it suddenly goes back to being needed?
<enebo[m]>
I think he thinks people will just use this in places where performance really matters but that will be a mistake in the end since people will use it in the name of being faster
<headius[m]>
so the caller needs to know this has logic to elide a return value and explicitly return nil
<headius[m]>
but only if that return value wont' be needed
<headius[m]>
and won't have side effects
<headius[m]>
ad infinatum
<enebo[m]>
well I hope it is not a recursive stack check :)
<enebo[m]>
I hope if it is last value of calling method it just stops and says yep it uses value as return
<headius[m]>
gross
<headius[m]>
so a call gets moved to the bottom of a method and now it looks like the return value is wanted
<enebo[m]>
A single level probably makes more sense since if you can allow any method which returns to check then that method will be randomly doing A then B behavior
<headius[m]>
so you'll have people doing return nil everywhere to try to coax this optimization out
<enebo[m]>
randomly is strong but it wuold be very odd
<headius[m]>
and then also checking this bit
<headius[m]>
because you don't know if YOUR caller might want the value
<headius[m]>
every method in an app might have this check and change how they make calls as a result
<headius[m]>
for want of a different method
<enebo[m]>
My main problem atm is that assignment changes the meaning of the method. The intention of this PR is not to do that but I suspect it will be the eventual outcome
<headius[m]>
we'll see code with `if return_value_used?; expensive_call(); else; expensive_call(); return nil; end`
<headius[m]>
I guarantee it
<enebo[m]>
heh I hope not
<enebo[m]>
probably with a lot of code between
<enebo[m]>
expensive_call(); return nil if return_value_used? is equiv
<enebo[m]>
err not quite
<enebo[m]>
anyways that version bothers me less in that it at least behaves the same sans return value...it is gross though
<enebo[m]>
people reading code will have to consider whether they assign or not and then read docs to make sure something does or does not happen based on that assignment or lack
<enebo[m]>
will social pressure end up making that previous sentence never happen?
<headius[m]>
someone will implement Haskell with this
<enebo[m]>
ok I need to continue on release but that is my current main concern
<enebo[m]>
My concern will for sure happen so it is mostly just a consideration of how much
<headius[m]>
ruby-core needs to decide if they are on redmine or github
<enebo[m]>
yeah truly
<enebo[m]>
maybe I should put that over on ruby-lang too
<enebo[m]>
I did
<headius[m]>
it couldn't hurt
<headius[m]>
a bot that reposts would help but seriously, pick a place
<enebo[m]>
fwiw, this is a 2-part API. I think the C Ruby part of it is ok
<enebo[m]>
It could lead to my same concern but I feel like the exposure of how many people write cext methods is quite small
<enebo[m]>
If they break semantics like I fear then there is more hope someone will fix it and internally MRI can utilize this
<headius[m]>
I don't care about the CRuby part of it really... we already can split Java-based methods on arity, and splitting on void would just be another permutation
<enebo[m]>
(nothing prevents people outside code from using anything either)
<enebo[m]>
yeah
<headius[m]>
I mean the C API part of it
<enebo[m]>
outside core of MRI I meant above
<enebo[m]>
yeah
<headius[m]>
next thing people will want is to be able to refine return_value_used?
<enebo[m]>
refine it
<headius[m]>
and alias it and send it and a million other things
<enebo[m]>
alias it in a refinement with use of caller and binding
<headius[m]>
caller[2].binding.eval "RubyVM.return_value_used?" does what?
<enebo[m]>
headius: the fact that this feature is what led to that video meant you were already very close to the precipice
<headius[m]>
I threw in a few arguments against exposing it as a user callable feature
<enebo[m]>
ok I think bits are ok. I will put something out after I eat
<headius[m]>
well, it's basically a compiler pragma
<headius[m]>
I don't think that's what we want Ruby to become
<headius[m]>
I sure don't
<enebo[m]>
wantarray worked in Perl but largely because everything was either a single value or an array of values. That duality generally lead to scalar being something like length of array and array being the array itself in API design
<enebo[m]>
but the duality was obvious on how it was to be used
<headius[m]>
wantarray is a very localized version of this
<enebo[m]>
yeah for sure
<headius[m]>
again probably because of the lack of overloading
<enebo[m]>
it is the only example I can think of though
<enebo[m]>
well it is Larry Wall
<headius[m]>
Scala has overloading on return value, which is what this wants
<headius[m]>
use site overloading basically, which would make this automatic
<headius[m]>
JVM bytecode can overload on return value but Java the language can't
<headius[m]>
so in Java you fix that by defining another method!
<headius[m]>
which is the right way to opt-into this
<enebo[m]>
"You'll have to get used to Dr. Malcolm" s/Malcolm/Larry Wall/
<headius[m]>
I wish I had the skills to make that mashup
<headius[m]>
ever since I saw one of his Exegesises live I feel like I understand perl in my soul
<enebo[m]>
I always think of him as bringing the hippy spirit to language design
<enebo[m]>
I got off that train before Perl 6 too :)
<headius[m]>
tenderlove is thumbs down on it
<headius[m]>
for the same reasons we've discussed
<headius[m]>
he posted
<headius[m]>
enebo: bits pushing?
<headius[m]>
oh after lunch
<headius[m]>
gotcha
<headius[m]>
I guess I'll eat
drbobbeaty has quit [*.net *.split]
victori has quit [*.net *.split]
ebarrett has quit [*.net *.split]
michael_mbp has quit [*.net *.split]
ebarrett has joined #jruby
drbobbeaty has joined #jruby
michael_mbp has joined #jruby
Antiarc has quit [*.net *.split]
sagax has quit [*.net *.split]
dopplergange has quit [*.net *.split]
Antiarc has joined #jruby
victori has joined #jruby
dopplergange has joined #jruby
sagax has joined #jruby
<headius[m]>
nirvdrum: tweet was just about this return_value_used? feature discussed above
<headius[m]>
I just don't want a bunch of greybeards to descend on it
<nirvdrum>
headius[m]: Ahh, thanks. I thought it might be some internal RH thing you couldn't discuss.
<headius[m]>
Red Hat have secrets? Perish the thought