Re: dlang.org/spec/function.html#pure-functions example

2023-10-28 Thread Nick Treleaven via Digitalmars-d-learn

On Monday, 16 October 2023 at 18:05:04 UTC, Paul wrote:
On Thursday, 12 October 2023 at 21:20:44 UTC, Jonathan M Davis 
wrote:

look like?

Types can have static members.

Basically what it comes down to is that outside of immutable 
data, pure functions only have access to their arguments and 
to what they can access via their arguments (be it by getting 
pointers from those arguments or calling other pure functions 
on them).


- Jonathan M Davis


Can I say in the general sense that when the word static is 
used it means that something is defined/declared at compile 
time?


This link should describe all the uses of `static`:
https://dlang.org/spec/attribute.html#static


Re: dlang.org/spec/function.html#pure-functions example

2023-10-21 Thread Jonathan M Davis via Digitalmars-d-learn
On Monday, October 16, 2023 12:05:04 PM MDT Paul via Digitalmars-d-learn 
wrote:
> On Thursday, 12 October 2023 at 21:20:44 UTC, Jonathan M Davis
>
> wrote:
> > look like?
> >
> > Types can have static members.
> >
> > Basically what it comes down to is that outside of immutable
> > data, pure functions only have access to their arguments and to
> > what they can access via their arguments (be it by getting
> > pointers from those arguments or calling other pure functions
> > on them).
> >
> > - Jonathan M Davis
>
> Can I say in the general sense that when the word static is used
> it means that something is defined/declared at compile time?

Hmmm. It seems like my message got eaten. So, I'll write it out again.

In any case, no, in general, static really doesn't have much to with runtime
vs compile time. It means different things in different contexts. Off the
top of my head, the only contexts where static specifically has anything to
do with compile time are with static if and static foreach, in which case,
those constructs become compile-time constructs instead of runtime
constructos. Other contexts have very different meanings for static.

For instance, a static member function is a member function that doesn't
have an implicit this reference/pointer and thus is pretty much just a
function that's scoped to the class/struct rather than being a function that
operates on instances of that class or struct.

On the other hand, static member variables are variables which are
associated with the class or struct and not with an instance of that class
or struct. So, there is only one instance of that variable for all objects
of that class or struct on a single thread, as opposed to non-static member
variables which are specific to each object.

static in functions has similar but different meanings. On a nested
function, it makes it so that the function has no implicit parameter which
is a reference to the context of the outer function, meaning that it's
pretty much just a function within another function, whereas a non-static
nested function actually has access to the outer function's scope and thus
can access the variables in the outer scope.

On the other hand, a static variable within a function is a variable where
there is only one instance of that variable for every call to that function
on a single thread, as opposed to normal function variables which get a new
instance every time that the function is called.

And there are other meanings for static in other contexts. There are
similarities between them, but if there is a definition that can be given
for what static means which covers all of those contexts (and there may be -
C manages that in spite of the fact that static means very different things
in different contexts there too), it's not an obvious definition. You mostly
just have to learn what static means in each context that it's used rather
than memorizing a general definition for it that can be applied in each
context.

- Jonathan M Davis





Re: dlang.org/spec/function.html#pure-functions example

2023-10-21 Thread Jonathan M Davis via Digitalmars-d-learn
On Monday, October 16, 2023 12:05:04 PM MDT Paul via Digitalmars-d-learn 
wrote:
> On Thursday, 12 October 2023 at 21:20:44 UTC, Jonathan M Davis
> 
> wrote:
> > look like?
> > 
> > Types can have static members.
> > 
> > Basically what it comes down to is that outside of immutable
> > data, pure functions only have access to their arguments and to
> > what they can access via their arguments (be it by getting
> > pointers from those arguments or calling other pure functions
> > on them).
> > 
> > - Jonathan M Davis
> 
> Can I say in the general sense that when the word static is used
> it means that something is defined/declared at compile time?






Re: dlang.org/spec/function.html#pure-functions example

2023-10-16 Thread Paul via Digitalmars-d-learn
On Thursday, 12 October 2023 at 21:20:44 UTC, Jonathan M Davis 
wrote:

look like?

Types can have static members.

Basically what it comes down to is that outside of immutable 
data, pure functions only have access to their arguments and to 
what they can access via their arguments (be it by getting 
pointers from those arguments or calling other pure functions 
on them).


- Jonathan M Davis


Can I say in the general sense that when the word static is used 
it means that something is defined/declared at compile time?




Re: dlang.org/spec/function.html#pure-functions example

2023-10-16 Thread Paul via Digitalmars-d-learn
On Thursday, 12 October 2023 at 21:20:44 UTC, Jonathan M Davis 
wrote:


Thanks Jonathan




Re: dlang.org/spec/function.html#pure-functions example

2023-10-13 Thread Nick Treleaven via Digitalmars-d-learn

On Thursday, 12 October 2023 at 19:33:32 UTC, Paul wrote:
If **int x** is global mutable state, what does static mutable 
state look like?


In addition to Jonathan's reply, see:
https://dlang.org/spec/function.html#local-static-variables


Re: dlang.org/spec/function.html#pure-functions example

2023-10-12 Thread Jonathan M Davis via Digitalmars-d-learn
On Thursday, October 12, 2023 1:33:32 PM MDT Paul via Digitalmars-d-learn 
wrote:
> The spec doc has the following statement and corresponding
> example:
> ***"Pure functions cannot directly access global or static
> mutable state."***
>
> ```d
> int x;
> immutable int y;
>
> pure int foo(int i)
> {
>  i++; // ok, modifying local state
>  //x = i; // error, modifying global state
>  //i = x; // error, reading mutable global state
>  i = y;   // ok, reading immutable global state
>  throw new Exception("failed"); // ok
> }
> ```
> If **int x** is global mutable state, what does static mutable
> state look like?

Types can have static members.

Basically what it comes down to is that outside of immutable data, pure
functions only have access to their arguments and to what they can access
via their arguments (be it by getting pointers from those arguments or
calling other pure functions on them).

- Jonathan M Davis





Re: how to benchmark pure functions?

2022-10-29 Thread max haughton via Digitalmars-d-learn

On Thursday, 27 October 2022 at 18:41:36 UTC, Dennis wrote:

On Thursday, 27 October 2022 at 17:17:01 UTC, ab wrote:
How can I prevent the compiler from removing the code I want 
to measure?


With many C compilers, you can use volatile assembly blocks for 
that. With LDC -O3, a regular assembly block also does the 
trick currently:


```D
void main()
{
import std.datetime.stopwatch;
import std.stdio: write, writeln, writef, writefln;
import std.conv : to;

void f0() {}
void f1()
{
foreach(i; 0..4_000_000)
{
// nothing, loop gets optimized out
}
}
void f2()
{
foreach(i; 0..4_000_000)
{
// defeat optimizations
asm @safe pure nothrow @nogc {}
}
}
auto r = benchmark!(f0, f1, f2)(1);
writeln(r[0]); // 4 μs
writeln(r[1]); // 4 μs
writeln(r[2]); // 1 ms
}
```


I recommend a volatile data dependency rather than injecting 
volatile ASM into code FYI i.e. don't modify the pure function 
but rather make sure the result is actually used in the eyes of 
the compiler.


Re: how to benchmark pure functions?

