pure or not pure?
Koroskin Denis
2korden+dmd at gmail.com
Fri Apr 11 12:21:48 PDT 2008
On Thu, 10 Apr 2008 17:26:20 +0400, Steven Schveighoffer
<schveiguy at yahoo.com> wrote:
> "Janice Caron" wrote
>> On 09/04/2008, Steven Schveighoffer wrote:
>>> So how is new char[] a pure function?
>>
>> new is special.
>>
>>> And why can't I 'wrap' new? For
>>> instance, if I have a function:
>>>
>>> int[] createIncreasingSequence(int s, int e, int step){...}
>>>
>>> which creates an array of ints that start at s and end at e,
>>> increasing
>>> by
>>> step each time, why can't I make that pure?
>>
>> I reckon you can, but you got the return type wrong.
>>
>> invariant(int)[] createIncreasingSequence(int s, int e, int
>> step){...}
>> {
>> auto array = new int[(e-s)/step];
>> foreach(ref a;array)
>> {
>> a = e;
>> e += step;
>> }
>> return assumeUnique!(array);
>> }
>
> This doesn't work for what I'm asking. I'll add more detail to the
> example.
> You have two functions f, and g:
>
> pure int f()
> {
> int[] x = new int[5];
> for(int i = 0; i < x.length; i++)
> x[i] = 1 + i;
>
> /* do stuff */
> return result;
> }
>
> pure int g()
> {
> int[] y = new int[15];
> for(int i = 0; i < y.length; y++)
> y[i] = 10 + (i * 3);
>
> /* do stuff */
> return result;
> }
>
> Now, I realize I have very similar code that initializes the int arrays,
> so
> I want to put that into a function that creates and initializes an array
> with the given parameters:
>
> int[] createIncreasingSequence(int length, int start, int step)
> {
> int[] result = new int[length];
> for(int i = 0; i < result.length; i++)
> result[i] = start + (i * step);
> return result;
> }
>
> Now, I think we all agree that createIncreasingSequence is as pure as
> calling new, right? That is, it doesn't affect any global state (except
> for
> allocating heap data) and will return an equivalent array every time the
> same arguments are given. But if I can't declare it as 'pure', then I
> can't
> call it from f and g:
>
> pure int f()
> {
> int[] x = createIncreasingSequence(5, 1, 1);
>
> /* do stuff */
> return result;
> }
>
> pure int g()
> {
> int[] y = createIncreasingSequence(15, 10, 3);
>
> /* do stuff */
> return result;
> }
>
> So should there be a way to define createIncreasingSequence such that I
> can
> call it from a pure function? Or do I have to re-implement it in every
> pure
> function I use?
>
There is a way with inew (invariant new):
class IncreasingSequence(int length)
{
public:
this(int start, int step)
{
for(int i = 0; i < length; i++)
elements[i] = start + (i * step);
}
int[length] elements;
}
pure int f()
{
auto x = inew IncreasingSequence!(5)(1, 1);
/* do stuff */
return result;
}
pure int g()
{
auto y = inew IncreasingSequence!(15)(10, 3);
/* do stuff */
return result;
}
Isn't it beautiful? Yet, it's /very/ close to wait you wanted.
More information about the Digitalmars-d
mailing list