3 ms·
Actually on closer examination the bug was subtler than that. I did check whether the incoming request was allowed to modify each field it was trying to modify
by pg 18y ago
Actually on closer examination the bug was subtler than that. I did check whether the incoming request was allowed to modify each field it was trying to modify. But the code that decided whether a field was modifiable was using a four variable list to destructure on a five value description of the field. This caused the variable determining whether a field was modifiable to be bound instead to the value saying whether or not it should be displayed. Which meant every field that was displayed was modifiable.
- IHackedHN 18y agoThat's actually pretty interesting to me. I didn't notice that when I was looking at the Hacker News code. Perhaps Arc shouldn't allow a list to be destructured except with a list of the same length? Allowing differing lengths seems likely to cause subtle bugs like this.
- dfranke 18y agoFor a language of my own design I'd agree, but I think that would be rather severely contrary to the spirit of Arc.
- pg 18y agoI generally tried to err on the side of flexibility, and it seemed more flexible not to require the lengths to match. I could imagine cases where you might want to use patterns both longer and shorter than the lists they were matched against. On the other hand, I'm not sure I've ever ended up taking advantage of this.
- IHackedHN 18y agoMaybe you could use something along the lines of &rest to optionally support a pattern shorter than the matched list?
- pg 18y agoYou could do that with a dot now. The trouble is, you end up creating a junk variable: arc> (let (x . y) '(a b c) y) (b c)
- IHackedHN 18y agoMaking users create junk variables seems to me like better behavior than the current implicit behavior. It's your decision, though, of course. Anyway, is it safe to assume that you're not going to try to get me arrested or anything?
- pg 18y agoI feel like unnecessary variables are extra bad; in cognitive terms they feel like they add more than one token to the length of a program. Do you mean your username is actually descriptive? Since you are obviously a Lisp hacker, I'd be happy to have a truce. Can you send me an email?
- IHackedHN 18y agoThank you. I've sent you an email.
- simonb 18y agoBut at the same time this junk variable is code-as-documentation professing the incomplete destructuring is intentional. You could go a step further and have a special ignore symbol, (for instance * ) like most pattern matching languages/libraries have with the property that it can appear multiple times: arc> (let (x * y . *) '(a b c d e f) y) c
- wingo 18y agoYou don't have to name it. It could be _. (let (x . _) '(a b c) x) It sounds like you're treating list destructuring like CL's mvbind. While it's subjective of course, I'm more comfortable with the runtime doing what I mean when I control the number of values (modulo `(apply values ...)'). I'm not comfortable with destructuring values "flexibly" when I don't control the data coming in.
- jganetsk 18y agoFor all people who say good programmers don't make type errors, here's a counterexample.
- pg 18y agoIt's an interesting question whether it's really a type error to mismatch the sizes of things. I feel like sometimes it is and sometimes it isn't.
- jganetsk 18y agoAgreed. But it sounded like, in this case, you were using a list to represent that which would have been represented by a record in a statically typed language. I'm imagining you'd have some kind of Field record type, with isDisplayable and isModifyable fields. Instead of destructuring as a list (or tuple), you would explicitly look for isDisplayable and isModifyable. But, of course, you could still make the same mistake in a statically typed language if you chose not to set up the data structure this way.
- KayEss 18y agoIn a strongly typed language one would normally want to reify the number in the type system whenever possible, i.e. the use of (a,b,c,d,e) rather than [a,b,c,d,e] in Haskell (that's a 5-tuple rather than a 5 element list). I think that people used to dynamic programming languages would normally pick the list rather than the tuple simply because it at first appears easier. I think Dijkstra had something to say on that particular subject :)