2022-10-28 Thread Siarhei Siamashka via Digitalmars-d-learn

On Friday, 28 October 2022 at 09:48:14 UTC, ab wrote:
Thanks to H.S. Teoh and Dennis for the suggestions, they both 
work. I like the empty asm block a bit more because it is less 
invasive, but it only works with ldc.


I used the volatileLoad/volatileStore functions to ensure that 
the compiler doesn't find a way to optimize out the code (for 
example, move repetitive calculations out of the loop or even do 
them at compile time) and the RDTSC/RDTSCP instruction via inline 
assembly for measurements: 
https://gist.github.com/ssvb/5c926ed9bc755900fdaac3b71a0f7cfd


The goal was to have a very fast way to check (with no measurable 
overhead) whether reasonable optimization options had been 
supplied to the compiler.


Re: how to benchmark pure functions?

2022-10-28 Thread Imperatorn via Digitalmars-d-learn

On Friday, 28 October 2022 at 09:48:14 UTC, ab wrote:

On Thursday, 27 October 2022 at 17:17:01 UTC, ab wrote:

[...]


Thanks to H.S. Teoh and Dennis for the suggestions, they both 
work. I like the empty asm block a bit more because it is less 
invasive, but it only works with ldc.


@Imperatorn see Dennis code for an example. 
std.datetime.benchmark works, but at high optimization level 
(-O2, -O3) the loop can be removed and the time brought down to 
0hnsec. E.g. try "ldc2 -O3 -run dennis.d".


AB


Yeah I didn't read carefully enough sorry 


Re: how to benchmark pure functions?

2022-10-28 Thread ab via Digitalmars-d-learn

On Thursday, 27 October 2022 at 17:17:01 UTC, ab wrote:

Hi,

when trying to compare different implementations of the 
optimized builds of a pure function using benchmark from 
std.datetime.stopwatch, I get times equal to zero, I suppose 
because the functions are not executed as they do not have side 
effects.


The same happens with the example from the documentation:
https://dlang.org/library/std/datetime/stopwatch/benchmark.html

How can I prevent the compiler from removing the code I want to 
measure? Is there some utility in the standard library or 
pragma that I should use?


Thanks

AB


Thanks to H.S. Teoh and Dennis for the suggestions, they both 
work. I like the empty asm block a bit more because it is less 
invasive, but it only works with ldc.


@Imperatorn see Dennis code for an example. 
std.datetime.benchmark works, but at high optimization level 
(-O2, -O3) the loop can be removed and the time brought down to 
0hnsec. E.g. try "ldc2 -O3 -run dennis.d".


AB


Re: how to benchmark pure functions?

2022-10-27 Thread Dennis via Digitalmars-d-learn

On Thursday, 27 October 2022 at 17:17:01 UTC, ab wrote:
How can I prevent the compiler from removing the code I want to 
measure?


With many C compilers, you can use volatile assembly blocks for 
that. With LDC -O3, a regular assembly block also does the trick 
currently:


```D
void main()
{
import std.datetime.stopwatch;
import std.stdio: write, writeln, writef, writefln;
import std.conv : to;

void f0() {}
void f1()
{
foreach(i; 0..4_000_000)
{
// nothing, loop gets optimized out
}
}
void f2()
{
foreach(i; 0..4_000_000)
{
// defeat optimizations
asm @safe pure nothrow @nogc {}
}
}
auto r = benchmark!(f0, f1, f2)(1);
writeln(r[0]); // 4 μs
writeln(r[1]); // 4 μs
writeln(r[2]); // 1 ms
}
```



Re: how to benchmark pure functions?

2022-10-27 Thread H. S. Teoh via Digitalmars-d-learn
On Thu, Oct 27, 2022 at 06:20:10PM +, Imperatorn via Digitalmars-d-learn 
wrote:
> On Thursday, 27 October 2022 at 17:17:01 UTC, ab wrote:
> > Hi,
> > 
> > when trying to compare different implementations of the optimized
> > builds of a pure function using benchmark from
> > std.datetime.stopwatch, I get times equal to zero, I suppose because
> > the functions are not executed as they do not have side effects.
> > 
> > The same happens with the example from the documentation:
> > https://dlang.org/library/std/datetime/stopwatch/benchmark.html
> > 
> > How can I prevent the compiler from removing the code I want to
> > measure?  Is there some utility in the standard library or pragma
> > that I should use?
[...]

To prevent the optimizer from eliding the function completely, you need
to do something with the return value.  Usually, this means you combine
the return value into some accumulating variable, e.g., if it's an int
function, have a running int accumulator that you add to:

int funcToBeMeasured(...) pure { ... }

int accum;
auto results = benchmark!({ 
// Don't just call funcToBeMeasured and ignore the value
// here, otherwise the optimizer may delete the call
// completely.
accum += funcToBeMeasured(...);
});

Then at the end of the benchmark, do something with the accumulated
value, like print out its value to stdout, so that the optimizer doesn't
notice that the value is unused, and decide to kill all previous
assignments to it. Something like `writeln(accum);` at the end should do
the trick.


T

-- 
Indifference will certainly be the downfall of mankind, but who cares? -- 
Miquel van Smoorenburg


Re: how to benchmark pure functions?

2022-10-27 Thread Imperatorn via Digitalmars-d-learn

On Thursday, 27 October 2022 at 17:17:01 UTC, ab wrote:

Hi,

when trying to compare different implementations of the 
optimized builds of a pure function using benchmark from 
std.datetime.stopwatch, I get times equal to zero, I suppose 
because the functions are not executed as they do not have side 
effects.


The same happens with the example from the documentation:
https://dlang.org/library/std/datetime/stopwatch/benchmark.html

How can I prevent the compiler from removing the code I want to 
measure? Is there some utility in the standard library or 
pragma that I should use?


Thanks

AB


Sorry, I don't understand what you're saying.

The examples work for me. Can you provide an exact code example 
which does not work as expected for you?


how to benchmark pure functions?

2022-10-27 Thread ab via Digitalmars-d-learn

Hi,

when trying to compare different implementations of the optimized 
builds of a pure function using benchmark from 
std.datetime.stopwatch, I get times equal to zero, I suppose 
because the functions are not executed as they do not have side 
effects.


The same happens with the example from the documentation:
https://dlang.org/library/std/datetime/stopwatch/benchmark.html

How can I prevent the compiler from removing the code I want to 
measure? Is there some utility in the standard library or pragma 
that I should use?


Thanks

AB


Re: Map, filter and pure functions

2019-11-29 Thread Paul Backus via Digitalmars-d-learn

On Friday, 29 November 2019 at 15:54:13 UTC, realhet wrote:

On Friday, 29 November 2019 at 15:49:24 UTC, Paul Backus wrote:
It's actually a much simpler reason: filter calls .front twice 
for each element in its input (once to check if the value 
satisfies the predicate, and then again to return the value if 
it does), and the range returned by map doesn't save the value 
of .front between calls, so it has to re-compute it each time 
by calling the transform function.


This makes it clear.

In my case a cache which can access all the previous elements 
would be a too big thing, so I will do the filtering in a later 
stage manually. But most importantly, now I know what's going 
on, Thank You!


The "cache" wrapper only caches one element at a time. The cached 
value is discarded after each call to .popFront.


Re: Map, filter and pure functions

2019-11-29 Thread realhet via Digitalmars-d-learn

