4

This is the link that I'm current teaching myself Scheme, http://www.ccs.neu.edu/home/dorai/t-y-scheme/t-y-scheme-Z-H-1.html

According to the author, enter image description here

Then I tried a minimal example

(define (check-p x)
  (if (>= x 0)
      (display 1)))

, and DrScheme gave me errors:

if: bad syntax (must have an "else" expression) in: (if (>= x 0) (display 1))

If I put an extra statement within the if statement, then it works. But I don't get it, why do we need an extra statement there? The code statement above made sense to me. If the number is greater than 0, display a 1, otherwise do nothing. Any idea?

Thanks,

roxrook
  • 13,511
  • 40
  • 107
  • 156
  • hmmm, works in the online repl: http://sisc-scheme.org/sisc-online.php – davin Apr 22 '11 at 00:10
  • 3
    Trying to learn from the scheme-in-fixnum-days text is not a good idea, why didn't you start from [HtDP](http://htdp.org/) instead? – Eli Barzilay Apr 22 '11 at 02:31
  • See also "Why is one-armed if missing from Racket": http://stackoverflow.com/questions/10863192/why-is-one-armed-if-missing-from-racket – soegaard Jun 03 '12 at 19:42

3 Answers3

5

DrScheme includes several "teaching" dialects of Scheme which are limited subsets of (they impose more restrictions than) standard R5RS or R6RS Scheme. The dialect that you are using probably restricts you to using if statements in which you provide values for both branches. In fact, I checked just now, and it looks like all of the "teaching" dialects forbid you from using an if statement with only one branch.

This is intended to help you learn to program in an applicative (sometimes known as functional) style of programming, in which you do not rely upon side effects but instead compute values merely by applying functions and returning results from them. In the applicative style, with no side effects, the only result of a statement is to return a value. An if statement that does not return a value in one of its branches would have no meaning for that case; it would not be useful, and in fact would cause undefined behavior when you tried to use the value returned by that if statement. In the applicative style, every statement in the language is an expression, evaluated for the value it computes, not the side effects that it causes.

If you are using display to provide output, you are not using a purely applicative style. That's perfectly fine, but many introductions to Scheme like to start by presenting an applicative style, because it is much easier to reason about and learn how everything actually works.

Since you're not working from a text that assumes an applicative style of programming, however, I'd recommend choosing a different dialect. Under the "Language" menu, select "Choose Language", and then I would recommend choosing either "R5RS" (which is intended to be as close to the standard as possible), or "Pretty Big" (which is R5RS plus a bunch of handy PLT extensions).

