[Issue 23589] [REG2.095] Purity check special case gives circular reference error.

2022-12-31 Thread d-bugmail--- via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=23589

--- Comment #3 from Dlang Bot  ---
dlang/dmd pull request #14765 "merge stable" was merged into master:

- 4b5a7826a74616e017698da79cb216a52b85775b by Iain Buclaw:
  fix Issue 23589 - [REG2.095] Purity check special case gives circular
reference error

https://github.com/dlang/dmd/pull/14765

--


[Issue 23589] [REG2.095] Purity check special case gives circular reference error.

2022-12-30 Thread d-bugmail--- via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=23589

Dlang Bot  changed:

   What|Removed |Added

 Status|NEW |RESOLVED
 Resolution|--- |FIXED

--- Comment #2 from Dlang Bot  ---
dlang/dmd pull request #14750 "fix Issue 23589 - [REG2.095] Purity check
special case gives circular reference error" was merged into stable:

- df4670e4506c5f83bd35d9f330c420bec9baf163 by Iain Buclaw:
  fix Issue 23589 - [REG2.095] Purity check special case gives circular
reference error

https://github.com/dlang/dmd/pull/14750

--


[Issue 23589] [REG2.095] Purity check special case gives circular reference error.

2022-12-28 Thread d-bugmail--- via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=23589

Dlang Bot  changed:

   What|Removed |Added

   Keywords||pull

--- Comment #1 from Dlang Bot  ---
@ibuclaw created dlang/dmd pull request #14750 "fix Issue 23589 - [REG2.095]
Purity check special case gives circular reference error" fixing this issue:

- fix Issue 23589 - [REG2.095] Purity check special case gives circular
reference error

https://github.com/dlang/dmd/pull/14750

--


[Issue 23589] [REG2.095] Purity check special case gives circular reference error.

2022-12-28 Thread d-bugmail--- via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=23589

johanenge...@weka.io changed:

   What|Removed |Added

   Keywords||industry, rejects-valid

--


[Issue 23589] New: [REG2.095] Purity check special case gives circular reference error.

2022-12-28 Thread d-bugmail--- via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=23589

  Issue ID: 23589
   Summary: [REG2.095] Purity check special case gives circular
reference error.
   Product: D
   Version: D2
  Hardware: All
OS: All
Status: NEW
  Severity: regression
  Priority: P1
 Component: dmd
  Assignee: nob...@puremagic.com
  Reporter: johanenge...@weka.io

The testcase below compiles with 2.094, but fails compilation with 2.095.
The regression is introduced by this PR:
https://github.com/dlang/dmd/pull/12023 (introduces size check for the special
case of zero-sized struct). Removing the size check
(`sd.determineSize(v.loc);`) "fixes" the regression.

Testcase:
```
struct TemplStr(string Description_) {}

template A() {
bool member;
alias THIS = typeof(this);
static THIS staticInstance;
static asSize()
{
return staticInstance.member;
}
}

template B() {
enum cols = columns();

enum cols_two = cols;
TemplStr!(cols_two) tstr;
}

struct S
{
  mixin A;
  mixin B;

  static string columns() {
auto dummy = 
return "as";
  }
}
```

--


[Issue 12191] bad purity propagation for double-nested delegate templates

2022-12-17 Thread d-bugmail--- via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=12191

Iain Buclaw  changed:

   What|Removed |Added

   Priority|P2  |P3

--


[Issue 18590] nothrow constructor call still type-checks destructor for purity

2022-12-17 Thread d-bugmail--- via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=18590

Iain Buclaw  changed:

   What|Removed |Added

   Priority|P2  |P3

--


[Issue 7314] strong purity should be inferred at call site

2022-12-17 Thread d-bugmail--- via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=7314

Iain Buclaw  changed:

   What|Removed |Added

   Priority|P2  |P4

--


[Issue 17442] regex purity issues

2022-12-17 Thread d-bugmail--- via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=17442

Iain Buclaw  changed:

   What|Removed |Added

   Priority|P1  |P3

--


[Issue 12819] Refused purity conversion of immutable array of arrays

2022-12-17 Thread d-bugmail--- via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=12819

Iain Buclaw  changed:

   What|Removed |Added

   Priority|P1  |P4

--


[Issue 21202] [REG2.093] std.algorithm.mutation.moveEmplace cannot deduce purity and errors

2021-10-07 Thread d-bugmail--- via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=21202
Issue 21202 depends on issue 21850, which changed state.

Issue 21850 Summary: [REG2.093] Template inference of pure not working
https://issues.dlang.org/show_bug.cgi?id=21850

   What|Removed |Added

 Status|NEW |RESOLVED
 Resolution|--- |FIXED

--


[Issue 21202] [REG2.093] std.algorithm.mutation.moveEmplace cannot deduce purity and errors

2021-08-22 Thread d-bugmail--- via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=21202

johanenge...@weka.io changed:

   What|Removed |Added

 Status|RESOLVED|CLOSED

--


[Issue 21202] [REG2.093] std.algorithm.mutation.moveEmplace cannot deduce purity and errors

2021-08-17 Thread d-bugmail--- via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=21202

RazvanN  changed:

   What|Removed |Added

 Status|NEW |RESOLVED
 CC||razvan.nitu1...@gmail.com
 Resolution|--- |DUPLICATE

--- Comment #2 from RazvanN  ---


*** This issue has been marked as a duplicate of issue 21850 ***

--


[Issue 21202] [REG2.093] std.algorithm.mutation.moveEmplace cannot deduce purity and errors

2021-06-14 Thread d-bugmail--- via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=21202

Johan Engelen  changed:

   What|Removed |Added

 Depends on||21850


Referenced Issues:

https://issues.dlang.org/show_bug.cgi?id=21850
[Issue 21850] [REG2.093] Template inference of pure not working
--


[Issue 7314] strong purity should be inferred at call site

2021-01-24 Thread d-bugmail--- via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=7314

timon.g...@gmx.ch changed:

   What|Removed |Added

 Status|RESOLVED|REOPENED
 Resolution|INVALID |---

--- Comment #3 from timon.g...@gmx.ch ---
???

--


[Issue 7314] strong purity should be inferred at call site

2021-01-23 Thread d-bugmail--- via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=7314

mhh  changed:

   What|Removed |Added

 Status|NEW |RESOLVED
 CC||maxha...@gmail.com
 Resolution|--- |INVALID

--- Comment #2 from mhh  ---
spec problem + this behaviour would make it inconsistent with regular
assignments

--


[Issue 21202] [REG2.093] std.algorithm.mutation.moveEmplace cannot deduce purity and errors

2020-10-20 Thread d-bugmail--- via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=21202

Dlang Bot  changed:

   What|Removed |Added

   Keywords||pull

--- Comment #1 from Dlang Bot  ---
@JohanEngelen updated dlang/phobos pull request #7670 "Help compiler deduce
`pure` for moveEmplaceImpl" fixing this issue:

- whitespace fix

  Fixes issue 21202

https://github.com/dlang/phobos/pull/7670

--


[Issue 21202] [REG2.093] std.algorithm.mutation.moveEmplace cannot deduce purity and errors

2020-08-27 Thread d-bugmail--- via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=21202

johanenge...@weka.io changed:

   What|Removed |Added

   Keywords||industry

--


[Issue 21202] New: [REG2.093] std.algorithm.mutation.moveEmplace cannot deduce purity and errors

2020-08-27 Thread d-bugmail--- via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=21202

  Issue ID: 21202
   Summary: [REG2.093] std.algorithm.mutation.moveEmplace cannot
deduce purity and errors
   Product: D
   Version: D2
  Hardware: All
OS: All
Status: NEW
  Severity: regression
  Priority: P1
 Component: phobos
  Assignee: nob...@puremagic.com
  Reporter: johanenge...@weka.io

This code no longer works since dlang 2.093:

```
struct Strukt2 {
this(int* _block) {  }
}

struct Strukt {
int* block;
Strukt2 foo() { return Strukt2(null); }
alias foo this;
}

void johan() {
Strukt a;
Strukt b;
import std.algorithm.mutation: moveEmplace;
moveEmplace(a, b);
}
```

Error: `pure` function
`std.algorithm.mutation.moveEmplace!(Strukt).moveEmplace` cannot call impure
function `std.algorithm.mutation.moveEmplaceImpl!(Strukt).moveEmplaceImpl`

Can be fixed by annotating `moveEmplaceImpl` with `pure`.

--


[Issue 20815] Wrong purity inference for postblit and copy constructor in template struct

2020-05-09 Thread d-bugmail--- via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=20815

Atila Neves  changed:

   What|Removed |Added

 Status|NEW |RESOLVED
 Resolution|--- |INVALID

--


[Issue 20815] New: Wrong purity inference for postblit and copy constructor in template struct

2020-05-09 Thread d-bugmail--- via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=20815

  Issue ID: 20815
   Summary: Wrong purity inference for postblit and copy
constructor in template struct
   Product: D
   Version: D2
  Hardware: x86_64
OS: Linux
Status: NEW
  Severity: normal
  Priority: P1
 Component: dmd
  Assignee: nob...@puremagic.com
  Reporter: atila.ne...@gmail.com

The code below shouldn't compile, but does. The postblit function is obviously
not pure, but pure code is allowed to call it. Interestingly, marking the
postblit as pure explicitly causes it to no longer compile.


struct Struct(T) {
this(this) {
import std.stdio;
writeln("oops");
}
}

void fun(Struct!int s) pure;

void gun() pure {
fun(Struct!int());
}



--


[Issue 7456] Purity strength not documented

2019-12-21 Thread d-bugmail--- via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=7456

berni44  changed:

   What|Removed |Added

 Status|NEW |RESOLVED
 CC||bugzi...@d-ecke.de
 Resolution|--- |WORKSFORME

--- Comment #5 from berni44  ---
Seems to be documented meanwhile:

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

