emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: pure-fns in byte-opt.el


From: Clément Pit-Claudel
Subject: Re: pure-fns in byte-opt.el
Date: Wed, 26 Jul 2017 09:39:00 +0200
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Thunderbird/52.2.1

On 2017-07-26 02:08, Stefan Monnier wrote:
>>> If string-to-char were a pure function, it would return the same
>>> value in both calls (since the arguments are `eq')
>>                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>> What do you mean by this?
> 
> That the argument passed to the first call is `eq` with the argument
> passed to the second call.

I see.  That's not what I understood to be usually meant by "pure": although 
both arguments are pointers to the same address in memory, the contents of that 
address have been modified in the meantime.  In that sense, haven't the two 
calls to string-to-char been passed different values (albeit stored in the same 
memory location)?

In other words, I don't see your example as proving that string-to-char is 
impure; instead, it just looks like a pure function that's passed two different 
values.  As a concrete example, is the following a proof that string-to-syntax 
is impure? If so, it should be removed from our list of pure functions :)

  (let ((s (make-string 1 ?w)))
    (list (string-to-syntax s)
          (progn
            (aset s 0 ?_)
            (string-to-syntax s))))

The same argument seems to apply to *all* functions marked pure in byte-opt.el, 
except `symbol-name' (namely `concat', `regexp-opt', `regexp-quote', and 
`string-to-syntax'). Under your definition, neither the `length' nor the `car' 
function on lists are pure. In fact, if I understand it correctly, your 
definition seems to imply that any function that reads mutable data is (by 
definition) impure.  Is that right?  This seems very restrictive, and it seems 
to be contradicted by existing 'pure' annotations in our codebase.  How do we 
call the property shared by `concat', `length', and `string-to-chars'? in ELisp 
land, if it's not "pure"?

In byte-opt we say this:

;; pure functions are side-effect free functions whose values depend
;; only on their arguments. For these functions, calls with constant
;; arguments can be evaluated at compile time. This may shift run time
;; errors to compile time.

I tried to get inspiration from looking at other `pure' annotations in lisp/ 
but the examples I found were confusing.  All four examples of (pure t) 
functions in smie.el take lists as input, for example:

(defun smie-precs->prec2 (precs)
  "Compute a 2D precedence table from a list of precedences. …
  (declare (pure t))

and indeed:

  (let ((s '((left "+") (right "*"))))
    (list (smie-precs->prec2 s)
          (progn
            (setf (caar s) 'right)
            (smie-precs->prec2 s))))

Can you point out where I went wrong? To me it just looks like Mark ran into a 
bug.

Clément.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]