A Pythonista's Impressions of Erlang

Joe Armstrong (AL/EAB) joe.armstrong@REDACTED
Wed Jan 12 14:51:01 CET 2005

> -----Original Message-----
> From: owner-erlang-questions@REDACTED
> [mailto:owner-erlang-questions@REDACTED]
> Sent: den 12 januari 2005 12:06
> Cc: erlang-questions@REDACTED
> Subject: Re: A Pythonista's Impressions of Erlang
> Speaking of string operations, I need to add (or remove) the 
> /  at the 
> end of an URL if it is absent (or present).
> I only ended in writing ugly code like that:
> RootUrl=
> if
>         list:last(SiteRoot) =/= $/ ->
>                 SiteRoot ++ [$/];
>         true ->
>                 SiteRoot
> end
> Is there an elegant way to do last character manipulation?


   Actually you're code will crash if SiteRoot is empty - since an empty list
has no last element. 

  Now you might think that since 

	"string" ++ Var 

 Is a legal pattern that you could write your function like this:

	add_slash(X = _ ++ "/") -> X;
	add_slash(X)            -> X ++ "/".

 But you would be wrong.
 To do it this way involves a quick hack to the compiler
of a rather simple parse_transform to change the semantics of
the compiler.

 Actually I see no reason why patterns like Var ++ StringLiteral should not
be compiled, especially since StringLiteral ++ Var *is* allowed - and therefore
disallowing Var ++ StringLiteral violates the principle of least astonishment.

 Failing that you'll have to hide the code in a function. Something like this

	aardvark([])  -> "/";
	aardvark(Str) ->
		case lists:last(Str) of
		  $/ -> Str;
	        _  -> Str ++ "/"

  This function is very difficult to name (append_a_slash_at_the_end_of_string_if_there_isnt_one)
isn't a good name, so I've called it aardvark until somebody comes up with a better name

  Now there might be a better way. Suppose the resultant string is
just going to be output somewhere.

  Then instead of doing Str ++ "/" (which is an expensive operation)
you just build a deep list [Str,"/"] (which is a cheap operation) 
and send this to your I/O routines which happily flatten the data as it is output.

  Note this programming style is very common -

  I write loads of stuff like:

  mkList(L) -> ["<ul>", 
		     map(fun({I,J}) ->
			     ["<li>", mk_href(I,J) "</li>"]

  mkHref(I, J) -> ["<a href='">,I,"'>",J,"</a>"].

  happy in the knowledge that these things will eventually get flattened on output.

  If you absolutely need a flat version of L just call sneaky_flatten(L)


	sneaky_flatten(L) -> binary_to_list(list_to_binary(L)).




More information about the erlang-questions mailing list