[erlang-questions] array search problem

Richard A. O'Keefe ok@REDACTED
Mon Feb 2 01:40:36 CET 2015

On 31/01/2015, at 5:36 am, Roelof Wobben <r.wobben@REDACTED> wrote:

> Hello,
> Im still struggeling to make the database exercise working.
> I have to implement a read method which outputs as this :
> 5> db:read(francesco, Db2).
> {ok,london}
> 6>  Db3 = db:write(joern, stockholm, Db2).
> [{joern,stockholm},{lelle,stockholm},{francesco,london}]
> 7>  db:read(ola, Db3).
> {error,instance}
> To achieve this do I need to use a try catch or can  I achieve this with only pattern matching.

What on earth would you use a try-catch *for*?

Your so-called "data base" is a thing that has been known as an
"association list" at least since the "Lisp 1.5 programmer's manual"
came out in 1962.

Think about a CASE ANALYSIS.

read(Key, Association_List)

There is no useful case analysis to do on Key.  It could be anything.
Association_List could be empty or it could be non-empty.  So

read(Key, [Head|Tail]) ->
    ?What goes here?;

read(Key, []) ->
    ?What goes here?.

Let's take the empty case first.
Example 7> shows that the result should be {error,instance}.
I am a little surprised that the error term does not include
the Key being sought.  Since we're not going to use the Key
in that case, I'll tell the compiler that we *mean* not to use
it by prefixing "_".

read(_, []) ->

Now let's take the non-empty case.  If we know that the
association list is not empty, do we know enough yet to decide
what to do?  No, we don't.

There are going to be two sub-cases.
- We have found what we are looking for.
- We haven't.

Do we know enough to handle example 5> ?
No: we need to know that Head is a pair with Key as its first
element.  Some functional languages have what's called
"linear" patterns, where the head of a function may mention
a variable at most once, so that in Haskell we would have to

read key ((k,v):alist) | k == key = ...
                       ^^^^^^^^^^  the guard.

Erlang doesn't have that restriction.  So we can do

read(Key, [{Key,Value}|_]) ->
    % non-empty case, subcase 'found'
    ?what goes here?;
read(Key, [_|Association_List]) ->
    % non-empty case, subcase 'not found'
    ?what goes here?;
read(_Key, []) ->

Now the 'found' subcase will have to return {ok,Value},
and the 'not found' subcase will have to keep on looking.
I'm sure you can figure those out for yourself.

You might actually find the book "The Little Schemer" of use.
The syntax of Scheme is very different from Erlang, and it
doesn't use pattern matching, but the data structures are
quite similar, in particular the lists.  The book is all
about teaching recursive programming, mostly using lists.
From Douglas Crockford's review

	Despite its flaws, the book has a very loyal
	following and that is because it works.
	It teaches one thing, a thing that is very
	difficult to teach, a thing that every
	professional programmer should know, and it
	does it really well.  These are lessons that
	stick with you.  You need to grab a sandwich
	and study this book.

What is the secret of functional programming?
It is case analysis, case analysis, case analysis!

	Cui comparatus indecens erit pavo,
	Inamabilis sciurus, et frequens Phoenix.
	--- Martial., l. 5. Epig. 38.

Compared with try-catch, a phoenix should be too frequent.

More information about the erlang-questions mailing list