On Friday, 29 November 2019 at 15:49:24 UTC, Paul Backus wrote:
It's actually a much simpler reason: filter calls .front twice 
for each element in its input (once to check if the value 
satisfies the predicate, and then again to return the value if 
it does), and the range returned by map doesn't save the value 
of .front between calls, so it has to re-compute it each time 
by calling the transform function.


This makes it clear.

In my case a cache which can access all the previous elements 
would be a too big thing, so I will do the filtering in a later 
stage manually. But most importantly, now I know what's going on, 
Thank You!


Re: Map, filter and pure functions

2019-11-29 Thread realhet via Digitalmars-d-learn

On Friday, 29 November 2019 at 15:30:22 UTC, realhet wrote:

...


Unfortunately function purity is not the answer.

I put a very long calculation into the transform function which 
is called from "map!".

And the "filter!" is making the "map!" call my function 2 times:
First for the "filter!" to decide it allows the element or not.
And second when the map! is passing it to the foreach() where I 
write the elements out.


Is there a solution for this performance issue?

Using functional programming, my program looks beautiful. But I 
need it to be optimal too.


//To be easier to understand, I want to make the following:
foreach(a; input){
  auto temp = slowFunction(a);
  if(check(temp))
writeln(temp);
}

//But the elegant functional form ->
input.map!slowFunction.filter!(a => check(a)).each!writeln;

//Produces the following unoptimal solution:
foreach(a; input){
  if(check(slowFunction(a)))
writeln(slowFunction(a));
}

Is there a functional way to fix this?

Thank you in advance!





Re: Map, filter and pure functions

2019-11-29 Thread Paul Backus via Digitalmars-d-learn

On Friday, 29 November 2019 at 15:30:22 UTC, realhet wrote:

Hi,

I have an input range.
I use the map! on it to transform using a function.
Finally I use filter! on the transformed data.

When I do a foreach on this, i noticed, that the transform 
function is called twice for each element.
If I remove the filter! it does only one transform function 
call per element.


Is this because the function is NOT PURE, so Phobos thinks that 
the function can give different results for the same input?


If I modify the function to be pure, will the transform 
function be called only once?


It's actually a much simpler reason: filter calls .front twice 
for each element in its input (once to check if the value 
satisfies the predicate, and then again to return the value if it 
does), and the range returned by map doesn't save the value of 
.front between calls, so it has to re-compute it each time by 
calling the transform function.


You can work around this using std.algorithm.iteration.cache, a 
range wrapper that calls .front on the underlying range exactly 
once, and then saves the value and reuses it for subsequent calls:


myRange
.map!transform
.cache
.filter!pred
.each!doSomething;


Map, filter and pure functions

2019-11-29 Thread realhet via Digitalmars-d-learn

Hi,

I have an input range.
I use the map! on it to transform using a function.
Finally I use filter! on the transformed data.

When I do a foreach on this, i noticed, that the transform 
function is called twice for each element.
If I remove the filter! it does only one transform function call 
per element.


Is this because the function is NOT PURE, so Phobos thinks that 
the function can give different results for the same input?


If I modify the function to be pure, will the transform function 
be called only once?


Re: Cannot make my shared PureMallocator callable in pure functions

2018-02-17 Thread Nordlöw via Digitalmars-d-learn

On Saturday, 17 February 2018 at 14:54:37 UTC, ag0aep6g wrote:
Nordlöw's methods are only weakly pure. They have mutable 
indirections either in the return type or in a parameter type. 
So calls to them should not be optimized away.


I found a solution at

https://github.com/nordlow/phobos-next/blob/master/src/pure_mallocator.d

currently successfully used at

https://github.com/nordlow/phobos-next/blob/master/src/open_hashmap_or_hashset.d

Works for me.

Thanks!


Re: Cannot make my shared PureMallocator callable in pure functions

2018-02-17 Thread Steven Schveighoffer via Digitalmars-d-learn

On 2/17/18 9:54 AM, ag0aep6g wrote:

On 02/17/2018 03:04 PM, Steven Schveighoffer wrote:
You have to be a bit careful here. pure functions can assume nothing 
is happening and simply not call the function.


That's only a problem when the called function is strongly pure, right?

Nordlöw's methods are only weakly pure. They have mutable indirections 
either in the return type or in a parameter type. So calls to them 
should not be optimized away.


That's fine as long as you aren't going to use the allocator to make any 
immutable or const data ;)


-Steve


Re: Cannot make my shared PureMallocator callable in pure functions

2018-02-17 Thread Eduard Staniloiu via Digitalmars-d-learn

On Saturday, 17 February 2018 at 12:33:25 UTC, Nordlöw wrote:

I'm struggling with making

https://github.com/nordlow/phobos-next/blob/master/src/pure_mallocator.d

callable in pure functions such as here

https://github.com/nordlow/phobos-next/blob/master/src/pure_mallocator.d#L84

Shouldn't a shared

static shared PureMallocator instance;

make it possible to call

PureMallocator.instance.allocate(16);

in pure functions?


As the folks before me have pointed out, the language doesn't 
allow you to use globals inside pure code, excepting global 
immutables; this makes sense as once an immutable object was 
constructed it will never change.


As Steven pointed out, we are just trying to fool the compiler 
into thinking that allocators don't have side effects; in the 
case of Mallocator, we are just forwarding calls to libc's 
mallocator.


With this in mind, it looks to me that you just need to decide 
what is the best/easiest way for you to forward the calls. You 
could:
  1) make all you methods static (after all, the allocator is 
stateless)

  2) make `instance` immutable and make all the methods const



Re: Cannot make my shared PureMallocator callable in pure functions

2018-02-17 Thread ag0aep6g via Digitalmars-d-learn

On 02/17/2018 03:04 PM, Steven Schveighoffer wrote:
You have to be a bit careful here. pure functions can assume nothing is 
happening and simply not call the function.


That's only a problem when the called function is strongly pure, right?

Nordlöw's methods are only weakly pure. They have mutable indirections 
either in the return type or in a parameter type. So calls to them 
should not be optimized away.


Re: Cannot make my shared PureMallocator callable in pure functions

2018-02-17 Thread Steven Schveighoffer via Digitalmars-d-learn

On 2/17/18 8:32 AM, ag0aep6g wrote:

On 02/17/2018 01:35 PM, rikki cattermole wrote:

pure means no globals. As in none :)


... except immutable ones. And since PureMallocator has no fields, 
`instance` can be made immutable, and all the methods can be made static 
or const. Then they can be used in `pure` code.


You have to be a bit careful here. pure functions can assume nothing is 
happening and simply not call the function.


-Steve


Re: Cannot make my shared PureMallocator callable in pure functions

2018-02-17 Thread Steven Schveighoffer via Digitalmars-d-learn

On 2/17/18 7:33 AM, Nordlöw wrote:

I'm struggling with making

https://github.com/nordlow/phobos-next/blob/master/src/pure_mallocator.d

callable in pure functions such as here

https://github.com/nordlow/phobos-next/blob/master/src/pure_mallocator.d#L84 



Shouldn't a shared

     static shared PureMallocator instance;

make it possible to call

     PureMallocator.instance.allocate(16);

in pure functions?


Pure functions cannot access shared or thread-local data. They are not 
supposed to have any side effects.


