A Pythonista's Impressions of Erlang

Richard A. O'Keefe <>
Tue Jan 18 05:49:00 CET 2005

(Someone) wrote:
	> Speaking of string operations, I need to add (or remove) the 
	> /  at the end of an URL if it is absent (or present).

The real problem with adding a / at the end of a URL is that it's an O(N)
operation rather than an O(1) operation.  That is, it's *not* the "if"
that is the *really* ugly part in
	> RootUrl = if list:last(SiteRoot) =/= $/ -> SiteRoot ++ [$/]
        >            ; true                       -> >                 SiteRoot
	>           end
but the "++".

	> Is there an elegant way to do last character manipulation?

Yes.  Instead of passing SiteRoot around, pass reverse(SiteRoot).

    SlashedToor = case Toor of     % Toor is Root reversed (:-)
                    [$/|_] -> Toor
                  ; _      -> [$/|Toor]

Keep it reversed as long as you are working on the end of it, only reverse
it when you need it.  

	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.
Because Var ++ StringLiteral is _slow_.

Another approach would be to just go ahead and _always_ add the slash,
relying on a clean-up pass at the end.

But the rules for what you can put where in an URL are sufficiently nasty
that you don't want to be worrying about them.  What you really want is a
URL abstract data type, perhaps with a representation like


	Protocol is an atom;
	Host is an atom or {Name,Port} or {Name,Port,User,Pass}
	Path is a list of strings (/x/y => ["x","y"]
	Query is a list of {Key,Value} pairs, possibly empty
	Fragment is a string

where NO escaping rules apply, just use the characters you want.  Then
you'd finally have a

    url:to_string(URL) -> String

function which pasted the pieces together with all the required punctuation
marks and escaping.

Ensuring that the Path ends with an empty string

    url:with_empty_step_at_end({url,R,H,P,_,_}) ->
	{url,R,H, case last(P) of [] -> P; P ++ [[]] end, [], []}.

is not constant time, but it's O(M), where M is the number of slashes
in the path, which is likely to be a lot less than N, the number of
characters in the path.

More information about the erlang-questions mailing list