[erlang-questions] Guards syntax for multiple values
Wed Mar 27 08:52:05 CET 2019
On 2019年3月26日火曜日 15時51分08秒 JST Florent Gallaire wrote:
> > As José pointed out, all guard BIFs are currently in the Erlang
> > module. So most likely there would be a new guard BIF in the erlang
> > module called is_member/2 or lists_member/2.
> Why do you clearly prefer is_member/2 or lists_member/2 to 'Var in
> <list literal>' ?
> It's also a good opportunity to make Erlang more modern with a sexy
> syntactic sugar...
That's what other disaster zones are for.
Functions are nearly always better than new syntax.
This particular case doesn't even rate discussion.
How much once-cool-but-now-unused syntax is there in C++, Haskell, Ruby, etc?
There are languages I've used for more than a decade in which I occasionally stumble upon a line I can't begin to comprehend because the syntax exhibits a never-used-but-legal construct and I have no idea what to call the thing I'm seeing so I am left powerless to even do a search to figure it out. "Oh! That's a 'left-fish'! Well, had I only known how to search for it... since it couldn't be simply named as a function..."
Erlang doesn't need new syntax for this, you need more familiarity with Erlang and to research our long and glorious history of discussing the merits of new syntax, pure function declarations, allowing more permissible functions in guards, set operators (instead of set functions/operations), etc. Quite a lot of that history is right here in the mailing list archives.
Any complex operation in a function head makes the burden of comprehending function heads more complex and has the potential to make the match itself expensive. You shouldn't want either to be true (consider the well-known case of paralyzed performance through the use of length/1 in a set of function head guards). If you want to do complex comparison operations (such as checking membership) do it in the body of a function itself. The closest you'll get to this in matching is with map keys, and there are constraints on that case for good reasons already.
Why would we go to the trouble to special-case some syntax for membership check which can only accept a literal at compile time (and how do you fit *that* in there if the list of things to check is very large?) when the obvious solution is what everyone already does (checking inside the function itself)? This case isn't even very common over literal values outside of parsers and encoders/decoders. I've written a LOT of encoders and decoders, and while extended guards leave a bit to be desired in terms of initial typing and there could be some utilty to making it easy to define a set of most-used guards (oh wait, you can write them once and wrap that up in a function, nevermind...) WRITING the code is never as important as being able to READ it later -- and a drop-down set of guards is pretty darn easy to comprehend, even in a gigantic set of function clauses like often encountered in encoders specifically because they are boring, explicit, and not hidden by any magical syntax.
Case in point:
Code like this happen a lot in decoders and parsers and pretty much nowhere else, and once written tend not to change much except for DEBUGGING if there turns out to be a problem with it. Infrequently updated forms of code is the WORST candidate for new syntax inclusion.
Note, I am NOT addressing there general case of membership checks, I am specifically addressing the case where the membership comparison set is statically defined and known at compile time becuase that's the only case that is even remotely reasonable to consider here. The case where the comparison is against dynamic values on either side is already handled by existing list, set, map, etc. functions. Note, there are SEVERAL ways to compare for membership because there are SEVERAL types of collections. Why are we special casing lists? Should we also have a magic syntax just in case something exists in a set? What about the now-unloved dicts? gb-trees?
More information about the erlang-questions