First class patterns in Erlang? (Alternatives) - erlang

Is there a way to create first-class-like patterns in Erlang? I need to be able to create and pass patterns as args to other functions but I know patterns are not first class in Erlang. I also looked at Elixir but it doesn't seem to offer anything more as far as patterns go.
I was wondering if anyone has come up with a simple solution to this problem. I was thinking of trying to implement something like this:
% Instead of using variables, we would just use uppercase atoms which would serve as vars
% A passable pattern
Pattern = {ok, 'Result'}.
% Custom function to check for matches
match(pattern, {ok, [1,2,3]}). % => true
I am new to Erlang so perhaps this is completely unnecessary. Perhaps there is a library that does this sort of thing?
Any advice is greatly appreciated. Thanks in advance!

I don't know if something exists already that does what you want, but you can easily implement it like this:
-module (match).
-compile([export_all]).
-define(MF(S), fun(S) -> true; (_)->false end).
match(F,V) -> F(V).
test() ->
Pattern = ?MF({ok,_}),
false = match(Pattern,{error,reason}),
true = match(Pattern,{ok,[1,2,3]}).

You might want to look at Erlang match specifications, which I believe are the sorts of patterns you're asking about. They're used for matching values in Erlang's tables and databases as well as in Erlang tracing. You might find some inspiration there.

I'm not sure I see your entire problem but it seems that a predicate function would suite you well. It's pretty common way to parameterize generic functions with them in a functional language. Take a look at lists functions such as map, foldl, filter.

I ended up using Elixir's macro functionality to implement something similar to Erlang's match specs. The code looks much cleaner(since I am simply defining functions with patterns) and they work very similar to Erlang's match specs.

Related

Abusing pattern matching

I come from C# and find myself in love with the F# pattern matching syntax as it's simpler than C# switch and way more useful. I like to use it as much as possible, is there a performance or any other downside to using it in weird ways like in this example?
match 0 with
|_ when a<b -> a
|_ -> b
In this particular example, there will be no performance penalty. It is very likely that performance penalty will also be absent in other cases, but to be absolutely sure you'll have to look at the generated code with something like ILSpy.
I must also add that as you use F#, you'll find that if/then/else is also very nice. In C#, if/else feels kinda awkward, because it can't be used as expression, but in F# it is not the case, and so the awkwardness soon disappears.
let x = if a < b then a else b
It even reads like plain English! :-)

Does Erlang have methods?

E.g. is there something like this:
O = widget:new(),
O:whirl()
I seem to recall seeing some code like this (maybe I was imagining it), but I haven't seen it in the tutorials that I've read. From what I've seen, the closest thing is this:
O = widget:new(),
widget:whirl(O)
That's not too bad, but not having to repeat widget: in the second expression would be nice.
This is syntax for parametrized modules which was removed from Erlang in R16 (2012).
No, Erlang does not have methods. Erlang has processes, not objects, and you communicate with them by messaging them, not calling methods on them. That's it. That's all there is to it.
The closest thing to new in Erlang that means what it means in Java or C++ is spawn. (The parameterized module discussion touches on something very different from what you would expect coming from a C++ type language where new reserves memory, calls a constructor, etc.)
There are actually two aspects to this: data objects (like a dict or list or something) and processes (things you create with spawn).
Within a function definition you might see something like
SomeDict = dict:new(),
or
OtherDict = dict:from_list(KV_List)
This does indeed create something, but its not an "object" in the Java or C++ sense, it is an "object" in the (older) sense of the term that it is a named reference to something in memory. And indeed you interact with it the same way you demonstrated above:
D = dict:new(),
ok = some_operation(D),
where some_operation/1 might be anything, whether it is dict:foo() or something else. The part before the colon is a module identifier, telling the runtime what namespace that function you're calling exists in -- nothing more.
The other thing, spawn, is much more like new in C++, where you want to create a complete thing that is alive and has arms and legs -- a noun that can do verby things:
Pid = spawn(Mod, Fun, Args),
Pid ! {some, message},
Most of the time you only see the erlang:send/2 function (also written as the infix ! operator) in prototype or non-OTP code. Usually this is hidden from you by interface functions that abstract away the fact that you are sending async messages all the time to communicate with your processes.
For some more in-depth explanation, I recommend reading Learn You Some Erlang -- the author explains this and other basic concepts in some depth.
Whatever you do, do not fall into the simpleton's trap of thinking Erlang is Java. That is just a great way to trip over your own preconceptions and get frustrated. This is probably the #1 beginner mistake I see people make...