Keep in mind, allocators have side effects, we just pretend they don't. 
You need to fool the compiler into thinking you aren't doing anything to 
global data.


The design of allocators makes this difficult. I suggested at one point 
in the past that such allocators make all functions static, which solves 
other problems. Oh, I even made a PR: 
https://github.com/dlang/phobos/pull/4288


But it wasn't to allow purity, it was to allow storage of an "instance" 
anywhere.


-Steve


Re: Cannot make my shared PureMallocator callable in pure functions

2018-02-17 Thread ag0aep6g via Digitalmars-d-learn

On 02/17/2018 01:35 PM, rikki cattermole wrote:

pure means no globals. As in none :)


... except immutable ones. And since PureMallocator has no fields, 
`instance` can be made immutable, and all the methods can be made static 
or const. Then they can be used in `pure` code.


Re: Cannot make my shared PureMallocator callable in pure functions

2018-02-17 Thread Nordlöw via Digitalmars-d-learn
On Saturday, 17 February 2018 at 12:35:00 UTC, rikki cattermole 
wrote:

in pure functions?


pure means no globals. As in none :)


I guess one solution is to make the member functions in 
PureMallocator static and change how the template argument 
`Allocator` for a container is used to call these member 
functions directly instead of via `instance`, right?


Re: Cannot make my shared PureMallocator callable in pure functions

2018-02-17 Thread rikki cattermole via Digitalmars-d-learn

On 17/02/2018 12:48 PM, Nordlöw wrote:

On Saturday, 17 February 2018 at 12:35:00 UTC, rikki cattermole wrote:

in pure functions?


pure means no globals. As in none :)


I don't understand.

I thought std.experimental.allocators API was designed to be able 
express these needs, @andralex?


Library code cannot change the language.

pure functions cannot access globals period, it does not matter what you 
write. Its a hard limit. You simply don't want pure here.


Re: Cannot make my shared PureMallocator callable in pure functions

2018-02-17 Thread Nordlöw via Digitalmars-d-learn
On Saturday, 17 February 2018 at 12:35:00 UTC, rikki cattermole 
wrote:

in pure functions?


pure means no globals. As in none :)


I don't understand.

I thought std.experimental.allocators API was designed to be able 
express these needs, @andralex?


Cannot make my shared PureMallocator callable in pure functions

2018-02-17 Thread Nordlöw via Digitalmars-d-learn

I'm struggling with making

https://github.com/nordlow/phobos-next/blob/master/src/pure_mallocator.d

callable in pure functions such as here

https://github.com/nordlow/phobos-next/blob/master/src/pure_mallocator.d#L84

Shouldn't a shared

static shared PureMallocator instance;

make it possible to call

PureMallocator.instance.allocate(16);

in pure functions?


Re: Cannot make my shared PureMallocator callable in pure functions

2018-02-17 Thread Nordlöw via Digitalmars-d-learn

On Saturday, 17 February 2018 at 12:33:25 UTC, Nordlöw wrote:

PureMallocator.instance.allocate(16);


currently errors as

pure_mallocator.d(84,16): Error: pure function 
'pure_mallocator.__unittest_pure_mallocator_82_0' cannot access 
mutable static data 'instance'


Re: Cannot make my shared PureMallocator callable in pure functions

2018-02-17 Thread rikki cattermole via Digitalmars-d-learn

On 17/02/2018 12:33 PM, Nordlöw wrote:

I'm struggling with making

https://github.com/nordlow/phobos-next/blob/master/src/pure_mallocator.d

callable in pure functions such as here

https://github.com/nordlow/phobos-next/blob/master/src/pure_mallocator.d#L84 



Shouldn't a shared

     static shared PureMallocator instance;

make it possible to call

     PureMallocator.instance.allocate(16);

in pure functions?


pure means no globals. As in none :)


Re: std.algorithm can not be used inside pure functions?

2017-05-06 Thread Szabo Bogdan via Digitalmars-d-learn

On Saturday, 6 May 2017 at 15:01:16 UTC, Adam D. Ruppe wrote:

On Saturday, 6 May 2017 at 14:14:41 UTC, Szabo Bogdan wrote:
oh yes, I get it... begin and end are `SysTime`.. there is any 
workaround for this?


Don't use pure?

I don't think any of the SysTime conversion methods are pure 
since all of them call C functions which pull from the time 
zone... even if you subclassed the timezone to be pure, SysTime 
wouldn't pick that up since it uses the impure interface.


I guess you could use a casted wrapper to hack in pure too, but 
I'd say just take the keyword off.


Thanks!


Re: std.algorithm can not be used inside pure functions?

2017-05-06 Thread Jonathan M Davis via Digitalmars-d-learn
On Saturday, May 6, 2017 2:14:41 PM CEST Szabo Bogdan via Digitalmars-d-
learn wrote:
> On Saturday, 6 May 2017 at 13:21:10 UTC, Adam D. Ruppe wrote:
> > On Saturday, 6 May 2017 at 13:19:17 UTC, Szabo Bogdan wrote:
> >> a.begin.toISOExtString,
> >
> > I believe that function is not marked pure if it is a SysTime
> > because it needs to pull global timezone info.
> >
> > What is the type of a.begin?
>
> oh yes, I get it... begin and end are `SysTime`.. there is any
> workaround for this?

Not really, no.

The SysTime operations should be pure so long as they don't involve the
TimeZone (e.g. adding and substracting is fine), but converting to a string
involves using the TimeZone, because it needs to convert the value from UTC
to whatever the time zone is. It would be nice if TimeZone operations could
be pure, but they fundamentally can't be because that doesn't work when
dealing with the system's local time.

- Jonathan M Davis



Re: std.algorithm can not be used inside pure functions?

2017-05-06 Thread Adam D. Ruppe via Digitalmars-d-learn

On Saturday, 6 May 2017 at 14:14:41 UTC, Szabo Bogdan wrote:
oh yes, I get it... begin and end are `SysTime`.. there is any 
workaround for this?


Don't use pure?

I don't think any of the SysTime conversion methods are pure 
since all of them call C functions which pull from the time 
zone... even if you subclassed the timezone to be pure, SysTime 
wouldn't pick that up since it uses the impure interface.


I guess you could use a casted wrapper to hack in pure too, but 
I'd say just take the keyword off.


Re: std.algorithm can not be used inside pure functions?

2017-05-06 Thread Szabo Bogdan via Digitalmars-d-learn

On Saturday, 6 May 2017 at 13:21:10 UTC, Adam D. Ruppe wrote:

On Saturday, 6 May 2017 at 13:19:17 UTC, Szabo Bogdan wrote:

a.begin.toISOExtString,


I believe that function is not marked pure if it is a SysTime 
because it needs to pull global timezone info.


What is the type of a.begin?


oh yes, I get it... begin and end are `SysTime`.. there is any 
workaround for this?


std.algorithm can not be used inside pure functions?

2017-05-06 Thread Szabo Bogdan via Digitalmars-d-learn

Hi,

I'm trying to write a function that saves some structs as csv 
file:


```
string toCsv(const(StatStorage) storage) {
  return storage.values
.map!(a => [ a.name, a.begin.toISOExtString, 
a.end.toISOExtString, a.status.to!string ])

.map!(a => a.join(','))
.join('\n');
}
```

