[erlang-questions] syntax errror on :

Roelof Wobben r.wobben@REDACTED
Sat Aug 8 18:59:27 CEST 2015


Op 8-8-2015 om 18:24 schreef Joe Armstrong:
> On Sat, Aug 8, 2015 at 5:44 PM, Roelof Wobben <r.wobben@REDACTED> wrote:
>> Op 8-8-2015 om 17:39 schreef Joe Armstrong:
>>
>>> 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
>>
>> Correct but the exercise I stated that let it chrash is not handy when
>> dealing with user input.
>> As I understand the exercise well I have to write error messages on wrong
>> input even as it against the erlang principle let it crash
> You can do both. You could write shape_to_char as I suggested and
> enclose the call
> in a catch or try statement
>
>      case (catch shape_to_char(X)) of
>         {'EXIT', _} ->
>               io:format("invalid input");
>         Shape ->
>               ...
>      end
>
> or
>
>      try shape_to_char(X) of
>          Shape ->
>             ...
>      catch
>          exit:Why ->
>              ...
>      end.
>
> The problem with your code is the name of the function and its type signature.
>
> What you wrote should have been called:
>
> shape_to_char_or_error(X) ->
>       <<your code>> ...
>
> with type:
>
> -spec (shape_to_char_or_error(char()) -> atom() | string()
>
> which mixes error handling with normal behaviour. I think it's better
> to write it with the simpler type signature and then enclose the code in
> a try-catch or catch construct - it's just prettier that way.
>
> Have fun
>
> /Joe
>
>
>
>
>
>>
>> Roelof
>>
>>
>> ---
>> Dit e-mailbericht is gecontroleerd op virussen met Avast antivirussoftware.
>> https://www.avast.com/antivirus
>>

Thanks,

Im at chapter 5 of introducing erlang and the try catch was not 
mentioned/explained.
For testing if the input of the dimensions is a integer or a float can 
that be in one clause or schould I write two.
The input is a string and I need the integer / float to calculate the 
area later. That function I already wrote in a earlier exercise.

Roelof


---
Dit e-mailbericht is gecontroleerd op virussen met Avast antivirussoftware.
https://www.avast.com/antivirus




More information about the erlang-questions mailing list