[erlang-questions] Tried this... Thought it interesting... But it didn't work.
Wed Sep 2 22:21:18 CEST 2015
When are you going to write your Erlang book? You have much to teach and I, for one, much appreciate it.
All the best,
From: "Jesper Louis Andersen" <jesper.louis.andersen@REDACTED>
Sent: Wednesday, September 2, 2015 9:23am
To: "Lloyd R. Prentice" <lloyd@REDACTED>
Cc: "zxq9" <zxq9@REDACTED>, "Erlang (E-mail)" <erlang-questions@REDACTED>
Subject: Re: [erlang-questions] Tried this... Thought it interesting... But it didn't work.
On Wed, Sep 2, 2015 at 4:24 AM, Lloyd R. Prentice <lloyd@REDACTED>
> Your code exhibits a depth of understanding and subtlety that I can only
> hope to aspire to.
> Can you help me understand the ?LET(... and ?SUCHTHAT(... expressions?
I agree with Fernando, that it is often nicer to pull these things into a
function on its own, and use that function as in:
f(X) -> [1,2] ++ e(X).
e(X) when X < 5 -> ;
e(X) -> [X].
In the QuickCheck models however, you would often end up writing many of
such one-off functions, so this is why I sometimes tend to use the [X ||
As for ?LET(...) and ?SUCHTHAT(...): They are macros which are used in
QuickCheck like tools (Erlang QuickCheck, Proper, Triq, ...). If you have a
generator like choose/2 which generates numbers between two endpoints:
Some times, however, you don't want a raw generator. You want to do
something to the result before you use it. The problem however is that the
generator generates. So your code would have to:
1. draw a specimen from the generator.
2. apply some function to the drawn specimen
3. return the result of the application, but do so as a new generator doing
This is what ?LET(...) does. Writing
I * 7).
would return a new generator, which draws a number between 1 and 10, and
returns 7 times that number. That is, it returns numbers in the range
The ?SUCHTHAT(..) macro is used as ?SUCHTHAT(S, Gen, Pred(S)). It picks a
specimen from Gen and then tests it against Pred. If Pred(S) returns true,
it returns that value. If Pred(S) returns false, it tries generating a new
value satisfying the predicate. I.e., generate S from Gen such that P(S) is
true. ?SUCHTHAT(..) itself is a generator, doing this internally.
You use the ?SUCHTHAT(..) macro to reject certain values which are not
desirable. In the case of trying to remove an element from a map, you want
to generate an element that is not present in the map in some cases. This
is to verify such removal has no effect on the map. So I use a
?SUCHTHAT(...) to make sure the generated target is not already present in
the map. I expect to be able to find such a value in relatively few tries.
Even considering very large maps with thousands of elements, you can easily
generate a new element randomly, which isn't in there.
 ?LET(..) is a monadic bind over the quickcheck monad.
 The caveat of ?SUCHTHAT is that you want it to generate a valid value
fairly quickly. If you are drawing random hay from a haystack to find a
needle, and the haystack is large, then it is a bad idea. You have a random
search problem at hand then.
More information about the erlang-questions