Kan ik mijn eigen bewakers in Erlang maken?

Ik kwam deze code op internet tegen:

is_char(Ch) ->         
    if Ch < 0 -> false;  
       Ch > 255 -> false;
       true -> true      
    end.

is_string(Str) ->            
    case is_list(Str) of           
    false -> false;           
    true -> lists:all(is_char, Str)
    end.

Het is de Guard I alwais gedroomd, in die zin dat het controleert of een input een string is - hoe dan ook, ik mag het niet gebruiken in erlang, waarom is dit? En is er een werk rond?

Ik zou graag dingen kunnen schrijven als:

Fun(Str) when is_string(Str) -> Str;
Fun(Int) when is_integer(Int) -> io:format("~w", [Int]).

of zelfs beter gebruiken op berichten.

7
ja ru de
Geen overtreding, maar een betere manier om te testen op tekenreeksen zijn de methoden: io_lib: printable_list/1 en io_lib: printable_unicode_list/1 gebruikt in combinatie.
toegevoegd de auteur Muzaaya Joshua, de bron
Zie ook this , this , deze , this en this question.
toegevoegd de auteur legoscia, de bron

2 antwoord

Het is niet toegestaan ​​om door de gebruiker gedefinieerde functies in de bewakers te gebruiken. Het is omdat de functies in de bewakers vrij moeten zijn van bijwerkingen (zoals het gebruik van io: format in uw functies). In bewakers beperkt u zich tot het volgende:

  • BIFs used for type tests (is_atom, is_constant, is_float, is_integer, is_list, is_number, is_pid, is_port, is_reference, is_tuple, is_binary, is_function, is_record),
  • boolean operators (not, and, or, andalso, orelse, ,, ;),
  • relational operators (>, >=, <, =<, =:=, ==, =/=, /=),
  • arithmetic operators (+, -, *, div, rem),
  • bitwise operators (band, bor, bxor, bnot, bsl, bsr),
  • other BIFs that are free of side effects (abs/1, element/2, hd/1, length/1, node/1,2, round/1, size/1, tl/1, trunc/1, self/0)
9
toegevoegd
@MartinKristiansen Niet echt, omdat elke code in modules tijdens runtime kan worden gewijzigd of vervangen.
toegevoegd de auteur Alexey Romanov, de bron
@MartinKristiansen Dat zou "alleen BIF's en die functies binnen de huidige module moeten zijn die alleen BIF's en functies binnen de huidige module aanroepen en niet recursief zijn (om te verzekeren dat ze eindigen)". Wat betekent dat je is_string niet als bewaker kunt gebruiken :)
toegevoegd de auteur Alexey Romanov, de bron
Hmm, het lijkt erop dat het controleren van bijwerkingen een vrij eenvoudige statisch-anale truc zou zijn ...
toegevoegd de auteur Martin Kristiansen, de bron
@alexeyRomanov: Je hebt absoluut gelijk - maar misschien maak je dan een beperking om BIF's en enige functies binnen de huidige module te gebruiken :-)
toegevoegd de auteur Martin Kristiansen, de bron
@MartinKristiansen ... of functies die speciale constructies gebruiken, zoals ontvangen die altijd een neveneffect hebben.
toegevoegd de auteur Magnus Kronqvist, de bron

Een andere reden voor het niet toestaan ​​van door de gebruiker gedefinieerde functies in bewakers is dat fouten anders worden behandeld in bewakers dan in "normale" functies. In een bewaking genereert een fout niet een uitzondering, maar alleen de bewaker zelf faalt.

Bewakers zijn niet echt uitdrukkingen maar tests .

5
toegevoegd