I think that it's obvious that this function has no external 
state and from my understanding, it should be a pure function. 
But when I declare it as `pure` I get an error `Error: pure 
function 'trial.reporters.stats.toCsv' cannot call impure 
function 'std.array.join!(MapResult!(__lambda3, 
MapResult!(__lambda2, const(Stat)[])), char).join'`.


What am I missing here?


Re: pure functions

2016-09-13 Thread Jonathan M Davis via Digitalmars-d-learn
On Tuesday, September 13, 2016 20:08:22 Patrick Schluter via Digitalmars-d-
learn wrote:
> On Tuesday, 13 September 2016 at 06:59:10 UTC, Jonathan M Davis
>
> wrote:
> > On Tuesday, September 13, 2016 03:33:04 Ivy Encarnacion via
> >
> > Digitalmars-d- learn wrote:
> >  A pure function cannot call any function that is not pure [...]
>
> I've read that a lot but it's not true. A pure function can call
> impure function. The restriction is, that the impure function
> called within the pure function does not depend or mutate on
> state existing outside of that function. If the called function
> changes local variable, it has no bearing on outside the scope.
> Here a contrived example in C.
>
> size_t strlen(const char *str); is pure. If I define it this way
> for example:
>
> size_t my_strlen(const char *str)
> {
>char temp[50];
>
>strlcpy(temp, str, sizeof temp);  /* strlcpy is not pure as it
> mutates something outside of its "scope" */
>
>return strlen(str);
> }
>
> That function is pure. There is no visible change outside of it.
>
> my_strlen and strlen have exactly the same properties.

That's because you're talking about functional purity and _not_ D's pure. If
you want to talk about D's pure, you pretty much need to forget about
functional purity. While D's pure allows you to get functional purity, it's
actually something different. It would be far more accurate at this point if
it were called something like @noglobal. Actual, functional purity really
only comes into play when a pure function's parameters are immutable or
implicitly convertible to immutable, at which point the compiler can
guarantee that the same arguments to the function will result in the
function returning the same result. Sometimes, pure functions whose
parameters are immutable or implicitly convertible to immutable are referred
to as strongly pure functions, whereas those whose parameters aren't are
called weakly pure. So-called strongly pure functions are what you need if
you want to talk about functional purity, whereas so-called weakly pure
functions are still pure as far as D is concerned, because they don't
violate the functional purity of a strongly pure function if they're called
by it.

Originally, for a function to be pure in D, it _had_ to have parameters
which were immutable or implicitly convertible to immutable, which actually
was functionally pure, but it was too restrictive to be useful, so pure was
expanded to what it is now, which makes it so that it's not really about
functional purity anymore even though it enables functional purity in a way
that the compiler can detect it and optimize for it.

But when a D programmer talks about a function that's imppure, they're
generally not talking about functional purity but about whether it's marked
with pure or inferred as pure by the compiler, and per that definition, the
code that you have above _is_ pure. In a way, what you're trying to prove
about impure in D is both right and wrong, because we're dealing with
conflicting definitions of purity here. When discussing pure in D, if you
want to talk about whether a function is functionally pure in the sense that
one would normally talk about pure functions outside of D, then you need to
clearly state that you're talking about functional purity and not about D's
pure. When simply saying that something is pure or not, folks here are going
to expect you to be talking about D's definition of purity.

By the way, the only ways to get around pure are:

1. use debug blocks (where pure is ignored in order to facilite debugging).

2. use an extern(*) other than extern(D) so that the body of the function
   doesn't have to be marked pure like the prototype does (since other types
   of linkage don't actually use pure), allowing you to lie to the compiler.

3. use function pointers and cast an impure function pointer to a pure one
   and thereby lie to the compiler.

So, there are a couple of ways to fool the compiler, but there's only one
wayt that's sanctioned by it, and it's only intended for debugging purposes.

- Jonathan M Davis



Re: pure functions

2016-09-13 Thread Steven Schveighoffer via Digitalmars-d-learn

On 9/13/16 4:08 PM, Patrick Schluter wrote:

On Tuesday, 13 September 2016 at 06:59:10 UTC, Jonathan M Davis wrote:

On Tuesday, September 13, 2016 03:33:04 Ivy Encarnacion via
Digitalmars-d- learn wrote:

 A pure function cannot call any function that is not pure [...]


I've read that a lot but it's not true. A pure function can call impure
function. The restriction is, that the impure function called within the
pure function does not depend or mutate on state existing outside of
that function. If the called function changes local variable, it has no
bearing on outside the scope.


D defines pure differently.

You are allowed to declare a function is pure if it takes (and possibly 
changes) mutable references. It can be called by pure functions, but 
will not be optimized in the same way one would expect traditional pure 
functions to be optimized.


We call it "weak-pure".

In D, an "impure" function is defined exactly as one that accesses 
mutable global state. Everything else can be declared pure. The one 
exception is memory allocation.


-Steve


Re: pure functions

2016-09-13 Thread Patrick Schluter via Digitalmars-d-learn
On Tuesday, 13 September 2016 at 06:59:10 UTC, Jonathan M Davis 
wrote:
On Tuesday, September 13, 2016 03:33:04 Ivy Encarnacion via 
Digitalmars-d- learn wrote:


 A pure function cannot call any function that is not pure [...]


I've read that a lot but it's not true. A pure function can call 
impure function. The restriction is, that the impure function 
called within the pure function does not depend or mutate on 
state existing outside of that function. If the called function 
changes local variable, it has no bearing on outside the scope.

Here a contrived example in C.

size_t strlen(const char *str); is pure. If I define it this way 
for example:


size_t my_strlen(const char *str)
{
  char temp[50];

  strlcpy(temp, str, sizeof temp);  /* strlcpy is not pure as it 
mutates something outside of its "scope" */


  return strlen(str);
}

That function is pure. There is no visible change outside of it.

my_strlen and strlen have exactly the same properties.



Re: pure functions

2016-09-13 Thread Jonathan M Davis via Digitalmars-d-learn
On Tuesday, September 13, 2016 03:33:04 Ivy Encarnacion via Digitalmars-d-
learn wrote:
> Can pure functions throw exceptions on its arguments? Also, how
> can it perform impure operations?

Yes, as long as the exception's constructor is pure, a pure function can
throw an exception. However, whether a pure function can do impure
operations depends on what you mean by that. A pure function cannot call any
function that is not pure (except in debug blocks, which circumvent pure
purely for debug purposes and should not be used in normal code). That's
part of being pure. But "pure" in the D sense really doesn't have anything
to do with functional purity except insofar as it helps enable functional
purity, so if when you're talking about a pure function doing an impure
operation, you mean doing something that isn't functionally pure, then it
can so long as the function's that it's calling are all pure.

_All_ that pure means in D is that the function cannot access any mutable,
global state or call any functions that aren't pure. At this point, it would
be far more accurate for it to be called @noglobal than pure, but it's pure
because when it was introduced, it was much closer to functionally pure (but
far less useful). Originally, pure functions had to have parameters which
were immutable or implicitly convertible to immutable so that the function
could be functionally pure. That requirement no longer exists, but when a
pure function does meet those requirements, there are optimizations that the
compiler can do based on functional purity. For instance, a pure function
which is functionally pure (i.e. if given the same arguments, it will always
result in the same return value) will only be called once with a given set
of arguments within an expression even if it's called multiple times. e.g.