--


[Issue 20047] call of static nested function ignores purity

2019-07-15 Thread d-bugmail--- via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=20047

Dlang Bot  changed:

   What|Removed |Added

 Status|NEW |RESOLVED
 Resolution|--- |FIXED

--- Comment #3 from Dlang Bot  ---
dlang/dmd pull request #10172 "fix handling of static impure functions nested
in pure functions (issues 20047 and 20050)" was merged into master:

- ccc7ed3d98f254b3326f0a7d06ebcb33f9038a1d by aG0aep6G:
  fix issue 20047 - call of static nested function ignores purity

https://github.com/dlang/dmd/pull/10172

--


[Issue 20047] call of static nested function ignores purity

2019-07-14 Thread d-bugmail--- via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=20047

Dlang Bot  changed:

   What|Removed |Added

   Keywords||pull

--- Comment #2 from Dlang Bot  ---
@aG0aep6G created dlang/dmd pull request #10172 "fix handling of static impure
functions nested in pure functions (issues 20047 and 20050)" fixing this issue:

- fix issue 20047 - call of static nested function ignores purity

https://github.com/dlang/dmd/pull/10172

--


[Issue 20047] call of static nested function ignores purity

2019-07-13 Thread d-bugmail--- via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=20047

--- Comment #1 from Mike Franklin  ---
This behavior was introduced in https://github.com/dlang/dmd/pull/4344 as a fix
to Issue 14039

--


[Issue 20047] call of static nested function ignores purity

2019-07-13 Thread d-bugmail--- via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=20047

Mike Franklin  changed:

   What|Removed |Added

 CC||slavo5...@yahoo.com
   See Also||https://issues.dlang.org/sh
   ||ow_bug.cgi?id=14039

--


[Issue 20047] New: call of static nested function ignores purity

2019-07-13 Thread d-bugmail--- via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=20047

  Issue ID: 20047
   Summary: call of static nested function ignores purity
   Product: D
   Version: D2
  Hardware: All
OS: All
Status: NEW
  Keywords: accepts-invalid, safe
  Severity: normal
  Priority: P1
 Component: dmd
  Assignee: nob...@puremagic.com
  Reporter: ag0ae...@gmail.com

Came up here: https://github.com/dlang/druntime/pull/2673

This compiles but shouldn't:


int* m;

int* impure_function() { return m; }
int* pure_function() pure
{
static int* bug() { return impure_function(); }
return bug(); /* Shouldn't compile. `bug` isn't pure. */
}

void main()
{
m = new int(42);
immutable int* i = pure_function();
assert(*i == 42); /* passes */
*m = 13;
assert(*i == 42); /* fails; immutable value has changed */
}


Also affects @safe functions.

--


Re: Purity of delegate-style toString

2018-05-06 Thread Q. Schroll via Digitalmars-d-learn

On Tuesday, 1 May 2018 at 12:03:15 UTC, ag0aep6g wrote:

On 05/01/2018 01:44 PM, Per Nordlöw wrote:
In which cases (if any) is it possible to make a 
delegate-style implementation of toString such as


     void toString(scope void delegate(const(char)[]) sink) 
const @trusted pure

     {
     // sink("...");
     // sink.formattedWrite!"..."(...);
     }

pure?


You have to mark `sink` as pure, too:

void toString(scope void delegate (const(char)[]) pure sink)
const @trusted pure

Then the toString method itself works, but it may not be 
callable by other code that wants to use an impure sink.


For example, `format` works, but `writeln` doesn't:


struct S
{
void toString(scope void delegate(const(char)[]) pure sink)
const @trusted pure
{
import std.format: formattedWrite;
sink("...");
sink.formattedWrite!"%s"(" ...");
}
}
void main()
{
import std.format: format;
import std.stdio: writeln;
writeln(format("%s", S())); /* Ok. Prints "... ...". */
writeln(S()); /* Nope. writeln would like to use an impure 
sink. */

}


By the way, you shouldn't mark toString as @trusted when `sink` 
is @system.


I had similar issue for opApply.

The generalized problem is, the attributes (pure, nothrow, @safe, 
@nogc) are too strong on functionals (i.e. functions taking 
function/delegate arguments). We could (and IMO should) weaken 
the attributes to mean: the same as always, *assuming all 
function/delegate arguments have it*.


Concrete example, say your `toString(scope void 
delegate(const(char)[]))` is conceptually pure, i.e. if `sink` is 
a pure function (by static typing), `toString(sink)` acts pure, 
and for impure `sink`, `toString(sink)` possibly impure. So 
purity of the functional `toString` depends on the purity of its 
arguments; that is very natural as most functionals call their 
parameters.


The current state makes attributes virtually useless for 
functionals. Often, toString can be templetized without drawback 
(except virtual functions), but opApply cannot. opApply must not 
be a template to enable type deduction for the variable.[1]


Making attributes act structurally has almost no consequences in 
terms of breakage; just more functions can be 
pure/nothrow/@nogc/@safe. It would make functionals 
impure/unsafe/..
that do not call their argument. The question is, in which 
contexts are they used and is it an issue -- is it a greater 
issue than this.


Complete example what the change would do:
Say you have

  void toString(scope void delegate(const(char)[]) sink) pure { 
sink("Example"); }


toString is a pure functional, so calling it is pure iff the 
argument itself is. The compiler statically knows if the argument 
is pure and can infer the purity of the expression.


[1] 
https://dlang.org/spec/statement.html#foreach_over_struct_and_classes
(We could define very general special cases where type deduction 
can be archived, e.g. opApply(DG : int delegate(Args))(DG).)


[Issue 8063] Purity of assert's second parameter

2018-05-05 Thread d-bugmail--- via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=8063

Oliver Rümpelein  changed:

   What|Removed |Added

 Status|NEW |RESOLVED
 CC||ol...@fg4f.de
 Resolution|--- |FIXED

--- Comment #2 from Oliver Rümpelein  ---
The output starting from 2.0.64 includes only the "Bad type size: 8"-message.
Resolving.

--


Re: Purity of delegate-style toString

2018-05-01 Thread Per Nordlöw via Digitalmars-d-learn

On Tuesday, 1 May 2018 at 12:03:15 UTC, ag0aep6g wrote:
By the way, you shouldn't mark toString as @trusted when `sink` 
is @system.


Thanks


Re: Purity of delegate-style toString

2018-05-01 Thread ag0aep6g via Digitalmars-d-learn

On 05/01/2018 01:44 PM, Per Nordlöw wrote:
In which cases (if any) is it possible to make a delegate-style 
implementation of toString such as


     void toString(scope void delegate(const(char)[]) sink) const 
@trusted pure

     {
     // sink("...");
     // sink.formattedWrite!"..."(...);
     }

pure?


You have to mark `sink` as pure, too:

void toString(scope void delegate (const(char)[]) pure sink)
const @trusted pure

Then the toString method itself works, but it may not be callable by 
other code that wants to use an impure sink.


For example, `format` works, but `writeln` doesn't:


struct S
{
void toString(scope void delegate(const(char)[]) pure sink)
const @trusted pure
{
import std.format: formattedWrite;
sink("...");
sink.formattedWrite!"%s"(" ...");
}
}
void main()
{
import std.format: format;
import std.stdio: writeln;
writeln(format("%s", S())); /* Ok. Prints "... ...". */
writeln(S()); /* Nope. writeln would like to use an impure sink. */
}


By the way, you shouldn't mark toString as @trusted when `sink` is @system.


Purity of delegate-style toString

2018-05-01 Thread Per Nordlöw via Digitalmars-d-learn
In which cases (if any) is it possible to make a delegate-style 
implementation of toString such as


void toString(scope void delegate(const(char)[]) sink) const 
@trusted pure

{
// sink("...");
// sink.formattedWrite!"..."(...);
}

pure?


[Issue 18590] New: nothrow constructor call still type-checks destructor for purity

2018-03-11 Thread d-bugmail--- via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=18590

  Issue ID: 18590
   Summary: nothrow constructor call still type-checks destructor
for purity
   Product: D
   Version: D2
  Hardware: All
OS: All
Status: NEW
  Severity: normal
  Priority: P2
 Component: dmd
  Assignee: nob...@puremagic.com
  Reporter: c...@dawg.eu

cat > bug.d << CODE
extern(C) int printf(const char*, ...);

struct F
{
static F create() pure nothrow
{
return F(1);
}

this(int) pure nothrow
{
}

~this()
{
printf("~this\n");
}
}
CODE
dmd -c bug

Error: pure function 'bug.F.create' cannot call impure function 'bug.F.~this'


Apparently happens because `F(1)` is lowered to `(tmp = F(1)),tmp` internally.
https://github.com/dlang/dmd/blob/93804714c4091a8d867c09ca7b5bf332acb34dfb/src/dmd/expression.d#L3931

--


[Issue 17442] regex purity issues

2017-09-08 Thread via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=17442

Dmitry Olshansky  changed:

   What|Removed |Added

   Assignee|nob...@puremagic.com|dmitry.o...@gmail.com

--


[Issue 7707] Purity inference fails when template used before it's defined

2017-06-25 Thread via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=7707

Vladimir Panteleev  changed:

   What|Removed |Added

 Status|NEW |RESOLVED
 CC||dlang-bugzilla@thecybershad
   ||ow.net
 Resolution|--- |INVALID

--- Comment #1 from Vladimir Panteleev  ---
This needs a self-contained test case.

Please reopen if you consider this issue still valid and can provide a
self-contained test case.

--


Re: purity question

