DEV Community

Discussion on: Write Better Code With [Functional Programming & Elixir]

 
elixirprogrammer profile image
Anthony Gonzalez

Nice one! Hard to believe that's Java. I agree, you can get sloppy with any language, even with Elixir, check this example:

def handle_event("upvote", %{"p_id" => post_id, "u_id" => user_id}, socket) do
    if user_id == "false" do
      {:noreply, redirect(socket, to: Routes.pow_session_path(socket, :new), replace: true)}
    else
      user = Repo.get!(User, user_id)
      post = Community.get_post!(post_id)
      vote = %Vote{}

      case current_user_voted?(user_id, post_id) do
        "" ->
          case Votes.create_vote(user, post, vote) do
            {:ok, _vote} ->
              User.karma_update(user_id, 1)
              post = Community.get_post!(post_id)
              if post.votes_count == -1 do
                Community.votes_count_update(post_id, 2)
              else
                Community.votes_count_update(post_id, 1)
              end
              post = Community.get_post!(post_id)
              socket =
                assign(socket,
                p_votes_count: post.votes_count,
                active?: "active",
                p_id: post_id,
                u_id: user_id)

              {:noreply, socket}
            {:error, %Ecto.Changeset{} = changeset} ->
              socket = assign(socket, changeset: changeset)
              {:noreply, socket}
          end
        "active" ->
            Votes.delete_vote(Votes.find_vote(user_id, post_id))
            User.karma_update(user_id, -1)
            Community.votes_count_update(post_id, -1)
            post = Community.get_post!(post_id)
            socket =
            assign(socket,
            p_votes_count: post.votes_count,
            active?: "",
            p_id: post_id,
            u_id: user_id)
          {:noreply, socket}
        nil ->
          vote = Votes.find_vote(user_id, post_id)
          case Votes.update_vote(vote, %{downvote: false}) do
            {:ok, _vote} ->
              User.karma_update(user_id, 1)
              post = Community.get_post!(post_id)
              if post.votes_count == -1 do
                Community.votes_count_update(post_id, 2)
              else
                Community.votes_count_update(post_id, 1)
              end
              post = Community.get_post!(post_id)
              socket =
              assign(socket,
              p_votes_count: post.votes_count,
              active?: "active",
              active_dislike?: "",
              p_id: post_id,
              u_id: user_id)

              {:noreply, socket}

            {:error, %Ecto.Changeset{} = changeset} ->
              socket = assign(socket, changeset: changeset)
              {:noreply, socket}
        end
      end
    end
  end

defp current_user_voted?(user_id, post_id) do
    if user_id == false or user_id == "false" do
      ""
    else
      voted? = Votes.find_vote(user_id, post_id)
      if voted? == nil do
        ""
      else
        if voted?.downvote == true do
          nil
        else
          "active"
        end
      end
    end
end
Enter fullscreen mode Exit fullscreen mode
Thread Thread
 
aminmansuri profile image
hidden_dude • Edited

Yeah that needs refactoring.

Also overuse of if/else and case is not helped with FP popular error handling these days.

A nice thing about exceptions is that you can essentially ignore errors in most places rather than having and if/else everywhere or an error handler everywhere.

That style seems to be devolving into old styles where error handling is mixed in with the happy path making the code harder to read.

Classic OO (Smalltalk) and classic FP (if you consider Common Lisp FP) didn't even really have "if statements" or "case statements".

These were handled in the libraries.

I think modern OO languages biggest flaw is there over reliance on statements and keywords that make them much less extendable than Smalltalk or Lisp where you could literally change everything by extending the libraries.

Really no "modern" OO language really has that flexibility and clean design. Not Java, not C++, not C#, not Ruby, not Python, not JavaScript.