* Should records be able to mimic primitive types? @ 2017-04-04 22:00 Paul Eggert 2017-04-05 1:09 ` Stefan Monnier 0 siblings, 1 reply; 18+ messages in thread From: Paul Eggert @ 2017-04-04 22:00 UTC (permalink / raw To: Emacs development discussions In looking at the 'record' feature recently added to master, I noticed that (record 'integer 'foo 'bar) returns a value V such that (type-of V) yields the symbol 'integer', even though V is not an integer. Is this intended? Or should 'record' and 'make-record' reject attempts to build records that pretend to be of primitive types? ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: Should records be able to mimic primitive types? 2017-04-04 22:00 Should records be able to mimic primitive types? Paul Eggert @ 2017-04-05 1:09 ` Stefan Monnier 2017-04-08 15:09 ` Philipp Stephani 0 siblings, 1 reply; 18+ messages in thread From: Stefan Monnier @ 2017-04-05 1:09 UTC (permalink / raw To: emacs-devel > In looking at the 'record' feature recently added to master, I noticed that > (record 'integer 'foo 'bar) returns a value V such that (type-of V) yields > the symbol 'integer', even though V is not an integer. Is this intended? Yes. `record` is just a primitive on top of which we can build things (e.g. cl-defstruct or EIEIO). > Or should 'record' and 'make-record' reject attempts to build records > that pretend to be of primitive types? I don't see the benefit in trying to try hard to prevent the user from shooting himself in the foot. Stefan ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: Should records be able to mimic primitive types? 2017-04-05 1:09 ` Stefan Monnier @ 2017-04-08 15:09 ` Philipp Stephani 2017-04-08 17:57 ` Stefan Monnier 0 siblings, 1 reply; 18+ messages in thread From: Philipp Stephani @ 2017-04-08 15:09 UTC (permalink / raw To: Stefan Monnier, emacs-devel [-- Attachment #1: Type: text/plain, Size: 423 bytes --] Stefan Monnier <monnier@iro.umontreal.ca> schrieb am Mi., 5. Apr. 2017 um 03:10 Uhr: > > Or should 'record' and 'make-record' reject attempts to build records > > that pretend to be of primitive types? > > I don't see the benefit in trying to try hard to prevent the user from > shooting himself in the foot. > > It's not trying hard, just a simple check for a known, small, and rarely-changing list of primitive symbols. [-- Attachment #2: Type: text/html, Size: 859 bytes --] ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: Should records be able to mimic primitive types? 2017-04-08 15:09 ` Philipp Stephani @ 2017-04-08 17:57 ` Stefan Monnier 2017-05-01 11:35 ` Philipp Stephani 2017-06-12 17:40 ` Stefan Monnier 0 siblings, 2 replies; 18+ messages in thread From: Stefan Monnier @ 2017-04-08 17:57 UTC (permalink / raw To: emacs-devel > It's not trying hard, just a simple check for a known, small, and > rarely-changing list of primitive symbols. To me, that's working very hard: - extra code. - extra maintenance - extra run-time checks. - no benefit since this doesn't catch a common situation. Stefan ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: Should records be able to mimic primitive types? 2017-04-08 17:57 ` Stefan Monnier @ 2017-05-01 11:35 ` Philipp Stephani 2017-05-01 12:03 ` Stefan Monnier 2017-06-12 17:40 ` Stefan Monnier 1 sibling, 1 reply; 18+ messages in thread From: Philipp Stephani @ 2017-05-01 11:35 UTC (permalink / raw To: Stefan Monnier, emacs-devel [-- Attachment #1: Type: text/plain, Size: 765 bytes --] Stefan Monnier <monnier@iro.umontreal.ca> schrieb am Sa., 8. Apr. 2017 um 19:58 Uhr: > > It's not trying hard, just a simple check for a known, small, and > > rarely-changing list of primitive symbols. > > To me, that's working very hard: > - extra code. > Only a tiny bit. > - extra maintenance > Negligible, because we rarely add new primitive types. A comment should be added to Ftype_of to also modify a static list of primitive types when adding a new type, but that should be it. > - extra run-time checks. > Minor concern. Emacs Lisp isn't C; we prefer to help the user over saving a couple of clock cycles. > - no benefit since this doesn't catch a common situation. > Catching uncommon situation is precisely the point of precondition checking. [-- Attachment #2: Type: text/html, Size: 1533 bytes --] ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: Should records be able to mimic primitive types? 2017-05-01 11:35 ` Philipp Stephani @ 2017-05-01 12:03 ` Stefan Monnier 2017-06-10 11:39 ` Philipp Stephani 0 siblings, 1 reply; 18+ messages in thread From: Stefan Monnier @ 2017-05-01 12:03 UTC (permalink / raw To: Philipp Stephani; +Cc: emacs-devel >> - no benefit since this doesn't catch a common situation. > Catching uncommon situation is precisely the point of precondition > checking. I'm talking about "common" within erroneous situations. There is an endless supply of erroneous situations: we only bother to try and detect those that are serious (e.g. could cause a memory corruption) or frequent/common. I've never seen this kind of error in the wild, so I doubt it would *ever* prove useful to someone. Stefan ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: Should records be able to mimic primitive types? 2017-05-01 12:03 ` Stefan Monnier @ 2017-06-10 11:39 ` Philipp Stephani 2017-06-10 12:43 ` Eli Zaretskii 0 siblings, 1 reply; 18+ messages in thread From: Philipp Stephani @ 2017-06-10 11:39 UTC (permalink / raw To: Stefan Monnier; +Cc: emacs-devel [-- Attachment #1: Type: text/plain, Size: 269 bytes --] Stefan Monnier <monnier@iro.umontreal.ca> schrieb am Mo., 1. Mai 2017 um 14:03 Uhr: > we only bother to > try and detect those that are serious (e.g. could cause a memory > corruption) or frequent/common. > > As said in another thread, I disagree with that principle. [-- Attachment #2: Type: text/html, Size: 558 bytes --] ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: Should records be able to mimic primitive types? 2017-06-10 11:39 ` Philipp Stephani @ 2017-06-10 12:43 ` Eli Zaretskii 2017-06-12 15:07 ` Philipp Stephani 0 siblings, 1 reply; 18+ messages in thread From: Eli Zaretskii @ 2017-06-10 12:43 UTC (permalink / raw To: Philipp Stephani; +Cc: monnier, emacs-devel > From: Philipp Stephani <p.stephani2@gmail.com> > Date: Sat, 10 Jun 2017 11:39:40 +0000 > Cc: emacs-devel@gnu.org > > Stefan Monnier <monnier@iro.umontreal.ca> schrieb am Mo., 1. Mai 2017 um 14:03 Uhr: > > we only bother to > try and detect those that are serious (e.g. could cause a memory > corruption) or frequent/common. > > As said in another thread, I disagree with that principle. It's okay to disagree, but these have been the principles underlying Emacs development since about forever, so please try to be consistent with them as long as they are followed. I don't think a case for making Emacs Lisp a more restricted development environment than it is now will gain many supporters. E.g., even the move to make characters a special data type separate from integers, something the XEmacs actually did, was rejected by Emacs. Of course, you should feel free to start a discussion about this, and let's see how many people support your proposed direction. ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: Should records be able to mimic primitive types? 2017-06-10 12:43 ` Eli Zaretskii @ 2017-06-12 15:07 ` Philipp Stephani 2017-06-12 17:00 ` Eli Zaretskii 0 siblings, 1 reply; 18+ messages in thread From: Philipp Stephani @ 2017-06-12 15:07 UTC (permalink / raw To: Eli Zaretskii; +Cc: monnier, emacs-devel [-- Attachment #1: Type: text/plain, Size: 1124 bytes --] Eli Zaretskii <eliz@gnu.org> schrieb am Sa., 10. Juni 2017 um 14:44 Uhr: > > From: Philipp Stephani <p.stephani2@gmail.com> > > Date: Sat, 10 Jun 2017 11:39:40 +0000 > > Cc: emacs-devel@gnu.org > > > > Stefan Monnier <monnier@iro.umontreal.ca> schrieb am Mo., 1. Mai 2017 > um 14:03 Uhr: > > > > we only bother to > > try and detect those that are serious (e.g. could cause a memory > > corruption) or frequent/common. > > > > As said in another thread, I disagree with that principle. > > It's okay to disagree, but these have been the principles underlying > Emacs development since about forever, so please try to be consistent > with them as long as they are followed. I don't think a case for > making Emacs Lisp a more restricted development environment than it is > now will gain many supporters. E.g., even the move to make characters > a special data type separate from integers, something the XEmacs > actually did, was rejected by Emacs. > That's not my intention. What I have in mind is to raise more signals in cases where users use Emacs functions incorrectly instead of employing unspecified behavior. [-- Attachment #2: Type: text/html, Size: 1681 bytes --] ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: Should records be able to mimic primitive types? 2017-06-12 15:07 ` Philipp Stephani @ 2017-06-12 17:00 ` Eli Zaretskii 2017-06-12 17:15 ` Stefan Monnier 0 siblings, 1 reply; 18+ messages in thread From: Eli Zaretskii @ 2017-06-12 17:00 UTC (permalink / raw To: Philipp Stephani; +Cc: monnier, emacs-devel > From: Philipp Stephani <p.stephani2@gmail.com> > Date: Mon, 12 Jun 2017 15:07:16 +0000 > Cc: monnier@iro.umontreal.ca, emacs-devel@gnu.org > > It's okay to disagree, but these have been the principles underlying > Emacs development since about forever, so please try to be consistent > with them as long as they are followed. I don't think a case for > making Emacs Lisp a more restricted development environment than it is > now will gain many supporters. E.g., even the move to make characters > a special data type separate from integers, something the XEmacs > actually did, was rejected by Emacs. > > That's not my intention. What I have in mind is to raise more signals in cases where users use Emacs > functions incorrectly instead of employing unspecified behavior. If some usage is unequivocally wrong, can never support legitimate use cases, and the defenses are not too expensive, then I think this could be okay. But we need to be careful not to disallow legitimate, though perhaps somewhat dangerous practices. Emacs's tradition is to trust the Lisp programmers not to shoot themselves in the foot, so we generally prefer to err on that side of the line, when in doubt. Punishing the innocent on behalf of possibly guilty is something I think we should try to avoid. ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: Should records be able to mimic primitive types? 2017-06-12 17:00 ` Eli Zaretskii @ 2017-06-12 17:15 ` Stefan Monnier 2017-06-12 17:22 ` Eli Zaretskii 0 siblings, 1 reply; 18+ messages in thread From: Stefan Monnier @ 2017-06-12 17:15 UTC (permalink / raw To: emacs-devel > If some usage is unequivocally wrong, can never support legitimate use > cases, and the defenses are not too expensive, then I think this could > be okay. But we need to be careful not to disallow legitimate, though > perhaps somewhat dangerous practices. Emacs's tradition is to trust > the Lisp programmers not to shoot themselves in the foot, so we > generally prefer to err on that side of the line, when in doubt. > Punishing the innocent on behalf of possibly guilty is something I > think we should try to avoid. I think the kind of added checks he's thinking of are "safe" in this respect. The reason why I disagree with them is because they are too costly compared to the likelihood they'll ever help catch a bug (either because they'd virtually never trigger except maybe during experimentation, and in the unlikely event that they do trigger, the problem they discover would quickly lead to lots of other problems anyway). We generally don't check every imaginable meaningless circumstance, but only those that we've found to occur often enough to warrant the runtime and maintenance cost of an extra test. E.g. the byte-compiler doesn't emit a warning when you try to compile an expression like (+ 'b x). Stefan ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: Should records be able to mimic primitive types? 2017-06-12 17:15 ` Stefan Monnier @ 2017-06-12 17:22 ` Eli Zaretskii 2017-06-12 17:47 ` Stefan Monnier 0 siblings, 1 reply; 18+ messages in thread From: Eli Zaretskii @ 2017-06-12 17:22 UTC (permalink / raw To: Stefan Monnier; +Cc: emacs-devel > From: Stefan Monnier <monnier@iro.umontreal.ca> > Date: Mon, 12 Jun 2017 13:15:35 -0400 > > > If some usage is unequivocally wrong, can never support legitimate use > > cases, and the defenses are not too expensive, then I think this could > > be okay. But we need to be careful not to disallow legitimate, though > > perhaps somewhat dangerous practices. Emacs's tradition is to trust > > the Lisp programmers not to shoot themselves in the foot, so we > > generally prefer to err on that side of the line, when in doubt. > > Punishing the innocent on behalf of possibly guilty is something I > > think we should try to avoid. > > I think the kind of added checks he's thinking of are "safe" in > this respect. > > The reason why I disagree with them is because they are too costly > compared to the likelihood they'll ever help catch a bug That'd be in the "defenses are too expensive" department, right? > We generally don't check every imaginable meaningless circumstance, but > only those that we've found to occur often enough to warrant the runtime > and maintenance cost of an extra test. Right. ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: Should records be able to mimic primitive types? 2017-06-12 17:22 ` Eli Zaretskii @ 2017-06-12 17:47 ` Stefan Monnier 0 siblings, 0 replies; 18+ messages in thread From: Stefan Monnier @ 2017-06-12 17:47 UTC (permalink / raw To: emacs-devel >> The reason why I disagree with them is because they are too costly >> compared to the likelihood they'll ever help catch a bug > That'd be in the "defenses are too expensive" department, right? Right. I just wanted to clarify that "expensive" is a relative notion: in the case under discussion, the extra check is just a single `memq` test on a fairly short list, so it's pretty cheap in itself; the only reason why I find it too expensive is that the expected gain is just extremely small. Stefan ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: Should records be able to mimic primitive types? 2017-04-08 17:57 ` Stefan Monnier 2017-05-01 11:35 ` Philipp Stephani @ 2017-06-12 17:40 ` Stefan Monnier 2017-06-16 18:42 ` Philipp Stephani 1 sibling, 1 reply; 18+ messages in thread From: Stefan Monnier @ 2017-06-12 17:40 UTC (permalink / raw To: emacs-devel >> It's not trying hard, just a simple check for a known, small, and >> rarely-changing list of primitive symbols. > To me, that's working very hard: > - extra code. > - extra maintenance > - extra run-time checks. > - no benefit since this doesn't catch a common situation. More concretely: what would be a scenario where such a check would be useful? AFAICT, you need all 3 of: 1- First, you'd need someone to be foolish enough to set his record's type to be one of the primitive types. This is the actual bug that your extra check would aim to catch. 2- Then you'd need to pass that object to a chunk of code which uses `type-of` and then checks the result for that primitive type. Otherwise, the type you set would behave just like any other non-primitive type so the "bug" would be harmless anyway. 3- Furthermore, you'd need this object to be manipulated exclusively in a way which also works with your record object without signaling an error (e.g. if the primitive type used is `integer`, it means your object should never be passed to the likes of `+` since otherwise the bug would already be discovered by `+` without any need for your extra check). I haven't seen any evidence that step 1 will ever occur, even by accident. No idea how likely is step 2. `type-of` is very rarely used (except via cl-defmethod) so it's fairly unlikely, but possible. Step 3 seems again very unlikely in itself, and even more so if step 2 occurred: if you checked with type-of that your object is of type `integer` there's a very high likelihood that you're going to then use operations which only work on integers. Will all 3 steps ever occur at the same time? Do we really want to make every call to `make-record` pay the extra test in order to hope to catch this hypothetical case? Obviously I think not, and I'd be curious to understand why you think otherwise. Stefan ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: Should records be able to mimic primitive types? 2017-06-12 17:40 ` Stefan Monnier @ 2017-06-16 18:42 ` Philipp Stephani 2017-06-16 19:07 ` Stefan Monnier 0 siblings, 1 reply; 18+ messages in thread From: Philipp Stephani @ 2017-06-16 18:42 UTC (permalink / raw To: Stefan Monnier, emacs-devel [-- Attachment #1: Type: text/plain, Size: 3372 bytes --] Stefan Monnier <monnier@iro.umontreal.ca> schrieb am Mo., 12. Juni 2017 um 19:41 Uhr: > >> It's not trying hard, just a simple check for a known, small, and > >> rarely-changing list of primitive symbols. > > To me, that's working very hard: > > - extra code. > > - extra maintenance > > - extra run-time checks. > > - no benefit since this doesn't catch a common situation. > > More concretely: what would be a scenario where such a check would > be useful? > > AFAICT, you need all 3 of: > 1- First, you'd need someone to be foolish enough to set his record's > type to be one of the primitive types. This is the actual bug that > your extra check would aim to catch. > Yes, though I wouldn't consider it foolish. make-record can be called indirectly, maybe even from a function that somehow generates the type name. People might try to create records named 'integer' and be happy that that appears to work. > 2- Then you'd need to pass that object to a chunk of code which uses > `type-of` and then checks the result for that primitive type. > Otherwise, the type you set would behave just like any other > non-primitive type so the "bug" would be harmless anyway. > 3- Furthermore, you'd need this object to be manipulated exclusively in > a way which also works with your record object without signaling an > error (e.g. if the primitive type used is `integer`, it means your > object should never be passed to the likes of `+` since otherwise the > bug would already be discovered by `+` without any need for your extra > check). > > I haven't seen any evidence that step 1 will ever occur, even by accident. > I don't care about how often some bug will occur. Rather the contrary: it's the rare bugs that are insidious. People learn about the common ones quickly, but nobody will expect a rare bug, until it arises. > > No idea how likely is step 2. `type-of` is very rarely used (except via > cl-defmethod) so it's fairly unlikely, but possible. > > Step 3 seems again very unlikely in itself, and even more so if step > 2 occurred: if you checked with type-of that your object is of type > `integer` there's a very high likelihood that you're going to then use > operations which only work on integers. > > Will all 3 steps ever occur at the same time? > I don't think this is an important question. The important point is: Previously, there were invariants such as (integerp x) == (eq (type-of x) 'integer) or that prin1 would only generate #s(hash-table ...) for actual hash tables. Now these invariants are broken. But it's critical that invariants are never broken, no matter how unlikely the breakage is. Imagine a system where 1 + 1 = 3 in one trillionth of the executions: even if the bug were rare, that system would be unusable. Even worse, because it is so rare, it is much more disastrous when it happens, because people started relying on the invariant that is "almost" guaranteed. But there's a discontinuity between "invariant is guaranteed" and "invariant is almost always guaranteed": the latter is identical to "invariant is not guaranteed at all". > > Do we really want to make every call to `make-record` pay the extra test > in order to hope to catch this hypothetical case? Yes, absolutely. I don't care whether it's rare or hypothetical, it breaks an invariant, and invariants must not be broken. [-- Attachment #2: Type: text/html, Size: 4403 bytes --] ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: Should records be able to mimic primitive types? 2017-06-16 18:42 ` Philipp Stephani @ 2017-06-16 19:07 ` Stefan Monnier 2017-09-24 14:47 ` Philipp Stephani 0 siblings, 1 reply; 18+ messages in thread From: Stefan Monnier @ 2017-06-16 19:07 UTC (permalink / raw To: Philipp Stephani; +Cc: emacs-devel >> Will all 3 steps ever occur at the same time? > I don't think this is an important question. But in the absence of the combination of those 3 steps, your check will make no difference. Are you saying that you don't think "whether my check makes a difference" is an important question? > The important point is: Previously, there were invariants such as > (integerp x) == (eq (type-of x) 'integer) or that prin1 would only > generate #s(hash-table ...) for actual hash tables. Now these > invariants are broken. Every patch we install changes an "invariant" (except for cosmetic patches, changes to the build system, ...). So we can't take such an absolute position, if we want to keep developing Emacs (including fixing bugs): we necessarily have to judge which invariants are worthy of being preserved and which ones aren't. E.g. if we ever get good support for bignums, we'll likely have to break your first invariant. Also we have to distinguish between breaking an invariant and not enforcing it. I do consider an Elisp code which creates a record of type `integer` as a bug, but I don't think it's worth this particular effort to enforce it. Even with your extra check the above two invariants won't always hold. I can trivially break the first one with some add-advice on type-of. Should we add another check to prevent breaking the "invariant" in that other way? The second can be broken without even using an advice on `prin1` simply by creating a record of type (make-symbol "hash-table"). Should we also add yet another check to try and avoid this other way to break your "invariant"? > But there's a discontinuity between "invariant is guaranteed" and > "invariant is almost always guaranteed": the latter is identical to > "invariant is not guaranteed at all". In Elisp, the general rule is that thanks to the dynamic nature of the language, there are precious few invariants which really always hold. E.g. as soon as your "invariant" calls a function by name, you're exposed to breakage via the advice mechanism. So, in a sense, Elisp is a landmine just like C. > Yes, absolutely. I don't care whether it's rare or hypothetical, it breaks > an invariant, and invariants must not be broken. You might like to try Agda or Coq, but Elisp will inevitably disappoint you in this area. In case you're interested, my own hobby language, Typer, tries to combine Coq with Lisp. Stefan ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: Should records be able to mimic primitive types? 2017-06-16 19:07 ` Stefan Monnier @ 2017-09-24 14:47 ` Philipp Stephani 2017-09-24 16:44 ` Stefan Monnier 0 siblings, 1 reply; 18+ messages in thread From: Philipp Stephani @ 2017-09-24 14:47 UTC (permalink / raw To: Stefan Monnier; +Cc: emacs-devel [-- Attachment #1: Type: text/plain, Size: 4447 bytes --] Stefan Monnier <monnier@iro.umontreal.ca> schrieb am Fr., 16. Juni 2017 um 21:07 Uhr: > >> Will all 3 steps ever occur at the same time? > > I don't think this is an important question. > > But in the absence of the combination of those 3 steps, your check will > make no difference. Are you saying that you don't think "whether my > check makes a difference" is an important question? > It does make a difference. It's important for specifications to be precise and unsurprising, no matter whether a certain case is frequent or not. > > > The important point is: Previously, there were invariants such as > > (integerp x) == (eq (type-of x) 'integer) or that prin1 would only > > generate #s(hash-table ...) for actual hash tables. Now these > > invariants are broken. > > Every patch we install changes an "invariant" (except for cosmetic > patches, changes to the build system, ...). > > So we can't take such an absolute position, if we want to keep > developing Emacs (including fixing bugs): we necessarily have to judge > which invariants are worthy of being preserved and which ones aren't. > True, but such changes need to be considered very carefully, and we need to state explicitly which invariants can be broken without notifying anybody (e.g. introducing new functions in the global namespace), which can be broken by listing them in the NEWS file under "Breaking changes" (such as removing a function), and which invariants cannot be broken. The change being discussed here is at least in the second category. I would argue it is even in the third category: it breaks invariants around fundamental ELisp types for no good reason. > E.g. if we ever get good support for bignums, we'll likely have to break > your first invariant. > We can't do that. Bignum support would either have to be completely transparent (which would make `eq' more complex), or they should be a completely separate type. > > Also we have to distinguish between breaking an invariant and not > enforcing it. I do consider an Elisp code which creates a record of > type `integer` as a bug, but I don't think it's worth this particular > effort to enforce it. > This doesn't work: if it's not an explicit error, then people will start relying on it ("Hyrum's law"). We need to enforce our specifications, otherwise they aren't specifications. > > Even with your extra check the above two invariants won't always hold. > I can trivially break the first one with some add-advice on type-of. > Should we add another check to prevent breaking the "invariant" in that > other way? The second can be broken without even using an advice on > `prin1` simply by creating a record of type (make-symbol "hash-table"). > Should we also add yet another check to try and avoid this other way to > break your "invariant"? > No. Even though I dislike the advice functionality, would want to ban it for primitive functions, and think that it's dangerously overused, it (or rather the underlying `fset' primitive) is a part of the language, just like reflection in Java. Users should definitely be warned to steer clear from fset and its wrappers except for specialized uses such as mocking, but its existence shouldn't affect other development: Code may always assume that `fset' hasn't been called on any of the named functions it calls. If that assumption is broken, it's the burden of the code that breaks it. > > > But there's a discontinuity between "invariant is guaranteed" and > > "invariant is almost always guaranteed": the latter is identical to > > "invariant is not guaranteed at all". > > In Elisp, the general rule is that thanks to the dynamic nature of the > language, there are precious few invariants which really always hold. > E.g. as soon as your "invariant" calls a function by name, you're > exposed to breakage via the advice mechanism. > > So, in a sense, Elisp is a landmine just like C. > Most languages have escape hatches (e.g. reflection in Java). That doesn't mean we should accept them as a given or introduce more them for no good reason. > > > Yes, absolutely. I don't care whether it's rare or hypothetical, it > breaks > > an invariant, and invariants must not be broken. > > You might like to try Agda or Coq, but Elisp will inevitably disappoint > you in this area. > > As mentioned, such invariants can be written conditionally to no `fset' calls happening. If `fset' is used, all invariants are trivially broken. [-- Attachment #2: Type: text/html, Size: 6051 bytes --] ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: Should records be able to mimic primitive types? 2017-09-24 14:47 ` Philipp Stephani @ 2017-09-24 16:44 ` Stefan Monnier 0 siblings, 0 replies; 18+ messages in thread From: Stefan Monnier @ 2017-09-24 16:44 UTC (permalink / raw To: emacs-devel > As mentioned, such invariants can be written conditionally to no `fset' > calls happening. If `fset' is used, all invariants are trivially broken. Emacs was designed with the intention to make it easy to change pretty much any part of its behavior. `fset` is one of the tools for that, but it's far from the only one. We can't list all the ways someone can shoot himself in the foot with Emacs Lisp, and even less automatically check them. So we have to limit ourselves to something more realistic, which is to focus on the problems which do occur with some reasonable probability. This said, if you do want to avoid such structs, I won't object (tho I'll find it a waste of time) as long as the check is done at compile-time (so it has 0 cost at run-time), e.g. in the `cl-defstruct` macro. Stefan ^ permalink raw reply [flat|nested] 18+ messages in thread
end of thread, other threads:[~2017-09-24 16:44 UTC | newest] Thread overview: 18+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2017-04-04 22:00 Should records be able to mimic primitive types? Paul Eggert 2017-04-05 1:09 ` Stefan Monnier 2017-04-08 15:09 ` Philipp Stephani 2017-04-08 17:57 ` Stefan Monnier 2017-05-01 11:35 ` Philipp Stephani 2017-05-01 12:03 ` Stefan Monnier 2017-06-10 11:39 ` Philipp Stephani 2017-06-10 12:43 ` Eli Zaretskii 2017-06-12 15:07 ` Philipp Stephani 2017-06-12 17:00 ` Eli Zaretskii 2017-06-12 17:15 ` Stefan Monnier 2017-06-12 17:22 ` Eli Zaretskii 2017-06-12 17:47 ` Stefan Monnier 2017-06-12 17:40 ` Stefan Monnier 2017-06-16 18:42 ` Philipp Stephani 2017-06-16 19:07 ` Stefan Monnier 2017-09-24 14:47 ` Philipp Stephani 2017-09-24 16:44 ` Stefan Monnier
Code repositories for project(s) associated with this public inbox https://git.savannah.gnu.org/cgit/emacs.git This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).