other annotations
zxq9
zxq9@REDACTED
Fri Jan 29 00:10:54 CET 2021
On 2021/01/28 22:17, Raimo Niskanen wrote:
> On Thu, Jan 28, 2021 at 01:43:00PM +0100, Loïc Hoguin wrote:
>> On 28/01/2021 13:11, Richard Carlsson wrote:
>>> Den tors 28 jan. 2021 kl 11:23 skrev Loïc Hoguin <essen@REDACTED
>>> <mailto:essen@REDACTED>>:
>>>
>>> By the way, if annotations are going to be a thing, it might be a good
>>> idea to make them more general so we can annotate other things, such as
>>> "pure function" / "side effect function" or "local send" / "remote
>>> send". I would personally love to easily identify message sends to
>>> remote nodes.
>>>
>>>
>>> These are also interesting things - maybe not inline but perhaps as
>>> keywords on function definitions; we had some ideas about marking
>>> functions as pure (for guards) back in the HiPE project, for example.
>>> Like any kind of strict typing, you then get into the question about
>>> such functions in other modules: If they can only be used locally, the
>>> feature is perhaps too limited to be worth it. To put them in other
>>> modules, you'd probably need to do name mangling like e.g. when linking
>>> C++, to ensure both caller and callee are following the conventions, and
>>> that might get too messy. I don't know anyone who has prototyped that,
>>> though, so it's not clear how it would look and feel.
>>
>> Considering the small number of already bound variables used in a match,
>> it might be more appropriate to make this a keyword as well. Or have a
>> longer form, for example "^match Var". Then you can have "^pure
>> function() -> todo.", "^remote Pid ! Msg" and so on. With the annotation
>> being added as metadata and usable by the compiler, parse transforms or
>> other tools (allowing custom annotations the compiler doesn't otherwise
>> understand).
>>
>> Other options could be "match^Var", "pure^function()" "remote^Pid !
>> ...", or "match::Var", ":match: Var"...
>>
>> The added advantage is that you're explicitly writing that this is a
>> match rather than relying on people's understanding of what ^ means.
>
> That is an interesting idea.
>
> {ok, ^Var} = foo(),
> {ok, match^Var} = foo(),
>
> More verbose, but not terribly. Still next to the variable. and no
> intermediate variable is needed. Maybe even clearer.
> Opens up for other annotations.
>
> Then ^ would be the annotation binary operator.
This is way more clear. And also makes it something new users could
*search* for.
As for pure functions VS side effecty functions... My idea on that is to
make them typespec annotations that Dialyzer can check:
-spec side_effecty_fun() -> ok.
-pure pure_fun(integer()) -> {ok, float()}.
or similar.
Note that allowing Dialyzer to actually handle this would require
adjusting every pure function in the standard library. Not a hard task,
but certainly a large one.
As for remote VS local send... need to think about that one a bit.
While the above would resolve some of my arguments against the "pinning"
issue, I can't shake the feeling that the real solution would be to move
forward with the direction we *already* have moved in Erlang (as regards
shadowing, specifically): Eliminate shadowing entirely and make the only
thing possible a match.
One Scope To Rule Them All is much more Erlangish than needing to add an
annotation and we already have a warning about shadowing as it is nearly
always an accident. We don't require an annotation for a match/assertion
anywhere else in the body of a function, so why only in a lambda *head*
only or an iterative assignment in a list comprehension?
Since we already have a warning, I believe it would be cleaner to enable
a compiler mode that removes shadowing and eventually make that the
default (and leave open the option to use a compiler mode that still
only warns).
Principles matter, and while I could groan and go along with a new
concept of variable annotations, I believe this will eventually take us
down a stupid road and warn against it. Any new thing will get abused by
people hypnotized by the Good Idea Fairy. Language design is hard. All
additions to a language increase its complexity. New users who find
Prolog syntax a bit icky will *definitely* find putting what looks like
the pow operator between a keyword that by the language's core
definition should be redundant and a variable name ultra icky (if
anything `shadow^VarName` should be the special case rather than
`match^VarName`).
Anyway, interesting idea. Much more interesting than "let's just throw
an unused ASCII char at it!"
-Craig
More information about the erlang-questions
mailing list