auto result = pureFunc(a) * pureFunc(a);

would result in only one call to pureFunc if pureFunc's parameters are
immutable or implicitly convertible to immutable, and the result will be
reused. But if the paramaters are not immutable or implicitly convertible to
immutable, then it's not functionally pure, and the calls cannot be
optimized. Most pure functions can't be optimized like that. On the whole,
pure is just a way to guarantee that a function is only using what it's
given via its arguments and not doing stuff like saving state in static or
global variables. Being able to optimize based on pure when it's actually
functionally pure is a just a nice bonus that pops up occasionally.

For a more in-depth look at D's purity, you should read

http://klickverbot.at/blog/2012/05/purity-in-d/

- Jonathan M Davis



Re: pure functions

2016-09-12 Thread sarn via Digitalmars-d-learn
On Tuesday, 13 September 2016 at 03:33:04 UTC, Ivy Encarnacion 
wrote:

Can pure functions throw exceptions on its arguments?


You can throw exceptions for whatever reasons from a function 
marked pure:


void foo() pure
{
throw new Exception("nope");
}

void main()
{
foo();
}


Also, how can it perform impure operations?


Well, the point of pure is to restrict you from doing that.  Is 
there something specific you're trying to do?


pure functions

2016-09-12 Thread Ivy Encarnacion via Digitalmars-d-learn
Can pure functions throw exceptions on its arguments? Also, how 
can it perform impure operations?


Question about pure functions

2013-09-16 Thread Bienlein

Hello,

ich habe a pure method bar() in a class Foo:

class Foo {
int i = 0;

void bar() pure {
i++;
}   
}

main() {
auto foo = new Foo();
foo.bar()   
}

The pure method bar changes the inst var i. Nevertheless, the
code above compiles and runs which I find confusing. I assumed
that changing an inst var by a pure function is considered
creating a side efect. But the compiler has no problems with this.

Am I getting something wrong here? Thanks for any hints.
Regards, Bienlein


Re: Question about pure functions

2013-09-16 Thread anonymous

On Monday, 16 September 2013 at 07:01:52 UTC, Bienlein wrote:

Hello,

ich habe a pure method bar() in a class Foo:

class Foo {
int i = 0;

void bar() pure {
i++;
}   
}

main() {
auto foo = new Foo();
foo.bar()   
}

The pure method bar changes the inst var i. Nevertheless, the
code above compiles and runs which I find confusing. I assumed
that changing an inst var by a pure function is considered
creating a side efect. But the compiler has no problems with 
this.


Am I getting something wrong here? Thanks for any hints.
Regards, Bienlein


(Weak) pure functions are allowed to mutate their arguments. 
Methods take the object via a hidden parameter, so that's an 
argument, too.


Mark all parameters const to get a strong pure function. For 
this const goes on the method:


class Foo {
int i = 0;

void bar() const pure {
// can't mutate i here
}
}

See also: http://dlang.org/function.html#pure-functions


Re: Question about pure functions

2013-09-16 Thread Bienlein
Mark all parameters const to get a strong pure function. For 
this const goes on the method:


class Foo {
int i = 0;

void bar() const pure {
// can't mutate i here
}
}

See also: http://dlang.org/function.html#pure-functions


I see, thanks a lot. I like this pure feature and was already
disappointed. Scala doesn't have it (has to remain interoperable
with Java), so I was really happy to see it in D. Your answer
saved my day :-)

-- Bienlein


Re: Question about pure functions

2013-09-16 Thread Jonathan M Davis
On Monday, September 16, 2013 10:08:22 anonymous wrote:
 Mark all parameters const to get a strong pure function. For
 this const goes on the method:

That's not actually enough. At present, in order for a function to be 
considered strongly pure, all of its parameters must be either immutable or 
implicitly convertible to pure (including the this reference). A const 
reference type is neither.

In principle, a function could be considered strongly pure if its parameters 
were const but its arguments were immutable, but the compiler isn't that smart 
about it at this point. The parameters themselves must be immutable or 
implicitly convertible to immutable.

So, at present, for a member function to be considered strongly pure, it must 
be an immutable member function, not const. In theory it could be const if the 
object itself were immutable, but again, the compiler isn't that smart about 
it at this point. In either case, the actual object would have to be 
immutable, which is not the case in most code.

And if you make the member functions immutable, they can only be called by 
immutable objects, forcing you to either duplicate your functions or make it 
so that your class can only be constructed as immutable.

pure member functions are useful, because they guarantee that the function is 
not accessing global mutable state, and because it makes it so that they can 
be called from strongly pure functions, but in general, pure member functions 
can't be strongly pure and therefore can't be optimized.