2017-05-30 Thread H. S. Teoh via Digitalmars-d-learn
On Tue, May 30, 2017 at 11:10:19AM -0700, Jonathan M Davis via 
Digitalmars-d-learn wrote:
[...]
> Yeah, basically, D's pure was originally what is now sometimes called
> "strongly pure," which is quite close to functionally pure in that the
> same input results in the same output (it still allows alocating
> memory and returning it though, so you can have equal but different
> objects if the same function is called multiple times with the same
> arguments in different contexts where the compiler doesn't memoize
> it). However, pure was so restrictive as to be borderline useless,
> because it could only pass types that were immutable or implicitly
> convertible to immutable. So, it was expanded to include any function
> which could not access global, mutable state, because such functions
> can be called from a "strongly" pure function without violating the
> strongly pure function's guarantees - and thus "weakly" pure functions
> were born, making it so that D's pure is really more like @noglobal
> than functionally pure. It's a critical building block in functional
> purity, and strongly pure functions still get all of the benefits that
> they got before (and now they can actually be useful, because they can
> call many more functions), but _most_ pure functions are weakly pure
> and thus don't get the full benefits of functional purity - and that's
> why some folks like Ketmar tend to get annoyed with D's pure. But the
> way it is is actually quite useful even if it's initially confusing.
> And even when there are no strongly pure functions in your program,
> knowing that a function cannot access global variables except through
> its arguments means a lot in and of itself.
[...]

In retrospect, we could have named "weakly pure" something like
@noglobal, and "strongly pure" as pure.

But be that as it may, I think D's pure system is actually extremely
ingenious.  Look at it this way: in the classical sense of functional
purity, which is what you get in (pure) functional languages, it can get
quite difficult to implement the functionality you want, because the
language enforces that every primitive you use in your implementation
must be pure.  The reasoning is that if you're only allowed to use pure
primitives, then the resulting function is guaranteed to be pure.  It's
nice and simple. However, it's also rather cumbersome, especially in the
context of an imperative language like D.

For example, in a functional language you cannot assign new values to
variables, and you cannot write for-loops, because the loop index is not
allowed to mutate. You cannot mutate anything, because mutation makes
the code impure. So instead of straightforward loops, you need to resort
to things like tail recursion; instead of mutation, you need to use
monads, and so on.  I'm not saying this is a bad thing, but it's just
cumbersome because you, the programmer, cannot simply implement a
function with a straightforward algorithm, but you have to work harder
to express the algorithm in functional terms using recursion and other
functional (pure) constructs.

The first insight in D's purity system is the observation that, given
some function f(), from the caller's POV all they care about is that (1)
the function always returns the same value given the same arguments, and
(2) there are no visible side-effects.  Point (2) is where the insight
lies: in a sense, it *doesn't matter* if f() does all kinds of impure
stuff in order to compute its return value, as long as the outside world
cannot see it.  It may be internally impure, but externally, as far as
the outside world is concerned, it's pure, because the caller can't tell
the difference.  So D allows things like variables, mutation, for-loops,
and all kinds of stuff inside (strongly) pure functions -- as long as
no global state is touched, and as long as the function arguments aren't
modified (from the caller's POV), f() is pure.  In other words, as long
as f() keeps its dirty laundry to itself and leaves the outside world
untouched, it is externally pure, even if it's internally impure.

The next insight is this: suppose f() calls g(), and g() is impure.  In
the traditional functional language purity system, this is outright
illegal, because a pure function, by definition, cannot call an impure
function, otherwise it is itself impure.  However, suppose g() does not
modify any global state.  It *may* modify stuff through its arguments --
which makes it impure.  But if f() is not allowed to modify its
arguments and has no global state, then at worst, it can only pass its
internal, non-global state to g(). Therefore, it is impossible for g()
to reach global state through its arguments. Thus, f()'s (external)
purity is preserved.

Note the fine distinction here, that g()'s external purity is keyed on
being called from inside a strongly-pure function f(). If f

Re: purity question

2017-05-30 Thread Jonathan M Davis via Digitalmars-d-learn
On Tuesday, May 30, 2017 16:54:13 ag0aep6g via Digitalmars-d-learn wrote:
> On 05/30/2017 11:12 AM, Rene Zwanenburg wrote:
> > If malloc were marked as pure, wouldn't that mean it must return the
> > same pointer every time you call it with the same size?
>
> D's `pure` mostly means: "does not access mutable state, and does not do
> input/output".
>
> There is never a requirement that a function must return the same value
> for the same input. But a compiler is allowed to memoize the result of a
> `pure` function when it has no mutable indirections in its parameter and
> return types. Such a function is "strongly pure".
>
> When there are mutable indirections, the function is "weakly pure".
> Weakly pure functions are not assumed to be memoizable, but "weakly
> pure" still has meaning:
>
> * Can call weakly pure functions from strongly pure ones.
>
> * When a weakly pure function has mutable indirections in the return
> type but not in the parameters (like malloc), then it must be returning
> freshly allocated memory. That means, the result cannot be referenced
> from anywhere else. So it can be converted to const/immutable/shared
> implicitly. The spec calls that a "pure factory function".
>
> Repeating Biotronic's links, the spec and David Nadlinger's article are
> the go-to resources for D's take on purity:
>
> https://dlang.org/spec/function.html#pure-functions
> http://klickverbot.at/blog/2012/05/purity-in-d/

Yeah, basically, D's pure was originally what is now sometimes called
"strongly pure," which is quite close to functionally pure in that the same
input results in the same output (it still allows alocating memory and
returning it though, so you can have equal but different objects if the same
function is called multiple times with the same arguments in different
contexts where the compiler doesn't memoize it). However, pure was so
restrictive as to be borderline useless, because it could only pass types
that were immutable or implicitly convertible to immutable. So, it was
expanded to include any function which could not access global, mutable
state, because such functions can be called from a "strongly" pure function
without violating the strongly pure function's guarantees - and thus
"weakly" pure functions were born, making it so that D's pure is really more
like @noglobal than functionally pure. It's a critical building block in
functional purity, and strongly pure functions still get all of the benefits
that they got before (and now they can actually be useful, because they can
call many more functions), but _most_ pure functions are weakly pure and
thus don't get the full benefits of functional purity - and that's why some
folks like Ketmar tend to get annoyed with D's pure. But the way it is is
actually quite useful even if it's initially confusing. And even when there
are no strongly pure functions in your program, knowing that a function
cannot access global variables except through its arguments means a lot in
and of itself.

- Jonathan M Davis



Re: purity question

2017-05-30 Thread ag0aep6g via Digitalmars-d-learn

On 05/30/2017 11:12 AM, Rene Zwanenburg wrote:
If malloc were marked as pure, wouldn't that mean it must return the 
same pointer every time you call it with the same size?


D's `pure` mostly means: "does not access mutable state, and does not do 
input/output".


There is never a requirement that a function must return the same value 
for the same input. But a compiler is allowed to memoize the result of a 
`pure` function when it has no mutable indirections in its parameter and 
return types. Such a function is "strongly pure".


When there are mutable indirections, the function is "weakly pure". 
Weakly pure functions are not assumed to be memoizable, but "weakly 
pure" still has meaning:


* Can call weakly pure functions from strongly pure ones.

* When a weakly pure function has mutable indirections in the return 
type but not in the parameters (like malloc), then it must be returning 
freshly allocated memory. That means, the result cannot be referenced 
from anywhere else. So it can be converted to const/immutable/shared 
implicitly. The spec calls that a "pure factory function".


Repeating Biotronic's links, the spec and David Nadlinger's article are 
the go-to resources for D's take on purity:


https://dlang.org/spec/function.html#pure-functions
http://klickverbot.at/blog/2012/05/purity-in-d/


Re: purity question

2017-05-30 Thread Biotronic via Digitalmars-d-learn

On Tuesday, 30 May 2017 at 13:45:07 UTC, Rene Zwanenburg wrote:

On Tuesday, 30 May 2017 at 11:34:52 UTC, ketmar wrote:
If malloc were marked as pure, wouldn't that mean it must 
return the same pointer every time you call it with the same 
size?


of course. but D "pure" is not what other world knows as 
"pure". we love to mess with words.


Well, there's the ability to modify non-const reference 
parameters from a pure function, but that's not applicable to 
malloc. Are there any other special rules?


The rules[0] are:

0) Can't call functions not marked pure.
1) Can't touch anything mutable that's not explicitly passed to 
the pure function.
1b) Except GC internal state - i.e. memory can be allocated via 
the GC.

1c) And floating-point exception flags and modes.
2) Can't do I/O (can be seen as a special case of 1 and 0).

There's a few more details, but that's the important stuff.

For a good article on the subject, I recommend David Nadlinger's 
Purity in D:


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

[0]: https://dlang.org/spec/function.html#pure-functions


Re: purity question

2017-05-30 Thread ketmar via Digitalmars-d-learn

Rene Zwanenburg wrote:


On Tuesday, 30 May 2017 at 11:34:52 UTC, ketmar wrote:
If malloc were marked as pure, wouldn't that mean it must return the 
same pointer every time you call it with the same size?


of course. but D "pure" is not what other world knows as "pure". we love 
to mess with words.


Well, there's the ability to modify non-const reference parameters from a 
pure function, but that's not applicable to malloc. Are there any other 
special rules?


"pure" methods can mutate object state.


Re: purity question

2017-05-30 Thread Rene Zwanenburg via Digitalmars-d-learn

On Tuesday, 30 May 2017 at 11:34:52 UTC, ketmar wrote:
If malloc were marked as pure, wouldn't that mean it must 
return the same pointer every time you call it with the same 
size?


of course. but D "pure" is not what other world knows as 
"pure". we love to mess with words.


Well, there's the ability to modify non-const reference 
parameters from a pure function, but that's not applicable to 
malloc. Are there any other special rules?


Re: purity question

2017-05-30 Thread ketmar via Digitalmars-d-learn

Rene Zwanenburg wrote:


On Monday, 29 May 2017 at 01:36:24 UTC, Jonathan M Davis wrote:

A simple example: anything that has a malloc/free pair.


Yeah, if you do it right, you should be fine, but you have to do it 
right, and it's very easy to miss some detail that makes it wrong to 
insist to the compiler that what you're doing is pure.


