Societies have written regulations, which you MUST follow: it is what participants expect and what defends your actions in case of court cases. There never, ever is self-elected elite which will be able to solve conflicts.
Expressions and behaviour of participants is either lawful (so must be accepted), or unlawful (not for "normal" people to decide about punishment). Regulation is different for open and closed meetings, and media.
Those American Style Code of Conduct must be banned from our events: they damage us. FOSDEM, CCC and many more, show us how to do it: how to stay sane.
To solve this: ditch all rules which violate freedom of speech. For each event, assign a team of mediators in case of conflicts. Harassment claims and such are police business.
]]>But forbidding people to say unpleasant things beforehand is not allowed in the EU. Kicking people out solely because a few non-elected others do not like your expression is not acceptable. But it has been done a few times now. Giving your own interpretation on very sensitive terms as harassment is really wrong.
Event organize MUST mediate when there are problems. As resolution, the MAY kick-out someone for that event. They can be asked in court for their reasons, and will often loose. (That's why you should get an organizers insurance)
Organizers can impose a bit stricter rules when the event is for members of an association, where the rules have passed a vote on the members meeting. We lack all of that in the Perl community, so end-up in horrible fights and a self-elected elite.
]]>TPF should offer a boilerplate set of community guidelines which perl affiliated projects may elect to adopt.
Beyond that, perhaps a mediation service should be offered to assist in resolving complaints. Projects may then wish to opt-in to the outcome of these resolutions.
This is not the first time this has happened, it is however the first time the perl community didnt pile on to someone. That's something *everyone* should think about.
https://blogs.perl.org/users/lets_code_perl/2019/07/tpf-perl-deserves-better-please-do-better.html
Couldn't lexical subs be extended to just work as private methods too...
If they’re not methods, they wouldn’t (and shouldn’t!) have a $self
variable. Which means, as you later suggested, that we’re back to:
my method _print_x () {...}
But methods (even lexical ones) need to be called on an explicit object, so we’re back to calling them like so: $self->_print_x()
And that still doesn’t solve the performance issue. If we allow lexical methods, then we have to extend the standard method call behaviour to pre-check whether we’re in a class block and, if so, to search for any suitable lexical methods in that current scope, before doing the usual class-based method look-up.
That could slow down every method call everywhere in Perl. Though, depending on the implementation, it might merely slow down every method call with every class
block.
Graham’s lexical-method-call proposal (i.e. $self->&_print_x()
) is especially interesting here, because it would also solve that performance issue, by only doing the lexical look-up.
Though, of course, it might introduce its own issues, since Corinna objects should only allow a method calls on actual Corinna methods, not on traditional Perl subroutines-pretending-to-be-methods.
Which means the $self->&_print_x()
syntax would first have to check whether or not it is inside a Corinna class
block, and then switch its lexical look-up accordingly.
That wouldn’t necessarily introduce a performance penalty, however, as the check-and-switch-look-up-mechanism process could (and should!) be performed only once — at compile-time — for each such call.
]]>If methods can be called like subs, then every sub call
now also has to check whether there's a suitable method to call instead.
And should it check for that method before checking for a sub, or after?
Probably after, but one could argue it both ways.
I think there’s a lot of value in being able to visually distinguish method calls from subroutine calls just by their call syntax. In fact, I think there’s a lot of benefit in being able to distinguish public method calls from private ones (and both of them from sub calls too).
That’s why I rather like Graham’s $self->&foo()
suggestion.
Because I no longer have to think about the differences between:
$self->foo(); # Public method call
$self->&bar(); # Private method call
baz(); # Subroutine call
I can tell them apart instantly, simply by the way they look.
No, subs are always looked up at runtime (unless, of course, you’re calling them
in a BEGIN
, CHECK
, UNITCHECK
, INIT
, or END
block).
It has to be runtime because Perl has to support runtime changes
in the implementation of a subroutine, in the form of typeglob reassignments:
local *foo = sub {...};
Prototypes certainly do affect compile-time parsing, but not runtime dispatch.
...it allows one to distinguish method calls from sub calls...but not requiring it
would result in more concise code.
This is the heart of our disagreement, I suspect.
I’m never in favour of trading affordance for conciseness. :-)
Also, the same argument could then be applied to slots and so,
being able to access object slots as regular variables shouldn't be allowed.
To me the argument is that it’s useful to be able to mentally and visually distinguish
between the the public API to a slot (which is a set of polymorphic methods)
and the actual storage for that slot (which is a variable).
Outside its class, a slot is only accessible via its public API; inside the class,
it’s accessible in two distinct ways: via its API or via its variable.
Hence, inside the class, we need two syntaxes for those two different types of access.
And I think that those two syntaxes should visually distinguish the kind of access
you’re getting: unconstrained and monomorphic access via the $slotname
syntax,
versus constrained and polymorphic access via the $self->slotname()
syntax.
And for exactly the same reason I don’t want us to use methodname()
to mean $self->methodname()
. Because it doesn’t allow us to visually or syntactically
distinguish between foo()
(a private method call) and bar()
(a subroutine call).
Because sub calls and method calls are different constructs
with different interfaces and behaviours, whereas lexical variables
and slot variables are the same construct with identical interfaces
and behaviours.
For me, language design is all about balancing the design goals of:
And, to me, using the foo()
syntax for both subroutines and private methods
doesn’t meet those three criteria.
It lacks affordance, because it means that something as straightforward as:
my method foo () {...}
method other {
...
$self->foo();
...
}
...will fail at runtime.
It lacks expressiveness, because I can’t tell just by looking at the following code:
method other {
...
foo();
...
}
...whether or not the call to foo()
will be passed $self
as its first argument.
Instead I have to go somewhere else and look at the definition of foo()
.
And that definition might be before or after the definition of other()
,
and not necessarily even in the same class, or even in the same file.
It also lacks intentionality, because I also can’t tell just by looking
whether the author of that previous code example was intending to call
a subroutine with no argument, or to call a method with one implicit argument.
So the “obvious” version of the call doesn’t work, and I can’t easily tell whether
the less obvious version is correct, or precisely what it’s going to do.
To me, that’s not a good solution.
In fact, at this point, I’d much rather we jettisoned private methods entirely,
and simply used regular lexical subroutines instead:
my sub foo ($self) {...}
method other {
...
foo($self);
...
}
The only problem with that approach is that it doesn’t give us an eventual
path forward on protected methods. (Not that I actually want protected methods either;
I think they’re a misfeature in OO languages, because they inevitably couple
the internals of derived classes to the implementation details of their base classes,
which subverts the fundamental principle of OO encapsulation.)
Of course, while lexical-as-private doesn’t help with protected methods,
neither do the current proposed syntaxes of either method $foo
/$self->$foo()
or my method foo
/$self->&foo()
.
So, if we are one day going to have protected methods, I think we have to
come up with a syntax, and an implementation, for private methods
that extends cleanly and obviously to protected methods as well.
Which is why I originally proposed:
method foo :private ($self) {...}
method other {
...
$self->foo();
...
}
...which then cleanly extends to:
method foo :protected ($self) {...}
method DerivedClass::other {
...
$self->foo();
...
}
One of the deep problems with language design (and, in particular, with the
ongoing design of Perl) is that we can’t just come up with a neat and clever
solution to each individual design problem in isolation. That’s how we paint
ourselves into an inextricable syntactic corner. Or end up with a
Frankenlanguage.
We need to consider not just what would be easy and convenient right now,
but also what is going to make the next five or ten design steps easier,
more convenient, and — above all — more consistent into the future.
That said, I truly appreciate your thoughtful and valuable contributions
to this discussion, Salvador. They are certainly helping me clarify
my own thinking and also, I believe, helping us collectively make
the right choices for Corinna...and for Perl.
And, to me, when two constructs are very similar but still distinct
that’s precisely when you want them to have distinctly dissimilar syntax.
So that when you’re writing the code you’re forced to think how
to unambiguously express whichever of them you actually intend.
And so that everyone is automatically helped to recognize which of them
was actually intended when they’re subsequently reading that code.
Also, there are several programming languages that use the same syntax for both... Common Lisp/CLOS uses the same syntax for everything. Admittedly all this programming languages have their issues... but I never heard anybody say the overloaded subroutine call syntax was one of them.
I was (a small) part of the C++ design discussions twenty-five years ago,
and I was certainly saying that, even back then.
And Larry Wall once specifically called out Lisp’s complete lack of syntactic affordance
as having “...all the visual appeal of oatmeal with fingernail clippings mixed in.”
I have to admit that for me, they real issue I have with supporting $self->private_method is that I see lots of issues at the implementation level.
I’m sure you’re right. But, like Larry, I’m always in favour of making
the implementors’ lives harder in order to make the developers’ lives easier. ;-)
Of course, Larry had far more right to hold that view than I do:
he’s an implementor himself; I am not.
For instance, what happens when you have...
return $self->foo + $b->foo + $c->foo;
Private methods by their very nature don’t participate in inheritance,
so you should get:
return $self->foo # A::foo() called
+ $b->foo # Can't call private B::foo() outside class B
+ $c->foo; # C::foo() if public, otherwise exception
Whereas, if you had actually wanted the same private A::foo()
called on $b
and $c
, then you'd have written it like so:
my sub foo($self) { ... }
sub bar() {
my $b = B->new();
my $c = C->new();
return foo($self) + foo($b) + foo($c);
}
You see, that’s exactly the problem with private methods.
Your “right” behaviour can’t be right, because it doesn’t conform to the
existing Perl dispatch behaviour of methods, which is: Go to the object’s
actual class, look for a suitably named method, if it exists then call it,
otherwise try recursively in the parent class(es).
So the method call to $b->foo()
should go to the object’s actual class (B
),
look for a suitably named method (B::foo
), check whether it exists (it does),
then attempt call it (KABOOM! “Can’t call private method B::foo() from class A”).
You’re proposing that we extend the method-call semantics to pre-check for
a possible non-polymorphic dispatch in the current class: First check if
the object isa __CLASS__
, if so then check if there is a suitably named
private method in the current class, and call it if there is, otherwise go to
the object’s actual class, look for a suitably named method, if it exists then call it,
otherwise try recursively in the parent class(es).
So now every method call is more expensive and more confusing. It’s a method call, but it
doesn’t always dispatch polymorphically to the bottom of the inheritance hierarchy to call
the most derived method; sometimes it dispatches statically into the middle of the
inheritance hierarchy to a more-ancestral method.
The “right” behaviour you’re suggesting is really the behaviour of a statically dispatched
subroutine within a lexical scope, not that of polymorphically dispatched method within
a class hierarchy. But the syntax you’re using to make the call labels that call as “method”,
not “sub”.
That’s not clear expressiveness, good affordance, or easily inferrable intentionality.
Otherwise you are requiring the B programmer to know about the private methods up the hierarchy class in order to avoid reusing their names.
No, we are requiring all programmers not to attempt to call private methods on objects
from outside those object’s own classes. Which is what the call to $b->foo()
from inside A
is attempting to do.
Once again, this discussion has been extremely helpful to me, Salvador. Thank-you.
You have managed to convince me that Perl shouldn’t have private methods at all.
That anything one might want to do via a private method would be much better done
via a lexical subroutine. That private method calls are confusing, easy to get wrong,
and lacking in expressiveness, affordance, and intentionality. That the mechanism for
private operations within a class should be lexical subroutines, not specially marked
methods. And that the syntax for executing a private operation within a class
should be the standard subroutine-call syntax, not the polymorphic method-call syntax
(or some new syntactic variant thereof).
I am sincerely grateful to you for that insight.
slot
keyword is now field
as well.field
from here on.]
...the issue is that lexical subs don't have access to the object state.
They only can access the object through its public interface.
That's a severe limitation...
You make a very good point there. One that I had not sufficiently considered.
I hope I am not the only one that would expect that closure over the slot $x to work
It would be great if they did.
However, fields are per-object, not per-scope, so allowing subroutines to close over them
would require some fancy footwork inside the implementation. Specifically, any subroutine
closing over a field would have to be implicitly passed the current invocant object
from the nearest surrounding method call on the stack, and internally would have to
use that object to select and access the actual storage for the field.
Of course, Corinna methods are indeed able close over fields, and so already require
such memory-addressing chicanery. But methods are always explicitly passed
their invocants, so they always have the necessary information to achieve
the correct memory look-up for a closed-over field.
I imagine that extending that per-object look-up to lexical subroutines as well would be
quite a bit trickier. The implementors might not be willing — or even able — to do so.
Which brings us full circle back to needing private methods after all. :-(
And our ongoing disagreement on the correct semantics for them
leads me to conclude that the only reasonable approach left is:
field $counter;
my method increment_counter() {
$counter++; # Methods can always close over fields
}
method track_counter () {
...
$self->&increment_counter(); # Lexical method call syntax
...
}
I think that’s sufficiently syntactically distinct to provide reasonable expressiveness,
affordance, and intentionality.
The only issue is that it doesn’t cleanly extend to allow protected methods as well.
(Though, in my personal opinion, that’s a feature, not a bug! ;-)
The $obj->&private_method()
syntax has a
few more benefits than just being available.
For a start, it is analogous to the existing $obj->$subref()
syntax.
Which, incidentally, does not perform polymorphic dispatch either.
It is also consistent with the Raku call-a-named-subroutine-as-a-method syntax:
# Raku code...
$obj.&subname();
...which doesn’t do polymorphic method dispatch either
(though that’s a more complex issue in Raku, as subroutines
can also be subject to polymorphic or even multimorphic dispatch,
via the multiple dispatch mechanism).
I agree that the $obj->&private_method()
syntax is unusual,
but that just means it stands out well in code. And it has related prior art
in both Perl and Raku. I think that makes it an excellent choice.
Is not ok to just do the same with lexical methods?
No. Methods in Perl are always called with an arrow.
I strongly oppose allowing them to be called like subroutines.
One of the main reasons we’re adding Corinna in the first place
is that it turned out to be suboptimal to reuse packages as classes.
hashes as objects, and subroutines as methods.
Given this modern understanding of the severe disadvantages of
“punning” constructs, I can’t see how reusing subroutine calls
as method calls could be an acceptable choice for Corinna.
Isn’t the answer simply “none”? It seems a trick question. Fields aren’t visible inside a sub
, whether it’s lexical or not, no?
Well, yes, obviously, a closure is a different kind of situation. The question would be what happens in a named sub declared inside a method – where I would expect the exact same behaviour that the “variable will not stay shared” warning cautions against currently. And I would expect the use of a lexical sub to cure the problem, the same way it currently does for regular subs.
]]>has been supported by Zydeco for over a year. documentation.
]]>