May 15, 2014 Re: Memory allocation purity | ||||
---|---|---|---|---|
| ||||
Posted in reply to Marc Schütz | On Thursday, 15 May 2014 at 11:31:34 UTC, Marc Schütz wrote: > There's an important difference between malloc and new: malloc returns a pointer, but new returns a typed object. This is crucial IMO, because the returned objects are equal to each other. I most code, but not all, so how does the compiler know if you don't have a reference type that explicitly bans identity comparison? If one requires value semantics it should also cover the reference. (Some programs allocate empty objects as "enums".) > optimization opportunities, but in terms of semantics. For example, you get the concept of uniqueness. And the I agree that uniqueness is an important property. I think Rust is onto something when they now want to rename "mut" to "uniq" or "only". But in this case uniqueness is the problem with "weakly pure", a problem that "pure functions" don't have. |
May 15, 2014 Re: Memory allocation purity | ||||
---|---|---|---|---|
| ||||
Posted in reply to Brian Schott | On Wed, 14 May 2014 21:11:30 -0400, Brian Schott <briancschott@gmail.com> wrote:
> On Thursday, 15 May 2014 at 00:48:52 UTC, Walter Bright wrote:
>> On 5/14/2014 5:44 PM, Brian Schott wrote:
>>> Can we say that Mallocator failures are not recoverable?
>>
>> malloc itself does not have that property. But you could design a wrapper for it that did.
>
> I'm concerned specifically with this wrapper: https://github.com/andralex/phobos/blob/allocator/std/allocator.d#L773
>
> We need to make these functions pure if they are going to be usable.
>
> Removing the stdlib import and adding
>
> private extern (C)
> {
> void* malloc(size_t) pure nothrow @trusted;
> void free(void*) pure nothrow @trusted;
> void* realloc(void*, size_t) pure nothrow @trusted;
> }
Be careful. The above is all correct, but as has been discussed, the minute you start making returns immutable or parameters immutable, they become strong-pure, which has undesirable properties for allocators. If you wrap the above with calls to typed data, then strong-pure might be inferred.
The compiler can specially designate things like idup to make sure they always are considered weak-pure. But library code has to be more cautious.
-Steve
|
May 15, 2014 Re: Memory allocation purity | ||||
---|---|---|---|---|
| ||||
Posted in reply to Manu | On Thu, 15 May 2014 07:52:20 -0400, Manu via Digitalmars-d <digitalmars-d@puremagic.com> wrote:
> On 15 May 2014 10:50, Walter Bright via Digitalmars-d
> <digitalmars-d@puremagic.com> wrote:
>> On 5/14/2014 5:03 PM, Meta wrote:
>>>
>>> Allocating memory through new and malloc should always be pure, I think,
>>> because
>>> failure either returns null in malloc's case,
>>
>>
>> malloc cannot be pure if, with the same arguments, it returns null sometimes
>> and not other times.
>
> Even if it doesn't fail, malloc called with identical arguments still
> returns a different result every time.
> You can't factor malloc outside a loop and cache the result because
> it's being called repeatedly with the same argument like you're
> supposed to be able to do with any other pure function.
> You shouldn't be able to do that with gcalloc either... how can gcalloc be pure?
That only applies to strong-pure functions. malloc would be weak-pure, since it returns a mutable pointer.
-Steve
|
May 15, 2014 Re: Memory allocation purity | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ola Fosheim Grøstad | Ola, you do not understand 'pure.' To consider the design of pure, you must first consider that you cannot add functional purity to an imperative language. It cannot be done. What you can do instead is what D offers with a 'weak purity' guarantee. That global state is not modified indirectly, that side-effects do not occur in a function, except through the function's parameters, except for memory allocation. D allows you to come pretty close to strong purity when a function is marked pure, does not allocate memory inside it or through its arguments, and has only const or immutable arguments. The only way you can get a better purity guarantee than that is to use a functional programming language like Haskell. |
May 15, 2014 Re: Memory allocation purity | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jonathan M Davis | On Thursday, 15 May 2014 at 11:01:38 UTC, Jonathan M Davis via Digitalmars-d wrote: > functions with mutable parameters. It doesn't. And it would actually be very > difficult for it to do so without doing full program optimization, which > really doesn't work with the C linking model that D uses. I think this C linking excuse is used too much :-). Clearly one can specify properties of C functions when writing the bindings. (Or; should be able to). Besides, not all call trees are full of C calls. > functions. The whole > purpose of weakly pure functions is to have functions which aren't > functionally pure but can still be used in functions that _are_ functionally pure. I take it you mean "expressions" and not necessarily defined functions. So the compiler memoize values derived from weakly pure functions? > source code for the function available. The only functions for which the > compiler ever deduces anything from their bodies are templated functions, But with the amount of templates in phobos… maybe it is time to move beyond fully separate compilation units? > about is the signature of the function. So, it's up to the programmer to tell > the compiler that a function is supposed to be pure, and it's up to the > compiler to verify that, and then use that knowledge to infer Ok, but based on bearophile's example it doesn't verify purity properly. So it is essentially part verified ("verify noglob") and part programmer guarantee ("this is pure"). I don't mind programmers being able to set guarantees. For instance for a C function or machine language routines it might be useful to specify that this is pure and avoid recomputation. > I agree that that would be great if we were starting over - just like it would > be great if @safe were the default, but it's too late now. We have to make do with what we have. Yes, many changes over time is not good. Maybe it would be a good idea to collect all those syntax improvements and apply them all at once once the semantics are frozen. > avoid it. And as > nice as changing some of the attributes around would be nice, it's too big a > breaking change for too little gain. It doesn't have to break anything. You could add "@global" and "@pure" (strong pure) and keep "pure" (weakly pure) as a deprecated feature. |
May 15, 2014 Re: Memory allocation purity | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ola Fosheim Grøstad | On Thu, 15 May 2014 02:50:05 -0400, Ola Fosheim Grøstad <ola.fosheim.grostad+dlang@gmail.com> wrote: > On Thursday, 15 May 2014 at 06:29:06 UTC, bearophile wrote: >> A little example of D purity (this compiles): > >> bool randomBit() pure nothrow @safe { >> return (new int[1].ptr) > (new int[1].ptr); >> } > > Yes, and then you may as well allow a random generator with private globals. Because memoing is no longer sound anyway. This has nothing to do with allocators being pure. They must be pure as a matter of practicality. The issue that allows the above anomaly is using the address of something. There is a reason functional languages do not allow these types of things. But in functional languages, allocating is allowed. To be honest, code that would exploit such an anomaly is only ever used in "proof" exercises, and never in real code. I don't think it's an issue. -Steve |
May 15, 2014 Re: Memory allocation purity | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter Bright | On Wed, 14 May 2014 20:50:08 -0400, Walter Bright <newshound2@digitalmars.com> wrote:
> On 5/14/2014 5:03 PM, Meta wrote:
>> Allocating memory through new and malloc should always be pure, I think, because
>> failure either returns null in malloc's case,
>
> malloc cannot be pure if, with the same arguments, it returns null sometimes and not other times.
Basically, you are saying that malloc must return the same block whenever it's called with the same parameters. This is simply nonsense.
null is not special, it's just another block.
I'm not saying malloc should be pure based on this, but the possibility that it returns null does not disqualify it.
-Steve
|
May 15, 2014 Re: Memory allocation purity | ||||
---|---|---|---|---|
| ||||
Posted in reply to w0rp | On Thursday, 15 May 2014 at 12:37:22 UTC, w0rp wrote:
> To consider the design of pure, you must first consider that you cannot add functional purity to an imperative language.
Of course you can. Functional languages execute in an "imperative context". That's why you need monads.
The term "pure function" is only needed in a non-functional language. Applicative/functional languages only have mathematical functions, no need for the term "pure" there.
|
May 15, 2014 Re: Memory allocation purity | ||||
---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer | On Thursday, 15 May 2014 at 12:57:43 UTC, Steven Schveighoffer wrote:
> To be honest, code that would exploit such an anomaly is only ever used in "proof" exercises, and never in real code. I don't think it's an issue.
That's the wrong attitude to take when it comes to the compiler and runtime.
If it verifies, it should verify. Not mostly, but fully, otherwise "weakly pure" becomes a programmer guarantee. Which is ok too, but either the one or the other.
How can you prove that such issues don't arise in real code?
|
May 15, 2014 Re: Memory allocation purity | ||||
---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer | On Thursday, 15 May 2014 at 12:57:43 UTC, Steven Schveighoffer wrote: > On Thu, 15 May 2014 02:50:05 -0400, Ola Fosheim Grøstad <ola.fosheim.grostad+dlang@gmail.com> wrote: > >> On Thursday, 15 May 2014 at 06:29:06 UTC, bearophile wrote: >>> A little example of D purity (this compiles): >> >>> bool randomBit() pure nothrow @safe { >>> return (new int[1].ptr) > (new int[1].ptr); >>> } >> >> Yes, and then you may as well allow a random generator with private globals. Because memoing is no longer sound anyway. > > This has nothing to do with allocators being pure. They must be pure as a matter of practicality. > > The issue that allows the above anomaly is using the address of something. There is a reason functional languages do not allow these types of things. But in functional languages, allocating is allowed. Which is what makes D pure lint-like helper and not effective optimization enabler. This part of type system was under-designed initially, it should have been much more restrictive. I am ok with current state though, it is just sad that it creates lot of false expectations from those familiar with pure functional languages. > To be honest, code that would exploit such an anomaly is only ever used in "proof" exercises, and never in real code. I don't think it's an issue. This is not true. Because of such code you can't ever automatically memoize strongly pure function results by compiler. A very practical concern. |
Copyright © 1999-2021 by the D Language Foundation