• Why is it allowed to deduce from undefined?

    From ceving@21:1/5 to All on Fri Nov 10 00:21:41 2023
    The following looks like a contradiction to me:

    (if (if #f #f) #t #f) ;; => #t
    (equal? (if #f #f) #t) ;; => #f

    Why does Scheme allowed this? And why is it anything other than division by zero?

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Maciek Godek@21:1/5 to All on Fri Nov 10 01:40:27 2023
    piątek, 10 listopada 2023 o 09:21:43 UTC+1 ceving napisał(a):
    The following looks like a contradiction to me:

    (if (if #f #f) #t #f) ;; => #t
    (equal? (if #f #f) #t) ;; => #f

    Why does Scheme allowed this? And why is it anything other than division by zero?

    I don't think this behaviour would be consistent across the implementations, (and I don't think it's well-defined)

    The reason this might work on some implementations is that they define
    a special value called "undefined", which is "silent" when it's supposed to be displayed in the REPL.
    (I know that Guile does that)

    It can also be occasionally true that (eq? (if #f #f) (if #f #f)).

    Of course, this value isn't equal to #t, which is why the second equality is #f.
    But this isn't any more surprising than, say

    (if 5 #t #f) ;; => #t
    (equal? 5 #t) ;; => #f

    because in Scheme every value other than #f is considered "true" in the context of "if"
    (and since this special "unspecified" value is different from #f, it is also considered "true")

    BTW When it comes to "division by zero", then it is also an ambiguous phrase:

    (/ 2 0) ===>!error
    (/ 2.0 0) ===> +inf.0
    (/ 0.0 0) ===> +nan.0
    (/ -2.0 0) ===> -inf.0
    (/ 2 0.0) ===> +inf.0
    (/ 2 -0.0) ===> -inf.0
    (/ 2.0 -0) ===> +inf.0

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Maciek Godek@21:1/5 to All on Fri Nov 10 03:07:19 2023
    piątek, 10 listopada 2023 o 11:17:32 UTC+1 ceving napisał(a):
    Maciek Godek schrieb am Freitag, 10. November 2023 um 10:40:29 UTC+1:

    some implementations [...] define a special value called "undefined"

    in Scheme every value other than #f is considered "true"
    I think this is the problem. Undefined must not be a value or any function which gets passed an undefined value must throw an error.

    I don't think it's mentioned anywhere in any RnRS.

    R5RS says this: |If the value of an expression is said to be ``unspecified,'' then the expression must evaluate to some object without signalling an error, but the value depends on the implementation; this report explicitly does not say what value should
    be returned."

    Maybe this can be solved if the evaluation of "undefined" throws an error?

    Some implementations that I tested produce a warning or an error when you're trying to use a one-armed if in the context that requires a value to be produced.

    A value "undefined" can be either true or false, because it is not defined. If it behaves sometimes like true and sometimes like false, it gets spooky. It must not behave at all.

    I haven't ever seen it behaving as #f anywhere. And indeed, the standard says: "Of all the standard Scheme values, only #f counts as false in conditional expressions"
    so if this value is distinct from #f, it cannot behave as #f.

    (I know that Kawa makes a deviation there, and allows another value to be false in the context of "if",
    namely the #!null value - which makes sense given its JVM interop, and which I personally found convenient,
    although I realize that different people's opinions on that matter will vary)

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From ceving@21:1/5 to Maciek Godek on Fri Nov 10 02:17:29 2023
    Maciek Godek schrieb am Freitag, 10. November 2023 um 10:40:29 UTC+1:

    some implementations [...] define a special value called "undefined"

    in Scheme every value other than #f is considered "true"

    I think this is the problem. Undefined must not be a value or any function which gets passed an undefined value must throw an error. Maybe this can be solved if the evaluation of "undefined" throws an error?

    A value "undefined" can be either true or false, because it is not defined. If it behaves sometimes like true and sometimes like false, it gets spooky. It must not behave at all.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From ceving@21:1/5 to Maciek Godek on Fri Nov 10 03:33:00 2023
    Maciek Godek schrieb am Freitag, 10. November 2023 um 12:07:22 UTC+1:

    R5RS says this: |If the value of an expression is said to be ``unspecified,'' then the expression must evaluate to some object without signalling an error,

    I am wondering why it has been defined this way.

    I would say the opposite should be right: it must signal an error.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Tristan Wibberley@21:1/5 to ceving on Sat Mar 2 12:52:27 2024
    On 10/11/2023 11:33, ceving wrote:
    Maciek Godek schrieb am Freitag, 10. November 2023 um 12:07:22 UTC+1:

    R5RS says this: |If the value of an expression is said to be ``unspecified,'' then the expression must evaluate to some object without signalling an error,

    I am wondering why it has been defined this way.

    I would say the opposite should be right: it must signal an error.

    First, I'm a newbie with Scheme, so I don't know all the names and nuances.

    You're thinking of pure functional languages. In Scheme, which has a
    certain imperative essence, (if...) can give *unspecified* and you can
    signal an error in that condition. It's like 'Control.Monad.when' in
    Haskell or 'if' in C, except that it also allows you to use it like 'if'
    in Haskell if you want to.

    That makes (if...) useful for inserting conditional actions in a
    sequence of them.

    You can always give a second argument if you are slow and steady enough.

    You can write a strict (if...) that requires two arguments but you must
    use a macro, I think, rather than (define...). I think you can force all (if...) uses in your files to be so strict if you want to make sure
    you've done that everywhere but I'm not so sure scheme makes it hard to subsequently liberalise.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Tristan Wibberley@21:1/5 to ceving on Sat Mar 2 12:17:02 2024
    On 10/11/2023 08:21, ceving wrote:
    The following looks like a contradiction to me:

    (if (if #f #f) #t #f) ;; => #t
    (equal? (if #f #f) #t) ;; => #f

    Why does Scheme allowed this? And why is it anything other than division by zero?

    In Guile:
    *There seems to be a common object available with the name
    "*unspecified*" which 'if' uses for an unspecified branch.

    * It's 'equal?' to itself as well as 'eq?' and 'eqv?' - I didn't try
    others.

    * It's distinct from both end-of-list and #f.

    I would expect division by zero only should 'if' be defined at least in
    part by division.

    --
    Tristan

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)