-----------
@safe pure auto fun()
{ import std.uni;
return "a\u0308".normalize;
}
-----------
Errors, with both nightly and stable DMD:
onlineapp.d(3): Error: `pure` function `onlineapp.fun` cannot call impure function `std.uni.normalize!(NormalizationForm.NFC, char).normalize`
There is nothing in `normalize` that should alter global state, so this should compile.
I'm classifying this as major, because this is the only way to normalize Unicode strings in D without a DIY or third-party library. The function not being available in pure code is a serious hinderance.
Comment #1 by johan_forsberg_86 — 2022-10-30T22:50:27Z
I took a look at this.
If you mark the following as pure:
normalize
decompose
decomposeHangul
Then there's only this that needs to be pure (in normalize)
() @trusted {
decomposed.assumeSafeAppend();
ccc.length = 0;
ccc.assumeSafeAppend();
} ();
To cheat and not make the appenders pure but the block pure we can just add pure:
() @trusted pure {
decomposed.assumeSafeAppend();
ccc.length = 0;
ccc.assumeSafeAppend();
} ();
But, we still need some way there to allow calling the impure append from the pure block.
Maybe we could cast some function pointer to pure, I don't know.
I tested wrapping it in a debug block and that makes it work, but I'm not sure what the "real" solution would look like.
() @trusted pure {
debug {
decomposed.assumeSafeAppend();
ccc.length = 0;
ccc.assumeSafeAppend();
}
} ();
Comment #2 by johan_forsberg_86 — 2022-10-30T23:11:46Z
One way I guess is to cast the function to pure.
The other is to actually mark _d_arrayshrinkfit as pure.
Which of those seems most reasonable?
Comment #3 by dlang-bot — 2023-06-14T17:27:22Z
@dukc created dlang/phobos pull request #8763 "fix issue 23361 - std.uni.normalize made pure" fixing this issue:
- fix issue 23361 - std.uni.normalize made pure
https://github.com/dlang/phobos/pull/8763
Comment #4 by Ajieskola — 2023-06-14T17:35:35Z
Oh, it seems I have missed your comment - I just figured all this out myself creating a fix for this when I could just have read your message.
I solved the assumeSafeAppend thing by marking the calls pure.
(But with a cast - does simply marking the lambda pure really work? I thought even `@trusted` code lets to treat impure calls as pure only with an explicit cast.)
I think it's okay because... well let me copy my comment from the code as explaination:
---
// assumeSafeAppend isn't considered pure as of writing, hence the
// cast. It isn't pure in the sense that the elements after
// the array in question are affected, but we don't use those
// making the call pure for our purposes.
---
Comment #5 by dlang-bot — 2023-06-18T12:45:18Z
dlang/phobos pull request #8763 "fix issue 23361 - std.uni.normalize made pure" was merged into master:
- e6ed40182187ea4f3caf1127102136f9aa5fd0ac by Ate Eskola:
fix issue 23361 - std.uni.normalize made pure
https://github.com/dlang/phobos/pull/8763