If malloc were marked as pure, wouldn't that mean it must return the same 
pointer every time you call it with the same size?


of course. but D "pure" is not what other world knows as "pure". we love to 
mess with words.


Re: purity question

2017-05-30 Thread Rene Zwanenburg via Digitalmars-d-learn

On Monday, 29 May 2017 at 01:36:24 UTC, Jonathan M Davis wrote:

A simple example: anything that has a malloc/free pair.


Yeah, if you do it right, you should be fine, but you have to 
do it right, and it's very easy to miss some detail that makes 
it wrong to insist to the compiler that what you're doing is 
pure.


If malloc were marked as pure, wouldn't that mean it must return 
the same pointer every time you call it with the same size?


Re: purity question

2017-05-29 Thread Seb via Digitalmars-d-learn

On Monday, 29 May 2017 at 08:49:07 UTC, ketmar wrote:

Brad Roberts wrote:

libraries that themselves aren't marked pure, there's a real 
need for escape hatches.  A simple example: anything that has 
a malloc/free pair.


they aren't pure. it is a sad misconception about purity, which 
D makes even more complex by allowing to mark, for example, 
*setters* as pure. but still, `malloc()` and `free()` aren't 
pure. and while various functions in std.math, for example, are 
marked `pure`, they aren't too.


There is pureMalloc since 2.074.0 (it was never announced):

https://github.com/dlang/druntime/pull/1746

However, without a pureFree it's rather limited in usefulness and 
needs to be workaround in real life:


https://github.com/dlang/druntime/pull/1718


Re: purity question

2017-05-29 Thread Ola Fosheim Grøstad via Digitalmars-d-learn

On Monday, 29 May 2017 at 11:25:06 UTC, ketmar wrote:
almost all of them, 'cause they depends on FPU rounding 
settings.


Well, yeah. IIRC contemporary floating point machine language 
instructions allow embedding of rounding mode into the 
instruction.


A pity languages are lagging behind, stuck in the 1980s...

WebAssembly is locking it to the default IEEE754-2008 
round-to-even. Which is reasonable as they aim for max 
portability, albeit a bit limiting.





Re: purity question

2017-05-29 Thread ketmar via Digitalmars-d-learn

Ola Fosheim Grøstad wrote:


On Monday, 29 May 2017 at 08:49:07 UTC, ketmar wrote:
pure. and while various functions in std.math, for example, are marked 
`pure`, they aren't too.


Out of curiosity, which functions in std.math aren't "pure" in the D 
sense?


almost all of them, 'cause they depends on FPU rounding settings.


Re: purity question

2017-05-29 Thread Ola Fosheim Grøstad via Digitalmars-d-learn

On Monday, 29 May 2017 at 08:49:07 UTC, ketmar wrote:
pure. and while various functions in std.math, for example, are 
marked `pure`, they aren't too.


Out of curiosity, which functions in std.math aren't "pure" in 
the D sense?




Re: purity question

2017-05-29 Thread ketmar via Digitalmars-d-learn

Brad Roberts wrote:

libraries that themselves aren't marked pure, there's a real need for 
escape hatches.  A simple example: anything that has a malloc/free pair.


they aren't pure. it is a sad misconception about purity, which D makes 
even more complex by allowing to mark, for example, *setters* as pure. but 
still, `malloc()` and `free()` aren't pure. and while various functions in 
std.math, for example, are marked `pure`, they aren't too.


[Issue 17442] regex purity issues

2017-05-28 Thread via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=17442

--- Comment #2 from Brad Roberts  ---
That's a tiny tip of a much larger iceberg.

--


Re: purity question

2017-05-28 Thread Seb via Digitalmars-d-learn

On Sunday, 28 May 2017 at 23:49:16 UTC, Brad Roberts wrote:
Is there a mechanism for declaring something pure when it's 
built from parts which individually aren't?


string foo(string s)
{
// do something arbitrarily complex with s that doesn't 
touch globals or change global state except possibly state of 
the heap or gc

return s;
}


Ali has answered this two years ago:

http://www.digitalmars.com/d/archives/digitalmars/D/learn/using_memset_withing_a_pure_function_74629.html#N74631

Copying for convenience:


If you want to live dangerously, you can use assumePure, which is 
found

in one of the unittest blocks of std.traits:

import std.traits;

auto assumePure(T)(T t)
if (isFunctionPointer!T || isDelegate!T)
{
 enum attrs = functionAttributes!T | FunctionAttribute.pure_;
 return cast(SetFunctionAttributes!(T, functionLinkage!T, 
attrs)) t;

}

int i = 0;

void foo()
{
 ++i;// foo accesses mutable module-level data
}

void bar() pure
{
 auto pureFoo = assumePure();
 pureFoo();// <-- pure function is calling impure function
}

void main()
{
 assert(i == 0);
 bar();
 assert(i == 1);// mutation through a pure function
}

It also came up in other discussions (the keyword is 
`assumePure`), e.g.

- http://forum.dlang.org/post/hpxxghbiomtitrmwe...@forum.dlang.org
- http://forum.dlang.org/post/nfhqvffqtkfsxjewg...@forum.dlang.org


[Issue 17442] regex purity issues

2017-05-28 Thread via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=17442

uplink.co...@googlemail.com changed:

   What|Removed |Added

 CC||uplink.co...@googlemail.com

--- Comment #1 from uplink.co...@googlemail.com ---
The reason for this is that regex calls malloc

--


Re: purity question

2017-05-28 Thread Jonathan M Davis via Digitalmars-d-learn
On Sunday, May 28, 2017 18:46:22 Brad Roberts via Digitalmars-d-learn wrote:
> Again, of course it's possible to do it wrong.  Escape hatches are like
> that.  And of course things are being worked on and improved, I'm one of
> the ones that's done a good bit of that at various points in time.  I'm
> really not seeking a lesson or lecture in why it's dangerous.

Sorry, if I'm coming across like I'm lecturing you. I'm not trying to. I'm
trying to be clear about the situation, and because this is on D.Learn, with
something like this, I don't want to show how to get around the issue
without clearly warning about the risks, because even if you know exactly
what you're doing when casting to get around purity problems, many others
reading this list will not.

- Jonathan M Davis



Re: purity question

2017-05-28 Thread Brad Roberts via Digitalmars-d-learn

On 5/28/2017 6:46 PM, Brad Roberts via Digitalmars-d-learn wrote:


Here's the bug that I'm digging into today, a clear example of an api 
that _should_ be pure, but based on the implementation is rather 
difficult for the compiler to infer.


https://issues.dlang.org/show_bug.cgi?id=17442


Re: purity question

2017-05-28 Thread Brad Roberts via Digitalmars-d-learn

On 5/28/2017 6:36 PM, Jonathan M Davis via Digitalmars-d-learn wrote:

On Sunday, May 28, 2017 17:53:25 Brad Roberts via Digitalmars-d-learn wrote:

On 5/28/2017 5:34 PM, Jonathan M Davis via Digitalmars-d-learn wrote:

On Sunday, May 28, 2017 16:49:16 Brad Roberts via Digitalmars-d-learn

wrote:

Is there a mechanism for declaring something pure when it's built from
parts which individually aren't?

string foo(string s)
{

   // do something arbitrarily complex with s that doesn't touch

globals or change global state except possibly state of the heap or gc

   return s;

}

 you can cast 

Ok, so there essentially isn't.  I'm well aware of the risks of lying to
the compiler, but it's also not sufficiently smart to unravel complex
code.  Combined with there being interesting parts of the standard
libraries that themselves aren't marked pure, there's a real need for
escape hatches.

Well, the big thing is that there are a number of functions in Phobos that
need to have someone go over them and fix them so that they are inferred to
be pure when they should be. Some work has been done in that area, and the
situation is certainly better than it once was, but not enough work has been
done to make it so that we can at all reasonably that everything in Phobos
that should be pure is and what isn't shouldn't be.


A simple example: anything that has a malloc/free pair.

Yeah, if you do it right, you should be fine, but you have to do it right,
and it's very easy to miss some detail that makes it wrong to insist to the
compiler that what you're doing is pure. So, arguably, having anything more
user-friendly than a cast is pretty dangerous. Having folks slap something
like @assume_pure on things (if there were such an attribute) could be
pretty risky. We already have enough trouble with @trusted on that front.
Ultimately, we want to be in a position where needing to get around pure is
very rare, and in most cases, I'd just tell folks to give up on pure on that
piece of code rather than trying to hack it into working.

- Jonathan M Davis


Again, of course it's possible to do it wrong.  Escape hatches are like 
that.  And of course things are being worked on and improved, I'm one of 
the ones that's done a good bit of that at various points in time.  I'm 
really not seeking a lesson or lecture in why it's dangerous.


Here's the bug that I'm digging into today, a clear example of an api 
that _should_ be pure, but based on the implementation is rather 
difficult for the compiler to infer.


Re: purity question

2017-05-28 Thread Jonathan M Davis via Digitalmars-d-learn
On Sunday, May 28, 2017 18:39:02 Brad Roberts via Digitalmars-d-learn wrote:
> On 5/28/2017 6:27 PM, Jonathan M Davis via Digitalmars-d-learn wrote:
> > There was a whole discussion or 3 is PRs about making malloc pure, and
> > IIRC, it was done and then decided that it wasn't safe to do some for
> > one reason or another (IIRC, it had to do with what would happen when
> > calls were elided, because the caller was strongly pure, but I'm not
> > sure). So, I'd be _very_ careful about deciding that it was safe to
> > call malloc in pure code. I expect that it's just fine in some
> > contexts, but it's easy enough to screw up and mark something as pure
> > when it really shouldn't be because of some detail you missed that you
> > should be _really_ careful about decided to cast to pure.
>
> That's one reason I explicitly referenced malloc/free pairs.  It's a lot
> easier to be sure that those together aren't violating purity.