If you want to see how many times a pure function is being called, then put a
call to writeln inside of a debug {} block inside of it and compile with
-debug, since debug blocks are not checked for purity (since they're for
debugging). It should then print out every time it's being called, which should
allow you to see whether multiple calls with the same arguments within an
expression are actually being optimized out (though you might have to compile
with -O for the compiler to do the optimizations - I don't know).

- Jonathan M Davis


Re: pure functions calling impure functions at compile-time

2012-05-24 Thread Don Clugston

On 23/05/12 11:41, bearophile wrote:

Simen Kjaeraas:


Should this be filed as a bug, or is the plan that only pure functions be
ctfe-able? (or has someone already filed it, perhaps)


It's already in Bugzilla, see issue 7994 and 6169.


It's just happening because the purity checking is currently being done 
in a very unsophisticated way.



But I think there is a semantic hole in some of the discussions about
this problem. Is a future compile-time JIT allowed to perform
purity-derived optimizations in CTFE?


Some, definitely. Eg.  foo(n) + foo(n)

can be changed to 2*foo(n), where n is an integer, regardless of what 
foo does.


It does need to be a bit conservative, but I think the issues aren't 
CTFE specific. Eg, something like this currently gives an assert at runtime:


pure nothrow void check(int n) pure nothrow
{
  assert(n == 4);
}

void main()
{
check(3);
}

even though check() can do nothing other than cause an error, it still 
cannot be optimized away. But you can get rid of all subsequent calls to 
it, because they'll produce the same error every time.


Re: pure functions calling impure functions at compile-time

2012-05-23 Thread bearophile

Simen Kjaeraas:

Should this be filed as a bug, or is the plan that only pure 
functions be

ctfe-able? (or has someone already filed it, perhaps)


It's already in Bugzilla, see issue 7994 and 6169.

But I think there is a semantic hole in some of the discussions 
about this problem. Is a future compile-time JIT allowed to 
perform purity-derived optimizations in CTFE?


Bye,
bearophile


pure functions/methods

2012-04-20 Thread Namespace

The sense of pure functions isn't clear to me.
What is the advantage of pure functions / methods?
I inform the compiler with const that this method does not 
change the current object, and therefore he can optimize (at 
least in C++) this method. How and what optimized the compiler if 
i have pure or const pure functions / methods?


Re: pure functions/methods

2012-04-20 Thread Ary Manzana

On 4/20/12 4:06 PM, Namespace wrote:

The sense of pure functions isn't clear to me.
What is the advantage of pure functions / methods?
I inform the compiler with const that this method does not change the
current object, and therefore he can optimize (at least in C++) this
method. How and what optimized the compiler if i have pure or const
pure functions / methods?


As far as I know pure functions always return the same results given the 
same arguments. They also don't cause any side effect.


http://en.wikipedia.org/wiki/Pure_function

Many invocations of a pure function can be executed in parallel because 
they don't have side effects. There's also a chance of caching their 
result since it only depends on the value of their arguments (though I 
doubt what rule the compiler can use to decide to do it).


I don't think any of the following benefits are implemented in DMD.


Re: pure functions/methods

2012-04-20 Thread Sean Cavanaugh

On 4/20/2012 3:06 AM, Namespace wrote:

The sense of pure functions isn't clear to me.
What is the advantage of pure functions / methods?
I inform the compiler with const that this method does not change the
current object, and therefore he can optimize (at least in C++) this
method. How and what optimized the compiler if i have pure or const
pure functions / methods?


Simplest explanation I can think of is:

a const function of a class can't modify its own classes data
a pure function can't modify any data, or call other functions that are 
not also pure (though there are exceptions)




Re: pure functions/methods

2012-04-20 Thread Timon Gehr

On 04/20/2012 10:06 AM, Namespace wrote:

The sense of pure functions isn't clear to me.
What is the advantage of pure functions / methods?


1. It enables stateless reasoning about program parts.
2. It enables certain compiler optimizations.


I inform the compiler with const that this method does not change the
current object, and therefore he can optimize (at least in C++) this
method.


const on a method does not give any guarantees in C++. A C++ compiler 
cannot perform optimizations based on a const method.



How and what optimized the compiler if i have pure or const
pure functions / methods?


DMD does not do a lot there currently.

This article seems to discuss what GCC does with pure functions:
http://lwn.net/Articles/285332/


Re: pure functions/methods

2012-04-20 Thread Namespace

On Friday, 20 April 2012 at 09:55:28 UTC, Timon Gehr wrote:

On 04/20/2012 10:06 AM, Namespace wrote:

The sense of pure functions isn't clear to me.
What is the advantage of pure functions / methods?


1. It enables stateless reasoning about program parts.
2. It enables certain compiler optimizations.

I inform the compiler with const that this method does not 
change the
current object, and therefore he can optimize (at least in 
C++) this

method.


const on a method does not give any guarantees in C++. A C++ 
compiler cannot perform optimizations based on a const method.



How and what optimized the compiler if i have pure or const
pure functions / methods?


DMD does not do a lot there currently.

This article seems to discuss what GCC does with pure functions:
http://lwn.net/Articles/285332/


So only GDC optimized pure functions at all?


Re: pure functions/methods

2012-04-20 Thread bearophile

Namespace:


So only GDC optimized pure functions at all?


I've seen DMD performs some optimizations with strongly pure 
functions that return integral values.


If you have code like:

int sqr(in int x) pure nothrow { return x * x; }

int y = ...
auto r = sqr(y) + sqr(y);

I think DMD replaces that with this, even when inlining is 
disabled:


int y = ...
auto r = sqr(y) * 2;

Bye,
bearophile


Re: Pure functions and delegates

2012-01-18 Thread Timon Gehr

On 01/18/2012 04:40 AM, H. S. Teoh wrote:

So, I was quite impressed with D's pureness system, and was
experimenting a bit with it. Then I discovered that delegates are
impure, which seems reasonable since there's no way to know what a
delegate might do. But *if* the compiler verifies that a particular
delegate is (weakly) pure in the context of the function that passed it,
then couldn't the function that it gets passed to be declared pure as
well?

The context is this:

class MyCollection {
...
void opApply(int delegate(const ref int n) cb) const {
...
if (cb(...)) { ... }
...
}
...
int[] enumerate() {
int[] list;
foreach (n; this) {
list ~= n;
}
return list;
}
}

Is there a way to convince the compiler that enumerate() can be marked
'pure' even though opApply() can't, in general, be pure because it
doesn't know what the delegate does?

Technically, enumerate() is weakly pure, because its delegate does not
touch anything outside of its scope, and given this particular delegate,
opApply() also is weakly pure. In other words, opApply()'s pureness
depends on the delegate passed to it. So if there was a way for the
compiler to check that yes, opApply() is (weakly) pure except for the
part that calls the delegate (perhaps using some kind of conditionally
pure attribute?), then it should, in theory, be possible to verify that
yes, the delegate that enumerate() passes to opApply() does not violate
pureness, so enumerate() can be labelled 'pure'.

The trouble is, given the current state of things, there is no way to
implement enumerate() in a pure way, short of duplicating most of
opApply()'s code and substituting the line that calls the delegate.
Which is a rather ugly workaround. But otherwise, MyCollection cannot be
used inside a (strongly) pure function unless it avoids using opApply()
and enumerate() altogether, even if the container never escapes the pure
function's scope. This is quite a major limitation IMHO.


T



I see two distinct issues here:

1.

int foo(int delegate(int) dg,x){return dg(x);}
int bar(int x)pure{foo(x=x,x);} // error but would be ok

2.

int foo(int x)pure{
int x;
(y=x=y)(2); // error but would be ok
return x;
}

1. could be resolved by a simple purity wildcard, in the lines of inout. 
(auto pure? =))
2. could be resolved by extending the weakly pure rule to the context 
pointer of nested functions. Nested functions and delegates would need 
to be able to be declared 'const'. (indicating that they are not allowed 
to mutate anything through the context pointer.) delegate literals and 
nested template function instantiations would need const inference.









Pure functions and delegates

2012-01-17 Thread H. S. Teoh
So, I was quite impressed with D's pureness system, and was
experimenting a bit with it. Then I discovered that delegates are
impure, which seems reasonable since there's no way to know what a
delegate might do. But *if* the compiler verifies that a particular
delegate is (weakly) pure in the context of the function that passed it,
then couldn't the function that it gets passed to be declared pure as
well?

The context is this:

class MyCollection {
...
void opApply(int delegate(const ref int n) cb) const {
...
if (cb(...)) { ... }
...
}
...
int[] enumerate() {
int[] list;
foreach (n; this) {
list ~= n;
}
return list;
}
}

Is there a way to convince the compiler that enumerate() can be marked
'pure' even though opApply() can't, in general, be pure because it
doesn't know what the delegate does?

Technically, enumerate() is weakly pure, because its delegate does not
touch anything outside of its scope, and given this particular delegate,
opApply() also is weakly pure. In other words, opApply()'s pureness
depends on the delegate passed to it. So if there was a way for the
compiler to check that yes, opApply() is (weakly) pure except for the
part that calls the delegate (perhaps using some kind of conditionally
pure attribute?), then it should, in theory, be possible to verify that
yes, the delegate that enumerate() passes to opApply() does not violate
pureness, so enumerate() can be labelled 'pure'.

The trouble is, given the current state of things, there is no way to
implement enumerate() in a pure way, short of duplicating most of
opApply()'s code and substituting the line that calls the delegate.
Which is a rather ugly workaround. But otherwise, MyCollection cannot be
used inside a (strongly) pure function unless it avoids using opApply()
and enumerate() altogether, even if the container never escapes the pure
function's scope. This is quite a major limitation IMHO.


T

-- 
He who laughs last thinks slowest.


Re: Forcing compile time evaluation of pure functions