Brian Campbell
  • 322,767
  • 57
  • 360
  • 340
  • 3
    There are *so* many things wrong with this answer, that I'll probably need a few comments. (a) DrScheme is called DrRacket now; (b) but in any case, it's not a language just a tool, the language is Racket; (c) the limitation is in most languages that racket implements, including the default `#lang racket`, not only in the teaching languages; (d) "applicative" is is pretty much a vacuous term, it's used by exactly one book, and "functional" is *far* more common, far enough that it doesn't make sense to use something else; – Eli Barzilay Apr 22 '11 at 02:10
  • 2
    (e) the intention of forbidding a single-branch `if` is much more than just teaching functional style, it is just bad style to mix things this way (overloading the two uses of `if`), instead, Racket has moved on to enforcing two sided `if`s and for one-sided conditionals it uses `when` and `unless` that also allow multi expression bodies and have a much more obvious (side-effect) meaning for readers of your code; (f) in Racket, an `if` with one result certainly has a well-defined meaning -- it returns either that result or `void` -- and that's almost never what newbies want. – Eli Barzilay Apr 22 '11 at 02:14
  • 2
    (g) even when you use side-effects (whatever the opposite of "applicative" is), an even when you have one-sided `if`s, they are still `if` *expressions*; (h) in Racket (or pretty much any scheme implementation) there are no distinction between expressions and statements -- the latter doesn't exist (at least not in the sense that you're thinking about); (i) using "Pretty Big" is *extremely bad advice* -- it is just a legacy language, and an ancient one now, and should not be used for any real work (or studying); – Eli Barzilay Apr 22 '11 at 02:21
  • 1
    (j) characterizing "Pretty Big" as "R5RS plus a bunch of [stuff]" is also wrong, since it's different from R5RS in a number of important ways; (k) recommending use of the R5RS language is also a pretty bad advice -- Racket's R5RS is very strict, which means that you get *exactly* R5RS, and many people walk out from that experience thinking that it's a useless toy language (and wrt R5RS, that conclusion is correct). – Eli Barzilay Apr 22 '11 at 02:23
  • @Eli (a) From his comments, Chan had mentioned using DrScheme 4.2.5, from when it was still called DrScheme. I was trying to help him use what he had. (b) When did I say DrScheme was a language? (c) I checked DrScheme 4.2.5, and all of the "How To Design Programs" languages refused one-branch "if", while R5RS, "Pretty Big", and EOPL allowed it. As I said, I'm discussing DrScheme, not Racket. (d) Tomayto-tomahto. It's no more vacuous than "functional", and I've seen a lot of people confused by that term as well. Hence providing both terms. – Brian Campbell Apr 22 '11 at 03:00
  • @Eli (e) Sure, it's better style to use `when` and `unless`. I was trying to explain one pedagogical purpose for forbidding one-armed if, not necessarily all. (f) "If yields a false value and no is specified, then the result of the expression is unspecified." From R5RS and R6RS (g)/(h) You're right, I was unclear here. I was trying to draw on the distinction that he may have known between statements and expressions from other languages, but that may be more confusing than clarifying. – Brian Campbell Apr 22 '11 at 03:14
  • @Eli (i)/(j) Chan mentioned that he was using Teach Yourself Scheme in Fixnum Days, which uses the MzScheme dialect. I believe that "Pretty Big" is the closest language available to that used in the book he's reading, so I figured it would be the least confusing for him. (k) You're right, R5RS is fairly limited, but it's the language most likely to be in common with other sources he looks at on Scheme. What language would you recommend he use? The student languages are clearly confusing him because they aren't what other sources teach. – Brian Campbell Apr 22 '11 at 03:20
  • @Eli I agree, I may not have explained perfectly the reason why the language he was using does not have one-branch `if`. If you feel like doing a better job explaining that, I encourage you to do so. The rest of your complaints are based on the fact that I was trying to help him use the tool he has and the book he's reading, rather than evangelizing the new tool and language Racket. I have only ever used DrSchem, and have not used Racket, so that's not something I can comment on. – Brian Campbell Apr 22 '11 at 03:29
  • I'll avoid a bulletized reply; some quick points: "applicative" is so unused that it's much more than pronunciation -- like any technical field, CS (and programming) has certain common terms that should be followed if you want to be understood; *any* specific implementation is better than R5RS, Racket happens to have several; recommending pretty-big is a bug, nothing less; the teaching languages do have some restrictions, but this one is not something that they *add*, it's part of the default language (`#lang scheme` in v4.x). – Eli Barzilay Apr 22 '11 at 03:30
  • @Eli You haven't responded to my most important point. What language would you suggest he use if he's learning from Teach Yourself Scheme in Fixnum Days? As far as I can tell, Pretty Big is the closest one to the language used in that book, but I could be wrong. I used to use the `mzscheme` language, but that doesn't seem to be available any longer. If that restriction is present in `#lang scheme`, then I don't think that will be very useful to him. – Brian Campbell Apr 22 '11 at 03:44
  • 1
    @Brian Campbell -- I can't answer that, since the question presupposes that he should get a recommendation for a language for TYSiFN but in fact that text is antique enough that it should just not be used. It was written in days where unhygienic macro systems were common, and `load` was not the dirty word it is now. So the right answer is that anyone that asks anything about doing TYSiFD should be encouraged away from it. (BTW, this was discussed on the Racket mailing list last month, see the thread around [this message](http://lists.racket-lang.org/users/archive/2011-March/044955.html).) – Eli Barzilay Apr 22 '11 at 16:27
3

What version of Scheme are you using? DrScheme 372 has no problem with an if statement without an else clause.

In any case, Scheme provides the when and unless operators, which act like an if statement that has (respectively) only a then-branch or only an else-branch. Given that, there's no pressing need for the if statement to have its else-branch be optional.

Lily Ballard
  • 182,031
  • 33
  • 381
  • 347
  • @Kevin Ballard: I'm using DrScheme 4.2.5 on Windows. I chose the default language under "Language" tab, but I don't know how to check what version of Scheme I'm using. Thank you. – roxrook Apr 22 '11 at 00:17
  • Note also that every expression in Scheme evaluates to a value. So there's no such thing as "otherwise do nothing"; you have to say "otherwise return such-and-such a value", such as `#f`. [R5RS](http://www.schemers.org/Documents/Standards/R5RS/HTML/r5rs-Z-H-2.html#%_toc_%_sec_4.1.5) and [R6RS](http://www.r6rs.org/final/html/r6rs/r6rs-Z-H-2.html#node_toc_node_sec_11.4.3) both say that you can have an `if` without an else clause, but the result is unspecified. Maybe you are in some starter language of DrScheme, in which it is preventing you from using bad style. – dfan Apr 22 '11 at 00:19
  • @dfan: Every expression evaluates to a value? I don't get this point. For example, if I put an extra statement says, a silly `0`, then what does this statement do? – roxrook Apr 22 '11 at 00:23
  • It returns the value of the then branch if your conditional is true and 0 otherwise. – Rachel Shallit Apr 22 '11 at 00:26
  • 1
    Are you familiar with a C-like language? You might want to think of `if` in Scheme as more like the ternary operator in C-like languages than the if statement in C-like languages. – Rachel Shallit Apr 22 '11 at 00:30
  • @rshallit: Thank you. I think I kinda got it now. – roxrook Apr 22 '11 at 00:58
0

try to change this one:

(define (check-p x)
(if (>= x 0)
(display 1)))

to this:

(define (check-p x)
(when (>= x 0)
(display 1)))

In Racket it should work

AuthorProxy
  • 7,946
  • 3
  • 27
  • 40