Agreed. But it's the intricacies like that which make having a clean
backdoor for pure a bit dangerous, much as it would be nice when you
actually need to do it and know what you're doing well enough to get it
right.

- Jonathan M Davis



Re: purity question

2017-05-28 Thread Brad Roberts via Digitalmars-d-learn

On 5/28/2017 6:27 PM, Jonathan M Davis via Digitalmars-d-learn wrote:

On Monday, May 29, 2017 01:01:46 Stefan Koch via Digitalmars-d-learn wrote:

On Monday, 29 May 2017 at 00:53:25 UTC, Brad Roberts wrote:

On 5/28/2017 5:34 PM, Jonathan M Davis via Digitalmars-d-learn

wrote:

On Sunday, May 28, 2017 16:49:16 Brad Roberts via

Digitalmars-d-learn wrote:

Is there a mechanism for declaring something pure when it's
built from
parts which individually aren't?

string foo(string s)
{

   // do something arbitrarily complex with s that doesn't

touch
globals or change global state except possibly state of the
heap or gc

   return s;

}

 you can cast 

Ok, so there essentially isn't.  I'm well aware of the risks of
lying to the compiler, but it's also not sufficiently smart to
unravel complex code.  Combined with there being interesting
parts of the standard libraries that themselves aren't marked
pure, there's a real need for escape hatches.  A simple
example: anything that has a malloc/free pair.

There is

void[] myPureMalloc(uint size) pure @trusted nothrow @nogc
{
 alias pure_malloc_t = pure nothrow void* function(size_t size);
 return (cast(pure_malloc_t)malloc)(size)[0 .. size];
}

