unofficial mirror of bug-guile@gnu.org 
 help / color / mirror / Atom feed
* (< complex) and friends
@ 2008-08-11 21:03 Bill Schottstaedt
  2008-08-12  9:18 ` Neil Jerram
  0 siblings, 1 reply; 12+ messages in thread
From: Bill Schottstaedt @ 2008-08-11 21:03 UTC (permalink / raw)
  To: bug-guile

guile> (< 1.0+1.0i)
#t
guile> (< 2.0 1.0+1.0i)

Backtrace:
In standard input:
   2: 0* [< 2.0 {1.0+1.0i}]

standard input:2:1: In procedure < in expression (< 2.0 1.0+1.0i):
standard input:2:1: Wrong type: 1.0+1.0i
ABORT: (wrong-type-arg)


(Happens also with > <= >=)






^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: (< complex) and friends
  2008-08-11 21:03 (< complex) and friends Bill Schottstaedt
@ 2008-08-12  9:18 ` Neil Jerram
  2008-09-17 21:37   ` Neil Jerram
  0 siblings, 1 reply; 12+ messages in thread
From: Neil Jerram @ 2008-08-12  9:18 UTC (permalink / raw)
  To: Bill Schottstaedt; +Cc: bug-guile

2008/8/11 Bill Schottstaedt <bil@ccrma.stanford.edu>:
> guile> (< 1.0+1.0i)
> #t
> guile> (< 2.0 1.0+1.0i)
>
> Backtrace:
> In standard input:
>   2: 0* [< 2.0 {1.0+1.0i}]
>
> standard input:2:1: In procedure < in expression (< 2.0 1.0+1.0i):
> standard input:2:1: Wrong type: 1.0+1.0i
> ABORT: (wrong-type-arg)

My guess (without actually looking at the code) is that

- using < etc with complex numbers will always give a wrong type arg error

- the single arg case is being optimized before reaching the check for
a complex number.

What behaviour would you prefer?  (Perhaps to say that < etc. only
compare the real parts of the provided numbers?  Is there any
precedent for that in other Schemes or standards?)

      Neil




^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: (< complex) and friends
  2008-08-12  9:18 ` Neil Jerram
@ 2008-09-17 21:37   ` Neil Jerram
  2008-09-17 21:45     ` Bill Schottstaedt
                       ` (2 more replies)
  0 siblings, 3 replies; 12+ messages in thread
From: Neil Jerram @ 2008-09-17 21:37 UTC (permalink / raw)
  To: Bill Schottstaedt; +Cc: bug-guile

This is mostly for the record, as I'm afraid I don't have any fix yet...

2008/8/12 Neil Jerram <neiljerram@googlemail.com>:
> 2008/8/11 Bill Schottstaedt <bil@ccrma.stanford.edu>:
>> guile> (< 1.0+1.0i)
>> #t

> My guess (without actually looking at the code) is that

> - the single arg case is being optimized before reaching the check for
> a complex number.

My guess was correct.  This comes from < being implemented as a
scm_tc7_rpsubr, which means that there is an underlying C primitive
(scm_less_p) that takes 2 args, and the evaluator deals with calling
this however many times are needed.  When there's just 1 arg, the
evaluator shortcuts the process and returns #t.

Instead of just returning #t, I guess there should be a type predicate
call.  It's not obvious where one would store the type predicate
though, in the subr structure...

As a workaround, you could use:

(let ((libguile-< <))
  (set! < (lambda args
	    (or (null? args)
		(not (null? (cdr args)))
		(real? (car args))
		(error "wrong type arg" (car args)))
	    (apply libguile-< args))))

Would that help?

Regards,
     Neil




^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: (< complex) and friends
  2008-09-17 21:37   ` Neil Jerram
@ 2008-09-17 21:45     ` Bill Schottstaedt
  2008-09-18 13:59       ` Jon Wilson
  2008-09-18 19:02       ` Andy Wingo
  2008-09-18 17:59     ` Bill Schottstaedt
  2008-09-19 13:23     ` Bill Schottstaedt
  2 siblings, 2 replies; 12+ messages in thread
From: Bill Schottstaedt @ 2008-09-17 21:45 UTC (permalink / raw)
  To: Neil Jerram; +Cc: bug-guile

There are actually more problems in that area; for example:

guile> (< 2 1 1.0+3.0i)
#f

which perhaps should be an error also.  My druthers for the
one arg case is to simply disallow it -- why does Guile support
stuff like:

guile> (<)
#t







^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: (< complex) and friends
  2008-09-17 21:45     ` Bill Schottstaedt
@ 2008-09-18 13:59       ` Jon Wilson
  2008-09-18 19:02       ` Andy Wingo
  1 sibling, 0 replies; 12+ messages in thread
From: Jon Wilson @ 2008-09-18 13:59 UTC (permalink / raw)
  To: Bill Schottstaedt; +Cc: bug-guile, Neil Jerram

Say you want to both filter out most elements from a list and also make 
sure that the remaining elements are sorted.

(apply < (filter some-predicate original-list))

If (<) didn't evaluate to #t, then you'd have to put code in there to 
check the length of the value you get from filter, which makes things 
uglier.  Also, having (<) => #t doesn't  hurt anything.

Bill Schottstaedt wrote:
> There are actually more problems in that area; for example:
> 
> guile> (< 2 1 1.0+3.0i)
> #f
> 
> which perhaps should be an error also.  My druthers for the
> one arg case is to simply disallow it -- why does Guile support
> stuff like:
> 
> guile> (<)
> #t
> 
> 
> 
> 
> 





^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: (< complex) and friends
  2008-09-17 21:37   ` Neil Jerram
  2008-09-17 21:45     ` Bill Schottstaedt
@ 2008-09-18 17:59     ` Bill Schottstaedt
  2008-09-19  3:07       ` Jon Wilson
  2008-09-19 13:23     ` Bill Schottstaedt
  2 siblings, 1 reply; 12+ messages in thread
From: Bill Schottstaedt @ 2008-09-18 17:59 UTC (permalink / raw)
  To: bug-guile

A couple similar cases:

guile> (< 2 1 "hi") 
#f

guile> (* 0 "hi")     
0

On the (apply < ...) business, I'd rather get an error than have something
broken go by just because "it is prettier".  That null list is going to trip you...






^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: (< complex) and friends
  2008-09-17 21:45     ` Bill Schottstaedt
  2008-09-18 13:59       ` Jon Wilson
@ 2008-09-18 19:02       ` Andy Wingo
  1 sibling, 0 replies; 12+ messages in thread
From: Andy Wingo @ 2008-09-18 19:02 UTC (permalink / raw)
  To: Bill Schottstaedt; +Cc: bug-guile, Neil Jerram

On Wed 17 Sep 2008 23:45, "Bill Schottstaedt" <bil@ccrma.Stanford.EDU> writes:

> why does Guile support stuff like:
>
> guile> (<)
> #t

I was going to say it's in the standard, but on second look it only
specifies "(< x1 x2 x3...)". And:

    Welcome to MzScheme v372 [3m], Copyright (c) 2004-2007 PLT Scheme Inc.
    > (<)
    <: expects at least 2 arguments, given 0

(PLT Scheme Inc? Anyway.)

Perhaps better to follow others' lead in this respect.

Andy
-- 
http://wingolog.org/




^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: (< complex) and friends
  2008-09-18 17:59     ` Bill Schottstaedt
@ 2008-09-19  3:07       ` Jon Wilson
  2008-09-19 23:11         ` Neil Jerram
  0 siblings, 1 reply; 12+ messages in thread
From: Jon Wilson @ 2008-09-19  3:07 UTC (permalink / raw)
  To: bug-guile

Here's a different way to think about it that makes the (<) case, as 
well as perhaps (< 2 1 "hi"), make sense quite naturally.  < is a 
procedure that returns #f if any of its arguments is less than or equal 
to the preceding argument.  Otherwise, it returns #t.

This definition makes the case (< a b) extend quite naturally to (< a b 
c ...), as well as to (< a) and (<).

And anyway, what harm does (<) really do?  Why do you think that it is 
"broken"?

Many functions which expect a list (fold, map) or a number of arguments 
(+, *) accept an empty list or no args as degenerate cases, and give 
sensible results.  When you write a procedure which expects a list or 
uses a rest arg, you generally handle the degenerate cases gracefully 
(instead of raising an error).  Why should < not be the same?

Bill Schottstaedt wrote:
> A couple similar cases:
> 
> guile> (< 2 1 "hi") 
> #f
> 
> guile> (* 0 "hi")     
> 0
> 
> On the (apply < ...) business, I'd rather get an error than have something
> broken go by just because "it is prettier".  That null list is going to trip you...
> 
> 
> 
> 





^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: (< complex) and friends
  2008-09-17 21:37   ` Neil Jerram
  2008-09-17 21:45     ` Bill Schottstaedt
  2008-09-18 17:59     ` Bill Schottstaedt
@ 2008-09-19 13:23     ` Bill Schottstaedt
  2008-09-19 23:17       ` Neil Jerram
  2008-09-19 23:59       ` Jon Wilson
  2 siblings, 2 replies; 12+ messages in thread
From: Bill Schottstaedt @ 2008-09-19 13:23 UTC (permalink / raw)
  To: bug-guile

map does not accept no list:

guile> (map (lambda (a) a))

Backtrace:
In standard input:
   1: 0* [map #<procedure #f (a)>]

standard input:1:1: In procedure map in expression (map (lambda # a)):
standard input:1:1: Wrong number of arguments to #<primitive-generic map>
ABORT: (wrong-number-of-args)


+ and * have a "natural" identity (0 and 1), so it is not silly that (+ a) is
(+ a 0) and (+) is (+ 0 0), but #t does not strike me as a natural identity
for < -- (< 1 1) is #f.   But I hate these kinds of discussions, so I defer...






^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: (< complex) and friends
  2008-09-19  3:07       ` Jon Wilson
