Parse Transform Question

Pete Kazmier <>
Wed Mar 8 22:24:12 CET 2006


Can I use a parse transform to take code that looks like this:

    test() ->
        cond
            predicate1() -> do1();
            predicate2() -> do2();
            predicate3() -> do3()
        end.
    
And transform it to this:

    test() ->
        case predicate1() of
            true  -> 
                do1();
            false -> 
                case predicate2() of
                    true  ->
                        do2();
                    false ->
                        case predicate3() of
                            true  ->
                                do3();
                            false ->
                                false
                        end
                end
        end.
    
While writing some code today, I ended up with something that looks
like this:

    test() ->
        if
            predicate1() -> do1();
            predicate2() -> do2();
            predicate3() -> do3()
        end.

I then discovered that one can only use valid guard expressions within
an 'if'.  Converting the above to a bunch of nested 'case' statements
was not very appealing to me as it looks ugly.  Could I use a parse
transform to give me the syntax that I am seeking?

What I have ended doing for the moment is:

    cond([]) -> false;
    cond([{Predicate, Func} | Rest]) ->
        case Predicate() of
            true  -> Func();
            false -> cond(Rest)
        end.

So I end up with:

    test() ->
        cond([{fun predicate1/0, fun do1/0},
              {fun predicate2/0, fun do2/0},
              {fun predicate3/0, fun do3/0}]).

Of course I am simplifying my code greatly.  My original code fragment
that started this whole quest is the following (which doesn't work):

process_directory(Base, [], Ancestors)          -> [];
process_directory(Base, [File|Rest], Ancestors) ->
    Path = filename:join(Base, File),
    if
        filelib:is_file(Path) andalso lists:suffix(".txt", File) ->
            Story = read_story(Path, lists:reverse(Ancestors)),
            [Story|process_directory(Base, Rest, Ancestors)];
        
        filelib:is_dir(Path) ->
            {ok, Contents} = file:list_dir(Path),
            lists:append(process_directory(Base, Rest, Ancestors),
                         process_directory(Base, Contents, [File|Ancestors]));
        true ->
            process_directory(Base, Rest, Ancestors)
    end.


Thanks,
Pete



More information about the erlang-questions mailing list