Skip to content

Questions about design of some parts #12

@OvermindDL1

Description

@OvermindDL1

A couple questions on design decisions or perhaps requesting new helper functions.


First, why does safe return a fun instead of branching at the point of call to be used as normal. Right now at https://github.com/expede/exceptional/blob/master/lib/exceptional/safe.ex#L86 it is doing a large branching and an apply call for every call. If instead if it (or a new name) were made a macro, then it could be fully inlined instead as a calling site, so you could do this for the examples in the README.md instead:

[1,2,3] |> safe(Enum.fetch!(1))
#=> 2

[1,2,3] |> safe(Enum.fetch!(999))
#=> %Enum.OutOfBoundsError{message: "out of bounds error"}

safe(Enum.fetch!([1,2,3], 999))
#=> %Enum.OutOfBoundsError{message: "out of bounds error"}

This could help readability and especially the usage while piping. Easily implementable as well.


Second, if_exception and such have a similar setup, they take functions, where if they were macro's then the if_exception last example could become:

ArgumentError.exception("error message")
|> if_exception do
  %{message: msg} -> msg
else
  value # if the default variable name was value, could always make it configurable
end
#=> "error message"

Also easily implementable, just stuff the do body in a case statement (maybe with a default to continue passing unmatched exceptions) and the else as normal. Could even optimize it so if the do body macro list has only one element and it is not keyed on a :-> then it could be a simple pass-through, so these would both work:

ArgumentError.exception("error message")
|> if_exception do
  %{message: msg} -> msg
else
  value
end
#=> "error message"

# Or this, if the passed in variable was named something like 'exc', could give an option to rename it too if you want:
ArgumentError.exception("error message")
|> if_exception do
  handle_error(exc)
else
  value
end
#=> "error message"

Or a configurable variable name could be used like:

ArgumentError.exception("error message")
|> if_exception myvar, do
  %{message: msg} -> msg
else
  myvar
end
#=> "error message"

# Or this, if the passed in variable was named something like 'exc', could give an option to rename it too if you want:
ArgumentError.exception("error message")
|> if_exception myvar, do
  handle_error(myvar)
else
  myvar
end
#=> "error message"

And of course the else clause could be optional if it is just a pass-through anyway.


And so forth on the other parts, just to help reduce the typing required and increasing readability by removing all sorts of things like .() from many calls.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions