Arc Forumnew | comments | leaders | submitlogin
4 points by cchooper 6107 days ago | link | parent

I'm think the problem he's referring to is:

  (find [< (len _) 3] '((1 2 3 4) (5 6 7 8)))
  => nil

  (find [< (len _) 3] '(nil (1 2 3 4) (5 6 7 8))
  => nil
Does Arc have a simple solution to this that I'm missing (other than reimplementing find that is)?


3 points by kennytilton 6107 days ago | link

Oh. We had the same question in re hash tables where one might want to distinguish between a key stored with the value nil and a missing key, not possible with Arc since it does not store the key when the value is nil, and pg replied that not being able to distinguish the two was not an issue in practice. Perhaps the same "show us the use case" rule applies here?

Otherwise, just use mem?

-----

1 point by rkts 6107 days ago | link

As I said, there are plenty of half-baked solutions to this problem, and mem is an example; it distinguishes two possibilities by returning either a cons or nil. What I'm looking for is a general abstraction that obviates the need for such kludges.

-----

5 points by kennytilton 6107 days ago | link

You say "kludge", I (and apparently pg) say "you do not have a use case, this is an imagined problem" and one should not build languages around imagined problems, you end up with Java. I asked for a use case and you have not supplied one. I am not saying one does not exist, I am saying any discussion of a "fix" is meaningless until we have a target.

Consider again the very similar case of Arc tables being unable to differentiate "key not found" from "key associated with nil". I was halfway thru a brilliant retort to pg on this with an example from my own real live working code (where I used CL's ability to differentiate the cases) when I realized Doh! I totally did not need the capability (and man was I happy I realized that before trying to school pg <g>).

The danger in posting a use case is that all the ones you offer will turn out to be better handled some other way. Then you will know why your bloated fix is not in Arc.

-----

4 points by rkts 6107 days ago | link

I knew someone was going to ask for a use case, which is why I gave an example that (I thought) was so basic as not to require one: find a list of a given length. If you can't solve such a simple problem simply, that indicates to me a fundamental weakness.

Besides the kludginess of mem, consider how easy it is to screw up with find. How do you verify that a list doesn't contain any nils? Without a type system to enforce such invariants you get the worst kind of bugs: those that are manifest only once in a blue moon and present no obvious diagnosis.

That similar problems arise with other uses of nil suggests to me that we're missing an abstraction.

Let me turn this around. Is there any code that would become more verbose with my suggestion? You may think it only helps in weird edge cases (which I dispute), but what do we lose by incorporating it?

-----

4 points by kennytilton 6106 days ago | link

<cough> No, the /code/ you offered was looking for a list with less than a given length with the understanding that nils might be in the list. The test for a list without nils is:

   (all idfn lst)
Is it a kluge to state the test positively? Actually, negative tests are understood to be harder on the cognitive system to get right.

Meanwhile, are you sure (member nil lst) is a kluge? It sure looks readable, and it sure does work. What exactly bothers you about that?

Meanwhile, a use case means your are not just running code samples you typed in at the repl, it means you are trying to solve a problem using a computer and something came up. So here we are after iterating over the members of the library and we built up a list of overdue books per member -- no, that would not have nils, that would have an assoc entry (bob . nil). Hmmm... can you help me here, I cannot think of one.

You have not responded to the very similar example of tables. Correct, one cannot distinguish the absence of a key from a key added with the value nil. A use case is not a couple of lines of code proving that, a use case is a lookup on drivers license number during a traffic stop and...?

My point you may have missed is that without a use case not perfectly well expressed with either of the two solutions I offered above, the fundamental weakness is in offering a theoretical functional gap in a language as if it were a gap in a language.

Recall that pg is already on record as wanting things that are problems in practice, that this is a hacker's language, not a strait jacket language like C++ or Java with all sorts of theoretical angst over untyped variables.

The problem, btw, of putting an air bag in the trunk of a car is the added weight. :)

-----

1 point by byronsalty 6106 days ago | link

In practice I imagine one would just use a known symbol like 'removed mid list/tree instead of blindly using a nil. But this is much less fun.

-----

2 points by kennytilton 6104 days ago | link

Puzzled. Do you mean the nils would arise because non-nil entries would be changed to nil as they were (somehow) processed? Just delete the cons:

   (= (cdr prior-kill-me) (cdr kill-me))
instead of:

   (= (car kill-me) nil)
Otherwise you are forever iterating over the now irrelevant cons,

-----