Re: other annotations
zxq9 <[email protected]>
| Newsgroups | gmane.comp.lang.erlang.general |
|---|---|
| Message-ID | <[email protected]> |
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 <[email protected] >>> <mailto:[email protected]>>: >>> >>> 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