@ 2008-09-19 23:11         ` Neil Jerram
  0 siblings, 0 replies; 12+ messages in thread
From: Neil Jerram @ 2008-09-19 23:11 UTC (permalink / raw)
  To: Jon Wilson, Bill Schottstaedt, Andy Wingo; +Cc: bug-guile

2008/9/19 Jon Wilson <jsw@wilsonjc.us>:
> Here's a different way to think about it that makes the (<) case, as well as
> perhaps (< 2 1 "hi"), make sense quite naturally. [...]

Thanks everyone for discussing these cases.  It seems to me that
although it may seem curious, Guile's current behavior doesn't
actually cause any significant trouble, and so doesn't need fixing.

But I may well be wrong about the practical impact.  If there are
realistic scenarios where the current behaviour turns out to be
dangerous, or to matter in some way, please describe those, and I'll
look again.

Regards,
       Neil




^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: (< complex) and friends
  2008-09-19 13:23     ` Bill Schottstaedt
@ 2008-09-19 23:17       ` Neil Jerram
  2008-09-19 23:59       ` Jon Wilson
  1 sibling, 0 replies; 12+ messages in thread
From: Neil Jerram @ 2008-09-19 23:17 UTC (permalink / raw)
  To: Bill Schottstaedt; +Cc: bug-guile

2008/9/19 Bill Schottstaedt <bil@ccrma.stanford.edu>:
> map does not accept no list:
>
> guile> (map (lambda (a) a))
>
> Backtrace:
> In standard input:
>   1: 0* [map #<procedure #f (a)>]
>
> standard input:1:1: In procedure map in expression (map (lambda # a)):
> standard input:1:1: Wrong number of arguments to #<primitive-generic map>
> ABORT: (wrong-number-of-args)

Right.  The number of lists given to map should be the same as the
number of parameters the lambda takes.

Were you saying that this is a bug, or is this just to set up an
analogy with the following?

> + and * have a "natural" identity (0 and 1), so it is not silly that (+ a) is
> (+ a 0) and (+) is (+ 0 0), but #t does not strike me as a natural identity
> for < -- (< 1 1) is #f.   But I hate these kinds of discussions, so I defer...

The value of (<) seems natural to me... but I admit that I can't
explain really clearly why that is!

And then there's (and) and (or) !

Nevertheless, I still don't see any significant impact anywhere here.
Please explain further if you do.

Regards,
     Neil




^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: (< complex) and friends
  2008-09-19 13:23     ` Bill Schottstaedt
  2008-09-19 23:17       ` Neil Jerram
@ 2008-09-19 23:59       ` Jon Wilson
  1 sibling, 0 replies; 12+ messages in thread
From: Jon Wilson @ 2008-09-19 23:59 UTC (permalink / raw)
  To: bug-guile

Bill Schottstaedt wrote:
> map does not accept no list:
But it does accept the empty list, which is what I intended to say, but 
didn't make clear.

> 
> guile> (map (lambda (a) a))
> 
> Backtrace:
> In standard input:
>    1: 0* [map #<procedure #f (a)>]
> 
> standard input:1:1: In procedure map in expression (map (lambda # a)):
> standard input:1:1: Wrong number of arguments to #<primitive-generic map>
> ABORT: (wrong-number-of-args)
> 
> 
> + and * have a "natural" identity (0 and 1), so it is not silly that (+ a) is
> (+ a 0) and (+) is (+ 0 0), but #t does not strike me as a natural identity
> for < -- (< 1 1) is #f.   But I hate these kinds of discussions, so I defer...

A natural identity for a predicate like this is either #t or #f.  The 
choice is really left up to the implementor, but should probably match 
other implementations (at least those that have some sort of identity) 
for the sake of consistency, and should most especially match the 
language in the specification or the manual (which should match each 
other where they overlap, of course!).  I'm not too concerned with which 
way the degenerate case goes (except in that it matches language and 
convention), but I do feel that the degenerate case should not be an error.
Regards,
Jon




^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2008-09-19 23:59 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-08-11 21:03 (< complex) and friends Bill Schottstaedt
2008-08-12  9:18 ` Neil Jerram
2008-09-17 21:37   ` Neil Jerram
2008-09-17 21:45     ` Bill Schottstaedt
2008-09-18 13:59       ` Jon Wilson
2008-09-18 19:02       ` Andy Wingo
2008-09-18 17:59     ` Bill Schottstaedt
2008-09-19  3:07       ` Jon Wilson
2008-09-19 23:11         ` Neil Jerram
2008-09-19 13:23     ` Bill Schottstaedt
2008-09-19 23:17       ` Neil Jerram
2008-09-19 23:59       ` Jon Wilson

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).