emacs-devel
[Top][All Lists]
Advanced

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

Re: [PATCH] Add new lisp function length= with bytecode support


From: Ken Raeburn
Subject: Re: [PATCH] Add new lisp function length= with bytecode support
Date: Fri, 10 Mar 2017 05:20:25 -0500

On Mar 6, 2017, at 19:29, Gdobbins <address@hidden> wrote:

> Attached is a new patch which implements length= and the <, >, <=, >= 
> variants in lisp. They aren't as efficient as the length= from the previous 
> patch, especially in cases like (length= list1 list2). Since these functions 
> can't share a bytecode with their non-length counterparts I don't know 
> whether the trade off of a compiler macro for them is worth it. With the lisp 
> functions the resulting bytecode would be both larger, and if none of the 
> sequences are lists, slower as well.
> 
> -- Graham Dobbins

Looks like interesting work.  A few comments:

The &rest arguments for the functions might be better called 
“sequences-or-numbers”, because the documentation as displayed by 
describe-function will show the parameter names.

> length< is a Lisp function in ‘/private/tmp/gdobbins.el’.
> 
> (length< &rest SEQUENCES)
> 
> Compare the lengths of sequences with numbers.

The documentation indicates that numbers are permitted in the argument list, 
but nthcdr won’t be happy with 3.0, or 3.1416, or 1.0e+INF, or 0.0e+NaN.

The tail-compare-or-swap and tail-adjust logic is hard to follow (especially 
with no comments).  Maybe it would be more straightforward to just have the 
macro check if the comparison symbol is = and do one thing, or < to do another, 
etc.  Maybe even two different implementations, one for = without the 
tail-adjust bit and one for < and <= with it.  And the functions working by 
argument list reversal can just be their own functions, or use an entirely 
separate macro.

I gather internal--length-compare (specifically the nthcdr bit) works for “less 
than” but not for “greater than”, and thus the reversal approach is actually 
required, not just a way to reduce the quantity of code generated.  Is that 
correct?

The doc string for “length<” talks about wanting its first argument to be a 
non-list.  I take it that’s because it'll always compute the length of a list 
in that position.  But I think
  (length< some-big-list 5)
could still limit the work it does by using nthcdr, couldn’t it?  Implement it 
the same as:
  (not (length< 4 some-big-list))
At least, when the number is known to be an integer.
I think it’s if both arguments are lists, that’s when you’re still stuck 
getting the real length of at least one of them.  (More than two arguments gets 
more complicated, but there are additional use cases where unbounded “length” 
calls can be avoided.  I don’t know if the case of more than two arguments 
comes up often enough to bother.)

The doc string’s attempt to refer to arguments that could be sequences or 
numbers, and which get treated differently depending on which they are, is a 
bit awkward.  Maybe something like:
  Compare numbers and lengths of sequences.
  Arguments that are numbers are compared directly; for sequences, their 
lengths are used.
  Return t if each number or length is `>’ to the next.
I’m still not wild about it.  Constructing a sentence from the 
comparison-operator’s symbol name is just going to be awkward, I think, 
compared to the doc strings for “>” or “length” which sound fairly natural.  
It’d be better to actually write out “greater than” and such.

The doc string mention of “more efficient” is ambiguous; more efficient than 
what?  Are you comparing against using “length” and “>”?  Or are you comparing 
different ways the arguments to the function might be arranged?

Ken


reply via email to

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