There was a whole discussion or 3 is PRs about making malloc pure, and IIRC,
it was done and then decided that it wasn't safe to do some for one reason
or another (IIRC, it had to do with what would happen when calls were
elided, because the caller was strongly pure, but I'm not sure). So, I'd be
_very_ careful about deciding that it was safe to call malloc in pure code.
I expect that it's just fine in some contexts, but it's easy enough to screw
up and mark something as pure when it really shouldn't be because of some
detail you missed that you should be _really_ careful about decided to cast
to pure.

- Jonathan M Davis


That's one reason I explicitly referenced malloc/free pairs.  It's a lot 
easier to be sure that those together aren't violating purity.


Re: purity question

2017-05-28 Thread Jonathan M Davis via Digitalmars-d-learn
On Sunday, May 28, 2017 17:53:25 Brad Roberts via Digitalmars-d-learn wrote:
> On 5/28/2017 5:34 PM, Jonathan M Davis via Digitalmars-d-learn wrote:
> > On Sunday, May 28, 2017 16:49:16 Brad Roberts via Digitalmars-d-learn 
wrote:
> >> Is there a mechanism for declaring something pure when it's built from
> >> parts which individually aren't?
> >>
> >> string foo(string s)
> >> {
> >>
> >>   // do something arbitrarily complex with s that doesn't touch
> >>
> >> globals or change global state except possibly state of the heap or gc
> >>
> >>   return s;
> >>
> >> }
> >
> >  you can cast 
>
> Ok, so there essentially isn't.  I'm well aware of the risks of lying to
> the compiler, but it's also not sufficiently smart to unravel complex
> code.  Combined with there being interesting parts of the standard
> libraries that themselves aren't marked pure, there's a real need for
> escape hatches.

Well, the big thing is that there are a number of functions in Phobos that
need to have someone go over them and fix them so that they are inferred to
be pure when they should be. Some work has been done in that area, and the
situation is certainly better than it once was, but not enough work has been
done to make it so that we can at all reasonably that everything in Phobos
that should be pure is and what isn't shouldn't be.

> A simple example: anything that has a malloc/free pair.

Yeah, if you do it right, you should be fine, but you have to do it right,
and it's very easy to miss some detail that makes it wrong to insist to the
compiler that what you're doing is pure. So, arguably, having anything more
user-friendly than a cast is pretty dangerous. Having folks slap something
like @assume_pure on things (if there were such an attribute) could be
pretty risky. We already have enough trouble with @trusted on that front.
Ultimately, we want to be in a position where needing to get around pure is
very rare, and in most cases, I'd just tell folks to give up on pure on that
piece of code rather than trying to hack it into working.

- Jonathan M Davis



Re: purity question

2017-05-28 Thread Jonathan M Davis via Digitalmars-d-learn
On Monday, May 29, 2017 01:01:46 Stefan Koch via Digitalmars-d-learn wrote:
> On Monday, 29 May 2017 at 00:53:25 UTC, Brad Roberts wrote:
> > On 5/28/2017 5:34 PM, Jonathan M Davis via Digitalmars-d-learn
> >
> > wrote:
> >> On Sunday, May 28, 2017 16:49:16 Brad Roberts via
> >>
> >> Digitalmars-d-learn wrote:
> >>> Is there a mechanism for declaring something pure when it's
> >>> built from
> >>> parts which individually aren't?
> >>>
> >>> string foo(string s)
> >>> {
> >>>
> >>>   // do something arbitrarily complex with s that doesn't
> >>>
> >>> touch
> >>> globals or change global state except possibly state of the
> >>> heap or gc
> >>>
> >>>   return s;
> >>>
> >>> }
> >>
> >>  you can cast 
> >
> > Ok, so there essentially isn't.  I'm well aware of the risks of
> > lying to the compiler, but it's also not sufficiently smart to
> > unravel complex code.  Combined with there being interesting
> > parts of the standard libraries that themselves aren't marked
> > pure, there's a real need for escape hatches.  A simple
> > example: anything that has a malloc/free pair.
>
> There is
>
> void[] myPureMalloc(uint size) pure @trusted nothrow @nogc
> {
> alias pure_malloc_t = pure nothrow void* function(size_t size);
> return (cast(pure_malloc_t)malloc)(size)[0 .. size];
> }

There was a whole discussion or 3 is PRs about making malloc pure, and IIRC,
it was done and then decided that it wasn't safe to do some for one reason
or another (IIRC, it had to do with what would happen when calls were
elided, because the caller was strongly pure, but I'm not sure). So, I'd be
_very_ careful about deciding that it was safe to call malloc in pure code.
I expect that it's just fine in some contexts, but it's easy enough to screw
up and mark something as pure when it really shouldn't be because of some
detail you missed that you should be _really_ careful about decided to cast
to pure.

- Jonathan M Davis



Re: purity question

2017-05-28 Thread Era Scarecrow via Digitalmars-d-learn

On Monday, 29 May 2017 at 01:12:53 UTC, Era Scarecrow wrote:

...


 Hmm didn't notice the post had split. Otherwise i wouldn't have 
replied... That and thinking about the GC state (outside of 
allocating memory)...


Re: purity question

2017-05-28 Thread Era Scarecrow via Digitalmars-d-learn

On Sunday, 28 May 2017 at 23:49:16 UTC, Brad Roberts wrote:
// do something arbitrarily complex with s that doesn't 
touch globals or change global state except possibly state of 
the heap or gc


 Sounds like the basic definition of pure to me; At least in 
regards to D. Memory allocation which is a system call, doesn't 
actually break purity. Then again if you were worried about not 
using the gc, there's the newer nogc property.


[quote]
 TDPL pg. 165: 5.11.1 Pure functions

 In D, a function is considered pure if returning a result is 
it's only effect and the result depends only on the function's 
arguments.

[/quote]


Re: purity question

2017-05-28 Thread Stefan Koch via Digitalmars-d-learn

On Monday, 29 May 2017 at 01:01:46 UTC, Stefan Koch wrote:


There is


void[] myPureMalloc(uint size) pure @trusted nothrow @nogc
{
   import core.stdc.stdlib : malloc;
   alias pure_malloc_t = @nogc pure nothrow void* function(size_t 
size);

   return (cast(pure_malloc_t))(size)[0 .. size];
}

This is the fixed version.


Re: purity question

2017-05-28 Thread Brad Roberts via Digitalmars-d-learn

On 5/28/2017 6:01 PM, Stefan Koch via Digitalmars-d-learn wrote:

On Monday, 29 May 2017 at 00:53:25 UTC, Brad Roberts wrote:

On 5/28/2017 5:34 PM, Jonathan M Davis via Digitalmars-d-learn wrote:
On Sunday, May 28, 2017 16:49:16 Brad Roberts via 
Digitalmars-d-learn wrote:

Is there a mechanism for declaring something pure when it's built from
parts which individually aren't?

string foo(string s)
{
  // do something arbitrarily complex with s that doesn't touch
globals or change global state except possibly state of the heap or gc
  return s;
}

 you can cast 



Ok, so there essentially isn't.  I'm well aware of the risks of lying 
to the compiler, but it's also not sufficiently smart to unravel 
complex code.  Combined with there being interesting parts of the 
standard libraries that themselves aren't marked pure, there's a real 
need for escape hatches.  A simple example: anything that has a 
malloc/free pair.


There is

void[] myPureMalloc(uint size) pure @trusted nothrow @nogc
{
   alias pure_malloc_t = pure nothrow void* function(size_t size);
   return (cast(pure_malloc_t)malloc)(size)[0 .. size];
}


That's still a cast.  It's a nice way to isolate the cast, but it's 
clearly still there.  And as I said, that's just one simple example.


Re: purity question

2017-05-28 Thread Stefan Koch via Digitalmars-d-learn

On Monday, 29 May 2017 at 00:53:25 UTC, Brad Roberts wrote:
On 5/28/2017 5:34 PM, Jonathan M Davis via Digitalmars-d-learn 
wrote:
On Sunday, May 28, 2017 16:49:16 Brad Roberts via 
Digitalmars-d-learn wrote:
Is there a mechanism for declaring something pure when it's 
built from

parts which individually aren't?

string foo(string s)
{
  // do something arbitrarily complex with s that doesn't 
touch
globals or change global state except possibly state of the 
heap or gc

  return s;
}

 you can cast 



Ok, so there essentially isn't.  I'm well aware of the risks of 
lying to the compiler, but it's also not sufficiently smart to 
unravel complex code.  Combined with there being interesting 
parts of the standard libraries that themselves aren't marked 
pure, there's a real need for escape hatches.  A simple 
example: anything that has a malloc/free pair.


There is

void[] myPureMalloc(uint size) pure @trusted nothrow @nogc
{
   alias pure_malloc_t = pure nothrow void* function(size_t size);
   return (cast(pure_malloc_t)malloc)(size)[0 .. size];
}


Re: purity question

2017-05-28 Thread Brad Roberts via Digitalmars-d-learn

On 5/28/2017 5:34 PM, Jonathan M Davis via Digitalmars-d-learn wrote:

On Sunday, May 28, 2017 16:49:16 Brad Roberts via Digitalmars-d-learn wrote:

Is there a mechanism for declaring something pure when it's built from
parts which individually aren't?

string foo(string s)
{
  // do something arbitrarily complex with s that doesn't touch
globals or change global state except possibly state of the heap or gc
  return s;
}

 you can cast 



Ok, so there essentially isn't.  I'm well aware of the risks of lying to 
the compiler, but it's also not sufficiently smart to unravel complex 
code.  Combined with there being interesting parts of the standard 
libraries that themselves aren't marked pure, there's a real need for 
escape hatches.  A simple example: anything that has a malloc/free pair.


Re: purity question

2017-05-28 Thread Jonathan M Davis via Digitalmars-d-learn
On Sunday, May 28, 2017 16:49:16 Brad Roberts via Digitalmars-d-learn wrote:
> Is there a mechanism for declaring something pure when it's built from
> parts which individually aren't?
>
> string foo(string s)
> {
>  // do something arbitrarily complex with s that doesn't touch
> globals or change global state except possibly state of the heap or gc
>  return s;
> }

Either everything the function is doing is pure, or it can't be pure without
cheating, and cheating is usually a bad idea. There is no @trusted
equivalent for pure. Now, if you're absolutely sure that the function
doesn't do anything that's actually going to run afoul of pure and what the
compiler will assume about pure functions, but it's using stuff that wasn't
properly marked as pure, or does something that can't be marked as pure for
some reason but in this context would actually be fine, you can cast.

For instance, std.datetime's LocalTime is a singleton which gets the
timezone conversion from the system. Its operations can't be pure, but it
can be constructed as pure, and because it's a singleton, it will return the
same instance every time. Originally, a static constructor was used to
initialize the singleton (which therefore worked great with pure), but
because of circular dependency pain with static constructors, we had to get
rid of the static constructors in std.datetime. The solution was to move the
initialization into another function which was not pure, and then when we
call it from theh singleton function, we cast it to pure:

static immutable(LocalTime) opCall() @trusted pure nothrow
{
alias FuncType = @safe pure nothrow immutable(LocalTime) function();
return (cast(FuncType))();
}

static immutable(LocalTime) singleton() @trusted
{
import core.stdc.time : tzset;
import std.concurrency : initOnce;
static instance = new immutable(LocalTime)();
static shared bool guard;
initOnce!guard({tzset(); return true;}());
return instance;
}

Now, in the vast majority of cases, I would strongly advise against cheating
in this manner, because you need to be absolutely sure that you're not
actually violating pure (particularly what the compiler will assume about
pure) by what you're doing, and usually what it comes down to is that
something that your function is calling needs to be fixed so that it can be
inferred as pure, or it simply needs to be marked as pure. Casting is a
horrible hack that should only be used as a last resort and only when you're
100% sure that it's fine. However, you _can_ use casting as a backdoor if
you really have to.

- Jonathan M Davis



purity question

2017-05-28 Thread Brad Roberts via Digitalmars-d-learn
Is there a mechanism for declaring something pure when it's built from 
parts which individually aren't?


string foo(string s)
{
// do something arbitrarily complex with s that doesn't touch 
globals or change global state except possibly state of the heap or gc

return s;
}


[Issue 17442] New: regex purity issues

2017-05-27 Thread via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=17442

  Issue ID: 17442
   Summary: regex purity issues
   Product: D
   Version: D2
  Hardware: All
OS: All
Status: NEW
  Severity: normal
  Priority: P1
 Component: phobos
  Assignee: nob...@puremagic.com
  Reporter: bra...@puremagic.com

At least two of the functions in std.regex that ought to be usable in a pure
context aren't.  I suspect there's a broader issue with that subsystem, but
haven't investigated.

-
module bugregex;

string unifyNewLine(string str) pure
{
import std.regex;

return std.regex.replace(str, regex(`\r\n|\r|\n`, "g"), "\n");
}
-

$ dmd -c -ofbugregex.o bugregex.d
bugregex.d(7): Error: pure function 'bugregex.unifyNewLine' cannot call impure
function 'std.regex.regex!string.regex'
bugregex.d(7): Error: pure function 'bugregex.unifyNewLine' cannot call impure
function 'std.regex.replace!(match, string, char, Regex!char).replace'

--


[Issue 11047] UDA + getAttributes bypass purity/safety check

2016-10-01 Thread via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=11047

--- Comment #4 from github-bugzi...@puremagic.com ---
Commits pushed to stable at https://github.com/dlang/dmd

https://github.com/dlang/dmd/commit/55bd78ded94a1f40ee80c4e42791f216e5d58c41
fix Issue 11047 - UDA + getAttributes bypass purity/safety check

https://github.com/dlang/dmd/commit/d1c3b6a1eab3347d9b6eb832b99ee45f70bd3702
Merge pull request #5863 from WalterBright/fix11047

--


Re: thisExePath purity

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

On 9/20/16 3:42 PM, crimaniak wrote:

On Tuesday, 20 September 2016 at 13:35:27 UTC, Steven Schveighoffer wrote:

Note that if you don't import the module that contains the static
ctor, it should be trimmed by the linker.

 Let's imagine linker can trim even imported module with static ctor, if
we have something like:

immutable string executablePath;

@local shared static this()
{
import std.file : thisExePath;
executablePath = thisExePath();
}

and there is no references to executablePath. Here it would be useful, I
think. Attribute @local (or @module? the name does not matter) mean this
block used only to init other symbols in this module so it can be
skipped if no references.


But if this is all that is in the module, why import the module if you 
aren't going to use any of it?



I would absolutely caution you from putting static this() inside any
template. Unfortunately, due to the way D generates these static
constructors, any module that uses staticMemoize, or *imports a module
that uses it*, will be marked as having a static constructor, and will
potentially create cycles.

 Please be more detail about cycles. Do you mean something like this?
https://isocpp.org/wiki/faq/ctors#static-init-order


Sort of, I mean this: 
https://dlang.org/spec/module.html#order_of_static_ctor


In other words, because the template has a static ctor in it, just 
instantiating it in your unrelated module puts static ctor in your 
module. And then cycles can appear that you wouldn't expect to happen.


-Steve





Re: thisExePath purity

2016-09-20 Thread crimaniak via Digitalmars-d-learn
On Tuesday, 20 September 2016 at 13:35:27 UTC, Steven 
Schveighoffer wrote:
Yes, but if your code does instantiate it, it is called, even 
if you don't ever call the function that calls it.
Yes, it's not ideal but better then just global variable and 
static block - it's called in any case, even if variable is not 
used at all.


Ideal solution will be something like attribute for static block 
leading to make it optional, so module will not be included if no 
usage of other symbols found. But I don't know way how to make it 
so template is used.


Note that if you don't import the module that contains the 
static ctor, it should be trimmed by the linker.
 Let's imagine linker can trim even imported module with static 
ctor, if we have something like:


immutable string executablePath;

@local shared static this()
{
import std.file : thisExePath;
executablePath = thisExePath();
}

and there is no references to executablePath. Here it would be 
useful, I think. Attribute @local (or @module? the name does not 
matter) mean this block used only to init other symbols in this 
module so it can be skipped if no references.



I would absolutely caution you from putting static this() 
inside any template. Unfortunately, due to the way D generates 
these static constructors, any module that uses staticMemoize, 
or *imports a module that uses it*, will be marked as having a 
static constructor, and will potentially create cycles.
 Please be more detail about cycles. Do you mean something like 
this? https://isocpp.org/wiki/faq/ctors#static-init-order




Re: thisExePath purity

2016-09-20 Thread crimaniak via Digitalmars-d-learn

On Tuesday, 20 September 2016 at 09:14:39 UTC, Marc Schütz wrote:

Have a look at `std.concurrency.initOnce`:
https://dlang.org/phobos/std_concurrency.html#.initOnce

But you will still need to use assumePure() for calling 
`thisExePath`, and it might do other things that are impure...


Yes, it's near but in this case I try to fix purity, so any 
variants of lazy initialization is not applicable here.


Re: thisExePath purity

2016-09-20 Thread crimaniak via Digitalmars-d-learn
On Tuesday, 20 September 2016 at 04:26:05 UTC, Jonathan M Davis 
wrote:
On Tuesday, September 20, 2016 04:17:21 crimaniak via 
Digitalmars-d-learn wrote:

 static shared immutable ReturnType!T value;


I would point out that immutable is implicitly shared, so 
there's no reason to put shared on an immutable variable. 
However, you _do_ want to put shared on a static constructor 
that initializes an immutable variable so that it's only run 
once for the program instead of once per thread (the compiler 
really should enforce that, but there's a longstanding bug that 
allows you to reinitialize an immutable variable by not putting 
shared on the static constructor and starting multiple threads).

 Ok, I got it. Thanks.


Re: thisExePath purity

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

On 9/20/16 12:17 AM, crimaniak wrote:

Hi and thanks all!

On Tuesday, 20 September 2016 at 00:43:10 UTC, Jonathan M Davis wrote:


immutable string executablePath;

shared static this()
{
import std.file : thisExePath();
executablePath = thisExePath();
}


This code is good for my needs but I start to think about how to call
thisExePath only if it is really used and come to this solution:

import std.traits: ReturnType, Parameters;

string staticMemoize(alias T, Parms = Parameters!T)() pure
{
struct Holder(alias T)
{
static shared immutable ReturnType!T value;
shared static this(){ value = T(Parms); }
}

return Holder!T.value;
}

unittest
{
import std.file : thisExePath;
assert(staticMemoize!thisExePath == thisExePath);
}

Something like this. Need to refine about input parameters, but I hope,
idea is clear.
Unlike the function memoize from phobos staticMemoize really pure. And
unlike proposed solution with ordinary variable staticMemoize is lazy,
because no call - no instantiation.


Yes, but if your code does instantiate it, it is called, even if you 
don't ever call the function that calls it.


Note that if you don't import the module that contains the static ctor, 
it should be trimmed by the linker.


I would absolutely caution you from putting static this() inside any 
template. Unfortunately, due to the way D generates these static 
constructors, any module that uses staticMemoize, or *imports a module 
that uses it*, will be marked as having a static constructor, and will 
potentially create cycles.


-Steve


Re: thisExePath purity

2016-09-20 Thread Marc Schütz via Digitalmars-d-learn

On Tuesday, 20 September 2016 at 04:17:21 UTC, crimaniak wrote:

Hi and thanks all!

On Tuesday, 20 September 2016 at 00:43:10 UTC, Jonathan M Davis 
wrote:



immutable string executablePath;

shared static this()
{
import std.file : thisExePath();
executablePath = thisExePath();
}


This code is good for my needs but I start to think about how 
to call thisExePath only if it is really used and come to this 
solution:


import std.traits: ReturnType, Parameters;

string staticMemoize(alias T, Parms = Parameters!T)() pure
{
struct Holder(alias T)
{
static shared immutable ReturnType!T value;
shared static this(){ value = T(Parms); }
}

return Holder!T.value;
}

unittest
{
import std.file : thisExePath;
assert(staticMemoize!thisExePath == thisExePath);
}

Something like this. Need to refine about input parameters, but 
I hope, idea is clear.
Unlike the function memoize from phobos staticMemoize really 
pure. And unlike proposed solution with ordinary variable 
staticMemoize is lazy, because no call - no instantiation.


Have a look at `std.concurrency.initOnce`:
https://dlang.org/phobos/std_concurrency.html#.initOnce

But you will still need to use assumePure() for calling 
`thisExePath`, and it might do other things that are impure...


Re: thisExePath purity

2016-09-19 Thread Jonathan M Davis via Digitalmars-d-learn
On Tuesday, September 20, 2016 04:17:21 crimaniak via Digitalmars-d-learn 
wrote:
>  static shared immutable ReturnType!T value;

I would point out that immutable is implicitly shared, so there's no reason
to put shared on an immutable variable. However, you _do_ want to put shared
on a static constructor that initializes an immutable variable so that it's
only run once for the program instead of once per thread (the compiler
really should enforce that, but there's a longstanding bug that allows you
to reinitialize an immutable variable by not putting shared on the static
constructor and starting multiple threads).

- Jonathan M Davis



Re: thisExePath purity

2016-09-19 Thread crimaniak via Digitalmars-d-learn

Hi and thanks all!

On Tuesday, 20 September 2016 at 00:43:10 UTC, Jonathan M Davis 
wrote:



immutable string executablePath;

shared static this()
{
import std.file : thisExePath();
executablePath = thisExePath();
}


This code is good for my needs but I start to think about how to 
call thisExePath only if it is really used and come to this 
solution:


import std.traits: ReturnType, Parameters;

string staticMemoize(alias T, Parms = Parameters!T)() pure
{
struct Holder(alias T)
{
static shared immutable ReturnType!T value;
shared static this(){ value = T(Parms); }
}

return Holder!T.value;
}

unittest
{
import std.file : thisExePath;
assert(staticMemoize!thisExePath == thisExePath);
}

Something like this. Need to refine about input parameters, but I 
hope, idea is clear.
Unlike the function memoize from phobos staticMemoize really 
pure. And unlike proposed solution with ordinary variable 
staticMemoize is lazy, because no call - no instantiation.


https://dlang.org/library/std/functional/memoize.html




Re: thisExePath purity

2016-09-19 Thread Jonathan M Davis via Digitalmars-d-learn
On Tuesday, September 20, 2016 00:37:10 Stefan Koch via Digitalmars-d-learn 
wrote:
> On Tuesday, 20 September 2016 at 00:01:58 UTC, crimaniak wrote:
> > Hi!
> >
> > Is there situations when output of thisExePath() can be
> > different during runtime? If yes, what the reason?
> > If no, is this possible to mark it as pure in phobos?
> >
> > https://dlang.org/library/std/file/this_exe_path.html
>
> No way to do that.
> It does I/O.
> However you cheat.
> look for assumePure in https://dlang.org/phobos/std_traits.html
> and then you can create a wrapper for it that is fake pure.

Yes, you can cast a function pointer to force purity, but that's almost
always a bad idea. It makes far more sense to just grab the value once and
reuse it. The only time that I'd suggest using the casting trick for
something like this would be when you can't afford to use static
constructors, and you can't afford to pass the value around. Casting to pure
should be a tool of last resort. It _is_ an option though if you really have
no reasonable alternative.

Another thing to consider in this case is that casting like that would
actually be needlessly expensive if he actually needs to make the call more
than once. It would be far cheaper to just save the result and reuse it. And
if it's stored in an immutable module-level or static variable, then it can
be used in a pure function.

- Jonathan M Davis



Re: thisExePath purity

2016-09-19 Thread Jonathan M Davis via Digitalmars-d-learn
On Tuesday, September 20, 2016 00:01:58 crimaniak via Digitalmars-d-learn 
wrote:
> Hi!
>
> Is there situations when output of thisExePath() can be different
> during runtime? If yes, what the reason?
> If no, is this possible to mark it as pure in phobos?
>
> https://dlang.org/library/std/file/this_exe_path.html

In principle, it should be impossible for it to change while the program is
running. However, what Phobos has to do to get the information can't be
pure. In the best case, it involves calling C functions that we can
reasonably assume will be pure but can't technically guarantee will be, but
in some cases, it actually involves querying the file system (e.g. on Linux,
it reads "/proc/self/exe"), which definitely can't be pure, because it
involves I/O.

If you really want a pure way to deal with this, then I'd suggest grabbing
the value at startup and setting it to an immutable variable. e.g. something
like

immutable string executablePath;

shared static this()
{
import std.file : thisExePath();
executablePath = thisExePath();
}

and then you can use that variable in pure code, because it's guaranteed not
to change.

- Jonathan M Davis



Re: thisExePath purity

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

On 9/19/16 8:01 PM, crimaniak wrote:

Hi!

Is there situations when output of thisExePath() can be different during
runtime? If yes, what the reason?
If no, is this possible to mark it as pure in phobos?

https://dlang.org/library/std/file/this_exe_path.html


Not in a way that D can ensure purity. Yes, it will not change. But that 
guarantee is not communicated via the OS functions required to call to 
get the information.


One thing you can do:

immutable string myPath;

shared static this()
{
   import std.file: thisExePath;
   myPath = thisExePath;
}

// now use myPath as required from pure functions.

-Steve


Re: thisExePath purity

2016-09-19 Thread Stefan Koch via Digitalmars-d-learn

On Tuesday, 20 September 2016 at 00:01:58 UTC, crimaniak wrote:

Hi!

Is there situations when output of thisExePath() can be 
different during runtime? If yes, what the reason?

If no, is this possible to mark it as pure in phobos?

https://dlang.org/library/std/file/this_exe_path.html


No way to do that.
It does I/O.
However you cheat.
look for assumePure in https://dlang.org/phobos/std_traits.html
and then you can create a wrapper for it that is fake pure.


thisExePath purity

2016-09-19 Thread crimaniak via Digitalmars-d-learn

Hi!

Is there situations when output of thisExePath() can be different 
during runtime? If yes, what the reason?

If no, is this possible to mark it as pure in phobos?

https://dlang.org/library/std/file/this_exe_path.html


[Issue 11047] UDA + getAttributes bypass purity/safety check

2016-06-16 Thread via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=11047

--- Comment #3 from github-bugzi...@puremagic.com ---
Commits pushed to master at https://github.com/dlang/dmd

https://github.com/dlang/dmd/commit/55bd78ded94a1f40ee80c4e42791f216e5d58c41
fix Issue 11047 - UDA + getAttributes bypass purity/safety check

https://github.com/dlang/dmd/commit/d1c3b6a1eab3347d9b6eb832b99ee45f70bd3702
Merge pull request #5863 from WalterBright/fix11047

fix Issue 11047 - UDA + getAttributes bypass purity/safety check

--


[Issue 11047] UDA + getAttributes bypass purity/safety check

2016-06-12 Thread via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=11047

Walter Bright  changed:

   What|Removed |Added

   Keywords||pull

--- Comment #2 from Walter Bright  ---
https://github.com/dlang/dmd/pull/5863

--


[Issue 11047] UDA + getAttributes bypass purity/safety check

2016-06-12 Thread via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=11047

--- Comment #1 from Walter Bright  ---
http://dlang.org/spec/attribute.html#UserDefinedAttribute

They are defined as "compile time expressions" meaning they have to be
evaluatable at compile time into a manifest constant. The bug here is this is
not being checked.

--


[Issue 11047] UDA + getAttributes bypass purity/safety check

2016-06-12 Thread via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=11047

Walter Bright  changed:

   What|Removed |Added

 CC||bugzi...@digitalmars.com
   See Also||https://issues.dlang.org/sh
   ||ow_bug.cgi?id=13442

--


Re: Weak Purity Blog Post

2016-03-30 Thread sarn via Digitalmars-d-announce
Yeah, there's a lot more stuff I could have talked about, but I 
think I'll leave it for other posts.


About testing, I think the way protection works in D (i.e., 
private members are accessible within the same file) is 
important, too.  I was a bit suspicious of that feature when I 
first looked at D (coming from C++) but now I actually like the 
kind of project structure it leads to.  I think better 
testability is just one of the advantages, but I'll write up a 
full blog post sometime.


Re: Weak Purity Blog Post

2016-03-30 Thread Jon D via Digitalmars-d-announce

On Monday, 28 March 2016 at 01:44:02 UTC, sarn wrote:
D's implementation of functional purity supports "weak" purity 
- functions that can mutate arguments but are otherwise 
traditionally pure.


I wrote a post about some of the practical benefits of this 
kind of purity:


https://theartofmachinery.com/2016/03/28/dirtying_pure_functions_can_be_useful.html


Nice article. A suggestion: The point about improved testability 
when designing for purity is well made. In D, this is further 
supported by the ability to write and place unit tests alongside 
the functions themselves. That's my personal opinion at least - 
because unit test are so easy to write in D, it encourages design 
for testability.


My suggestion is to add a note about this to the post.

--Jon


Re: Weak Purity Blog Post

2016-03-30 Thread Nordlöw via Digitalmars-d-announce

On Monday, 28 March 2016 at 01:44:02 UTC, sarn wrote:
I wrote a post about some of the practical benefits of this 
kind of purity:


https://theartofmachinery.com/2016/03/28/dirtying_pure_functions_can_be_useful.html


Great. It would be nice if you added a section that discusses 
purity in collaboration with allocators.


See discussions:

http://forum.dlang.org/post/yvwtjybwphxovrxav...@forum.dlang.org
http://forum.dlang.org/post/ejaarbdzcqgqhkxla...@forum.dlang.org

and

https://github.com/D-Programming-Language/druntime/pull/1183#issuecomment-202444315


Re: Weak Purity Blog Post

2016-03-30 Thread sarn via Digitalmars-d-announce

On Monday, 28 March 2016 at 09:59:12 UTC, ag0aep6g wrote:

On 28.03.2016 03:44, sarn wrote:

https://theartofmachinery.com/2016/03/28/dirtying_pure_functions_can_be_useful.html


From there:

Well, you can get the usual (“strong”) purity guarantee just 
by making all pointer or reference type arguments const.


Indirections in the return type also play into this. David 
Nadlinger explains this in his article on the matter:


http://klickverbot.at/blog/2012/05/purity-in-d/#indirections-in-the-return-type


Thanks.  I updated the post.


Re: Weak Purity Blog Post

2016-03-28 Thread ag0aep6g via Digitalmars-d-announce

On 28.03.2016 03:44, sarn wrote:

https://theartofmachinery.com/2016/03/28/dirtying_pure_functions_can_be_useful.html


From there:


Well, you can get the usual (“strong”) purity guarantee just by making all 
pointer or reference type arguments const.


Indirections in the return type also play into this. David Nadlinger 
explains this in his article on the matter:


http://klickverbot.at/blog/2012/05/purity-in-d/#indirections-in-the-return-type


Re: Weak Purity Blog Post

2016-03-28 Thread Walter Bright via Digitalmars-d-announce

On 3/27/2016 10:41 PM, deadalnix wrote:

https://www.reddit.com/r/programming/comments/4c8zs6/how_dirtying_pure_functions_a_little_can_be/



BTW, thanks for posting it.


Re: Weak Purity Blog Post

2016-03-28 Thread Walter Bright via Digitalmars-d-announce

On 3/27/2016 6:44 PM, sarn wrote:

D's implementation of functional purity supports "weak" purity - functions that
can mutate arguments but are otherwise traditionally pure.

I wrote a post about some of the practical benefits of this kind of purity:

https://theartofmachinery.com/2016/03/28/dirtying_pure_functions_can_be_useful.html


It's a nice article, you should put your name on it as the author!


Re: Weak Purity Blog Post

2016-03-28 Thread Walter Bright via Digitalmars-d-announce

On 3/27/2016 10:41 PM, deadalnix wrote:

On Monday, 28 March 2016 at 05:21:36 UTC, Joakim wrote:

On Monday, 28 March 2016 at 01:44:02 UTC, sarn wrote:

D's implementation of functional purity supports "weak" purity - functions
that can mutate arguments but are otherwise traditionally pure.

I wrote a post about some of the practical benefits of this kind of purity:

https://theartofmachinery.com/2016/03/28/dirtying_pure_functions_can_be_useful.html



Very well-written, someone post it on Reddit.


https://www.reddit.com/r/programming/comments/4c8zs6/how_dirtying_pure_functions_a_little_can_be/



Queue my usual harangue:

Articles do MUCH MUCH better on reddit if, when posted, a brief description of 
the content of the article is also posted. Like what sarn posted here.


Not doing so seriously blunts the value. People need a reason to click on the 
article. It's why when you google something, you don't just get a list of links. 
You get a blurb with each link.


Weak Purity Blog Post

2016-03-27 Thread sarn via Digitalmars-d-announce
D's implementation of functional purity supports "weak" purity - 
functions that can mutate arguments but are otherwise 
traditionally pure.


I wrote a post about some of the practical benefits of this kind 
of purity:


https://theartofmachinery.com/2016/03/28/dirtying_pure_functions_can_be_useful.html


Re: Containers, Allocators and Purity

2016-03-24 Thread ZombineDev via Digitalmars-d-learn

On Thursday, 24 March 2016 at 11:18:06 UTC, Nordlöw wrote:
Could somebody briefly outline how the thread-locality 
(non-GC-locked) of allocators  relates to the purity of the 
containers using them?


This because I want to move forward with optimizations in my 
knowledge graph that requires GC-free array containers storing 
value typed elements (integers) which preferrably has pure API.


Specifically, I want to use something like

https://github.com/economicmodeling/containers/blob/master/src/containers/dynamicarray.d

that is `@safe pure` and uses lock-free allocations in a 
heavily multi-threaded application.


If I want purity aswell which `std.experimental.allocators` are 
possible?


After a quick glance at: 
https://github.com/economicmodeling/containers/blob/master/src/containers/dynamicarray.d


It looks like if `useGC == false`, all of the methods should be 
`pure`-ready, except for `remove(size_t)` and `~this()`. These 
two methods use `typeid.destroy`, which I don't think is `pure`.


Re: Containers, Allocators and Purity

2016-03-24 Thread ZombineDev via Digitalmars-d-learn

On Thursday, 24 March 2016 at 11:18:06 UTC, Nordlöw wrote:
Could somebody briefly outline how the thread-locality 
(non-GC-locked) of allocators  relates to the purity of the 
containers using them?


This because I want to move forward with optimizations in my 
knowledge graph that requires GC-free array containers storing 
value typed elements (integers) which preferrably has pure API.


Specifically, I want to use something like

https://github.com/economicmodeling/containers/blob/master/src/containers/dynamicarray.d

that is `@safe pure` and uses lock-free allocations in a 
heavily multi-threaded application.


If I want purity aswell which `std.experimental.allocators` are 
possible?


Currently almost nothing in `std.experimental.allocators` is 
explicitly marked as pure, except for some of the things in 
./common.d 
(https://github.com/D-Programming-Language/phobos/pull/3957 
*shameless plug*). Thankfully make, makeArray, dispose and some 
of the allocators are templates, so you can rely on attribute 
inference.


The most important thing is that you need to have pure `allocate` 
and `deallocate` methods. After this `make` and friends will work 
like magic (at least for types with pure `this` and `~this`). 
`pure` statefull allocator essentially means that it has to be 
thread-local, so there are no global side-effects. Essentially, 
to achieve this you can make a large initial allocation in each 
thread (even from a non-pure allocator) and then you can make 
`pure` sub-allocations out of it.


You can read more about my adventures with my `pure` smart 
pointer here:

http://forum.dlang.org/post/eegjluaiwvdxfnbxk...@forum.dlang.org
http://forum.dlang.org/post/bvgyrfvuqrqcyvhkq...@forum.dlang.org


Containers, Allocators and Purity

2016-03-24 Thread Nordlöw via Digitalmars-d-learn
Could somebody briefly outline how the thread-locality 
(non-GC-locked) of allocators  relates to the purity of the 
containers using them?


This because I want to move forward with optimizations in my 
knowledge graph that requires GC-free array containers storing 
value typed elements (integers) which preferrably has pure API.


Specifically, I want to use something like

https://github.com/economicmodeling/containers/blob/master/src/containers/dynamicarray.d

that is `@safe pure` and uses lock-free allocations in a heavily 
multi-threaded application.


If I want purity aswell which `std.experimental.allocators` are 
possible?


Re: Container Purity

2015-12-09 Thread Nordlöw via Digitalmars-d-learn

On Wednesday, 9 December 2015 at 10:47:18 UTC, Nordlöw wrote:

that uses std.experimental.container


Correction: I mean std.experimental.allocator


Container Purity

2015-12-09 Thread Nordlöw via Digitalmars-d-learn

Is it currently possible for a container such as

https://github.com/economicmodeling/containers/blob/master/src/containers/dynamicarray.d

that uses std.experimental.container

to be completely pure? If not can be made to?

I wonder because only length(), empty(), front() and back() are 
tagged as pure in DynamicArray at


https://github.com/economicmodeling/containers/blob/master/src/containers/dynamicarray.d

are marked as pure. Is there a reason for this?


Re: Container Purity

2015-12-09 Thread Kagamin via Digitalmars-d-learn
Allocators usually use global state. Such code is usually treated 
as impure.


  1   2   3   4   5   6   7   8   9   10   >