2011-07-14 Thread scarrow
I think invoking a template to call the pure function (StaticEval!(Hash(foo))
isn't much different from StaticHash!(foo).  You still have to explicitly know
whether you're dealing with a compile time constant or not.  I'd really like to
figure out how to have Hash(foo) be static and Hash(variable) be dynamic.


Re: Forcing compile time evaluation of pure functions

2011-07-14 Thread bearophile
scarrow:

 I'd really like to figure out how to have Hash(foo) be static and 
 Hash(variable) be dynamic.

In GCC there is a way to (sometimes) do it, see the __builtin_constant_p here:
http://www.delorie.com/gnu/docs/gcc/gcc_81.html

Time ago I have asked for something similar in D too, because I think it allows 
to implement a poor's man manual partial compilation using templates. Maybe 
it's worth asking about this in the main D newsgroup. But before asking, it's 
better to have few use cases examples :-)

Bye,
bearophile


Re: Forcing compile time evaluation of pure functions

2011-07-14 Thread bearophile
 In GCC there is a way to (sometimes) do it, see the __builtin_constant_p here:
 http://www.delorie.com/gnu/docs/gcc/gcc_81.html

Google code search gives about 8,100 answers:
http://www.google.com/codesearch#search/q=%22__builtin_constant_p%22type=cs

Bye,
bearophile


Re: Forcing compile time evaluation of pure functions

2011-06-30 Thread bearophile
scarrow:

 Annoyingly, however, I can't do the following at compile time:
 
 f(Hash(foo));
 
 I'm not sure what the point is in distinguishing between these two cases.

Walter has decided that he doesn't like the D compiler to arbitrary run at 
compile time arbitrary long to run code. This is named partial compilation and 
it has some traps. In theory I agree with you that I'd like the compiler to be 
smarter, but in practice Walter prefers control here, so DMD runs compile-time 
functions only if you explicitly ask their result to be known at compile-time.

Note that in D you are able to run at compile time functions that are pure just 
in the execution path that's used at compile-time, even if on the whole they 
are not pure. This works:

int x;
int foo(bool b, int y) { if (b) return x; else return y; }
enum result = foo(false, 10);


 I want to be able to write:
 
 string s = bar;
 f(Hash(foo));// invoke the compile time version and pass a constant 
 to f
 f(Hash(s));// invoke the runtime version and pass the result to f

Is this good enough?

/**
To execute a function at compile time.
*/
template StaticEval(A...) {
   enum typeof(A[0]) StaticEval = A[0];
}

void f(size_t) {}
size_t Hash(string s) { return 0U; }

void main() {
f(Hash(foo));
f(StaticEval!(Hash(foo)));
}


The second Hash runs at compile-time, there is only one call to 
_D4test4HashFAyaZk (compiled with -O -release, without -inline):

__Dmain comdat
L0: pushEAX
pushdword ptr FLAT:_DATA[0Ch]
pushdword ptr FLAT:_DATA[08h]
callnear ptr _D4test4HashFAyaZk
callnear ptr _D4test1fFkZv
xor EAX,EAX
callnear ptr _D4test1fFkZv
xor EAX,EAX
pop ECX
ret

Bye,
bearophile


Re: Forcing compile time evaluation of pure functions

2011-06-30 Thread Simen Kjaeraas

On Thu, 30 Jun 2011 07:11:44 +0200, scarrow shawn.ba...@gmail.com wrote:


Hey all,

I'd like to embed hashed strings into my code.  The C++ version of this  
engine
ran an external tool to preprocess the files.  In D my strongly pure  
function
is only evaluated if I assign it to something like an enum or invoke it  
from a

template.  So the following generate compile time hashes:

enum blort = Hash(foo);
f(CHash!(foo));

Annoyingly, however, I can't do the following at compile time:

f(Hash(foo));

I'm not sure what the point is in distinguishing between these two  
cases.  If
it is a properly pure function there should be no harm in doing a  
compile time

evaluation.


Actually, there might. Pure functions are allowed to depend upon the
immutable global variables, whose values may be calculated at startup
(see static this)

--
  Simen


Forcing compile time evaluation of pure functions

2011-06-29 Thread scarrow
Hey all,

I'd like to embed hashed strings into my code.  The C++ version of this engine
ran an external tool to preprocess the files.  In D my strongly pure function
is only evaluated if I assign it to something like an enum or invoke it from a
template.  So the following generate compile time hashes:

enum blort = Hash(foo);
f(CHash!(foo));

Annoyingly, however, I can't do the following at compile time:

f(Hash(foo));

I'm not sure what the point is in distinguishing between these two cases.  If
it is a properly pure function there should be no harm in doing a compile time
evaluation.  Ideally (and maybe this is being purposely avoided) I want to be
able to write:

string s = bar;
f(Hash(foo));// invoke the compile time version and pass a constant 
to f
f(Hash(s));// invoke the runtime version and pass the result to f


Re: Forcing compile time evaluation of pure functions

2011-06-29 Thread scarrow
Oh, I also wanted to mention that although ideally I'd be able to invoke the
compile time and runtime versions identically and have it automatically select,
I'm also worried about accidentally invoking the runtime version when I should
have been using the compile time version.  I can't think of a way to make it:

string s = foo;
auto h = Hash(foo);// I'd like it to fail but doesn't
auto i = CHash!(foo);  // works fine (compile time)
auto j = Hash(s);// works fine (runtime)
auto k = CHash!(s);  // fails as it should




running pure functions in parallel

2010-08-03 Thread Justin
I'm designing an application which needs to process a lot of data as quickly as
possible. I've found that I can engineer the processing algorithms into pure
functions which can operate on different segments of my data. I would like to
run these functions in parallel but:

spawn() precludes returning a value
the docs seem to be silent on the possibility of using out parameters

Do I have to use messaging passing to get a value out of a pure function being
run in a separate thread?


Making pure functions get dirty (D 2.0)

2009-02-20 Thread Burton Radons
I'm writing a general conversion template function a la:

  pure T convert (T, U) (const (U) value);

Sweet, and really handy for template errors because you can tell the user which 
number input it is that angered it. The problem is that if you're converting 
int to string there's allocations there that doesn't have to be there for many 
purposes (also I'm using it for error formatting, which isn't so good if what 
I'm telling the user is that there's no memory for allocations). So I thought 
I'd make it work like this:
 
  // May call write multiple times for arrays, each time builds onto the array.
  void convertInto (T, U, alias write) (const (T) value)
  {
write (You've bespoiled my honour, cur!\n);
  }

  void convertWith (T, U) (const (U) value, void delegate (T) write)
  {
convertInto! (T, U, write) (value);
  }

  import std.stdio;
  void main ()
  {
void write (string text) { writef (text); }
convertWith! (string, string) (Let's you and I spend a few moments alone 
without a chaperone, baby.\n, write);
  }

Strangely enough this compiles but it doesn't actually DO anything (everything 
works, it's just that convertInto is not called at all); just taking the pure 
off fixes it. Obviously it shouldn't work, but what would I do to make an 
conditionally-pure function like this without code replication or mixin madness?

It feels like I'm missing some kind of third way.


Re: Making pure functions get dirty (D 2.0)

2009-02-20 Thread Burton Radons
Oh I see what's going on. pure functions get funky processing; if you don't 
actually use their return values they're not even compiled. Once you actually 
take the return value it'll complain about it whether it's a pure inner 
function in a pure outer function or anything else unless if it's a pure outer 
function which is perhaps the most useless thing you could have in this context.