[erlang-questions] syntax errror on :

Joe Armstrong erlang@REDACTED
Sat Aug 8 17:39:39 CEST 2015


On Sat, Aug 8, 2015 at 1:03 PM, Roelof Wobben <r.wobben@REDACTED> wrote:
> Hello,
>
> I try to find a solution for this etude :
> http://chimera.labs.oreilly.com/books/1234000000726/ch05.html#CH05-ET01
>
> So far I have this :
>
> %% @author Roelof Wobben <r.wobben@REDACTED>
> %% @doc Function to calculate the area of a rectangle
> %% @reference from <a href=
> "http://shop.oreilly.com/product/0636920025818.do" >Introducing Erlang</a>,
> %% O'Reilly Media, Inc., 2012.
> %% @copyright 2012 by R.WObben
> %% @version 0.1
>
> -module(geom51).
>
> -export([area/0]).
>
> %% @doc ask the user for which shape the area
> %% must be calculated.
> %% Choices are :
> %% c or a C for a circle
> %% e or a E for a ellipse
> %% t or a T for a triangle
>
> -spec(area() -> char() ).
>
> area() ->
>     io:format("Which shape must the area be calculated?~n"),
>     io:format(" R. Rectangle ~n"),
>     io:format(" T. Triangle~n"),
>     io:format(" E. Ellipse~n"),
>     Answer = io:get_line("Your choice?  "),
>
>     Value = hd(Answer),
>     char_to_shape(Value).
>
> %% @doc convert the choice to a Shape and send the
> %5 data to the dimension function
> %% when the choice is a  :
> %% r or a R then the shape will be a rectangle
> %% t or a T then the shape will be a triangle
> %% e or a E then the shape will be a ellipse
>
> -spec(char_to_shape(char() ) -> atom() ).
>
> char_to_shape(Char) ->
>     case Char of
>         $R -> get_dimension(rectangle);
>         $T -> triangle;
>         $E -> ellipse;
>         $r -> rectangle;
>         $t -> triangle;
>         $e -> ellipse;
>         _Else -> "Wrong Shape"
>     end.

Just a quick comment on this function:

char_to_shape can return a string (ie "Wrong Shape") and NOT a shape (atom)
so you violate your own spec.

A better solution is to omit the final clause and write

char_to_shape(Char) ->
    case Char of
        $R -> get_dimension(rectangle);
        $T -> triangle;
        $E -> ellipse;
        $r -> rectangle;
        $t -> triangle;
        $e -> ellipse
  end.

Now the function will generate an exception if called with an incorrect
argument. Returning a string is just about the worse thing you could do
since some other function somewhere else will have to deal with this.

This is an example of the "let it crash" philosophy. Crashing is no big deal in
Erlang - in single threaded languages crashing is a big deal - if you crash
you lose *everything*. In Erlang you can have millions of processes,
if a few crash who cares? In Erlang we let processes watch each other,
if one process
crashes some other process is supposed to observe this and try to fix the error.

In Erlang we assume we'll never get things right and that programs will crash
so we don't really bother to program defensively - but we do make sure
errors are detected and logged and faulty computations restarted.

This leads to a very clean and simple programming style since you don't
have to add the additional clauses to catch errors - just leave them out.
This make life easy for the programmer since it's in writing these extra
clause the programmer is "out of spec" ie what should I do in the error case.
Return a string? (as you did) print a message - but who will deal with the
string, who will read the message?

The refactored code is actually easier to read and write since there is no
nasty edge case.

So there you are - two new principles:

    "Let it crash"
    "Let some other process fix the error"

Cheers

/Joe


>
> -spec(get_dimension( atom() ) -> number() ) .
>
> %% @doc Calculates the area of a shape, given the
> %% shape and two of the dimensions. Returns the product
> %% of its arguments for a rectangle, one half the
> %% product of the arguments for a triangle, and
> %% math:pi times the product of the arguments for
> %% an ellipse.
>
> get_dimension(Shape)->
>     case Shape of
>         rectangle ->
>             Answer1 = io:get_line("What is the length of the rectangle?  "),
>             {Test, _} = string:to_float(Answer1),
>                      case Test of
>                          error -> Test2 = string:to_integer(Answer1),
>                          case  Test2 of
>                              error -> io:write("the input schould be a
> number");
>                              _Else -> Test2 = Test
>                          end
>                      end
>     end
>
>
> but now I see these error message :
>
> geom51.erl:72: syntax error before:
> geom51.erl:42: function get_dimension/1 undefined
> geom51.erl:51: spec for undefined function geom51:get_dimension/1
>
> geom51.erl:72: syntax error before:
> geom51.erl:42: function get_dimension/1 undefined
> geom51.erl:51: spec for undefined function geom51:get_dimension/1
>
> anyone who knows how to solve this one ?
>
> Roelof
>
>
>
>
>
>
>
>
>
> ---
> Dit e-mailbericht is gecontroleerd op virussen met Avast antivirussoftware.
> https://www.avast.com/antivirus
>
> _______________________________________________
> erlang-questions mailing list
> erlang-questions@REDACTED
> http://erlang.org/mailman/listinfo/erlang-questions



More information about the erlang-questions mailing list