How should i define something constantlike in Erlang

I have a module which does some non constrained minimization. I'd like to keep its' interface as simple as possible, so the best choice would be to reduce it to a single function something like: min_of( F ).
But as soon as it is brutal computation, i would have to deal with at least two constants: precision of minimization algorithm and maximum number of iterations, so it would not hang itself if target function doesn't have local minimum at all.
Anyways, the next best choice is: min_of( F, Iterations, Eps ). It's ok, but I don't like it. I would like to still have another min_of( F ) defined something like this:
min_of( F ) ->
min_of( F, 10000, 0.0001).
But without magic numbers.
I'm new to Erlang, so I don't know how to deal with this properly. Should i define a macros, a variable or maybe a function returning a constant? Or even something else? I found Erlang quite expressive, so this question seems to be more of a good practice, than technical question.
You can define macros like this
-define(ITERATIONS, 10000).
-define(EPS, 0.0001).
and then use them as
min_of(F, ?ITERATIONS, ?EPS).
You can use macros but you can also use in-lined functions.
-compile({inline, [iterations/0, eps/0]}).
iterations() -> 10000.
eps() -> 0.0001.
and then use it in the way
min_of(F) ->
min_of(F, iterations(), eps()).
The benefit is you can use all syntax tools without need of epp. In this case also calling of function is not performance critical so you can even go without inline directive.

How to trace for all functions in an Erlang module except for one?

I wanted to trace for all functions in an erlang module, with dbg:tpl, but one of the internal functions took up 95% of the trace file. I then wanted to exclude only that single function and found that it was not as easy as I thought it would be.
I know there are great pattern matching possibilities for arguments when tracing.
Is there a similar possibility to apply pattern matching for functions?
eg.: {'=/=', '$2', function_name}
I am open for outside-the-box solutions as well!
Thank You!
It can be achieved as one statement with a list comprehension:
[dbg:tpl(Mod, F, []) || {F, _Ar} <- Mod:module_info(functions), not lists:member(F, DontTrace)].
Where Mod is the module you want to trace on, and DontTrace is a list of functions names that should not be traced on.
dbg:tpl(mod,[]).
dbg:ctpl(mod,notthisfunction).
Haven't tested this but shouldn't this do the trick? Don't know of a way to do it in one line.

Backtracking in Erlang

First of all sorry for my English.
I would like to use a backtracking algorithm in Erlang. It would serve as a guessing to solve partially filled sudokus. A 9x9 sudoku is stored as a list of 81 elements, where every element stores the possible number which can go into that cell.
For a 4x4 sudoku my initial solution looks like this:
[[1],[3],[2],[4],[4],[2],[3],[1],[2,3],[4],[1],[2,3],[2,3],[1],[4],[2,3]]
This sudoku has 2 solutions. I have to write out both of them. After that initial solution reached, I need to implement a backtracking algorithm, but I don't know how to make it.
My thought is to write out the fixed elements into a new list called fixedlist which will change the multiple-solution cells to [].
For the above mentioned example the fixedlist looks like this:
[[1],[3],[2],[4],[4],[2],[3],[1],[],[4],[1],[],[],[1],[4],[]]
From here I have a "sample", I look for the lowest length in the solutionlist which is not equal to 1, and I try the first possible number of this cell and I put it to that fixedlist. Here I have an algorithm to update the cells and checks if it is still a solvable sudoku or not. If not, I don't know how to step back one and try a new one.
I know the pseudo code of it and I can use it for imperative languages but not for erlang. (prolog actually implemented backtrack algorithm, but erlang didn't)
Any idea?
Re: My bactracking functions.
These are the general functions which provide a framework for handling back-tracking and logical variables similar to a prolog engine. You must provide the function (predicates) which describe the program logic. If you write them as you would in prolog I can show you how to translate them into erlang. Very briefly you translate something like:
p :- q, r, s.
in prolog into something like
p(Next0) ->
Next1 = fun () -> s(Next0) end,
Next2 = fun () -> r(Next1) end,
q(Next2).
Here I am ignoring all other arguments except the continuations.
I hope this gives some help. As I said if you describe your algorithms I can help you translate them, I have been looking for a good example. You can, of course, just as well do it by yourself but this provides some help.

Resources