I need a function with some kind of a step-by-step logic and I wonder how I can make one. Let\'s take a log in process on a site as an example, so I need the following logic
What you're looking for is what I'd call an "early exit". I had the same question when I started with functional programming in F# quite a while ago. The answers I got for that may be instructive:
Multiple Exits From F# Function
This is also a good discussion of the question (although again it's F#):
http://fsharpforfunandprofit.com/posts/recipe-part2/
TL;DR construct your functions as a series of functions each taking and returning a tuple of an atom and the password string to check. The atom will either be :ok or :error. Like so:
defmodule Password do
defp password_long_enough?({:ok = a, p}) do
if(String.length(p) > 6) do
{:ok, p}
else
{:error,p}
end
end
defp starts_with_letter?({:ok = a, p}) do
if(String.printable?(String.first(p))) do
{:ok, p}
else
{:error,p}
end
end
def password_valid?(p) do
{:ok, _} = password_long_enough?({:ok,p}) |> starts_with_letter?
end
end
And you would use it like so:
iex(7)> Password.password_valid?("ties")
** (FunctionClauseError) no function clause matching in Password.starts_with_letter?/1
so_test.exs:11: Password.starts_with_letter?({:error, "ties"})
so_test.exs:21: Password.password_valid?/1
iex(7)> Password.password_valid?("tiesandsixletters")
{:ok, "tiesandsixletters"}
iex(8)> Password.password_valid?("\x{0000}abcdefg")
** (MatchError) no match of right hand side value: {:error, <<0, 97, 98, 99, 100, 101, 102, 103>>}
so_test.exs:21: Password.password_valid?/1
iex(8)>
Of course, you'll want to construct your own password tests but the general principle should still apply.
EDIT: Zohaib Rauf did a very extensive blog post on just this idea. Well worth reading as well.