Scheme初学者练习

时间:2015-05-10 00:22:32

标签: scheme

我今天第一次尝试使用某个Scheme,我想尝试编写一些函数,这些函数可以让我对基本语法有所了解,但由于某种原因(也许是因为我缺乏睡觉)它比我预期的要困难得多。

首先,我想创建一个显示列表中每个项目的函数。基本上我会给它:

(mydisplay '(3 4 "dog" 9)) and it would display those items.

接下来我想在Scheme中编写相当于这个C ++ snipet的内容:

for (int i = 6; i < 25; i+=6)
{
  cout << i << endl;
}

任何提示或帮助将不胜感激!很抱歉可能是waaaayyy太简单的问题,但我似乎无法掌握一些语法

谢谢!

3 个答案:

答案 0 :(得分:1)

当我第一次看Lisp时,我认识了6种语言并且经历过学习新语言非常简单。不幸的是,我的经历并不是如何学习一门新语言,因为当我认为我知道6种语言时,事实是我知道有6种方言来自common ancestor called Algol。 Perl,Java,C ++几乎是相同的语言,如果你知道一个,你知道如何在一天内完成另一个。

你需要找到一本好书或资源,你可以遵循并学习Scheme,好像你以前从未有过编程语言。您可以查看Rosetta Code for Scheme来比较一些算法在Scheme中的完成情况,但即使您看到任务具有相似的结构,它们往往会做很多不同的事情。

;; roll your own using recursion
(define (my-display lst)
  (when (pair? lst)
    (display (car lst))
    (newline)
    (my-display (cdr lst))))

;; one with higher order procedures
(define (my-display lst)
  (for-each (lambda (e) 
              (display e)
              (newline))
            lst))


;; Close to your algol for loop 
(let make-number ((count 6))
  (if (< count 25)
      (begin
        (display count)
        (newline)
        (make-number (+ count 6)))
      'return-value))

;; A better approach 
;; make a list of the numbers based on start end and step
(define (make-range start end step)
  (let rec ((cnt start))
    (if (> cnt end)
        '()
        (cons cnt (rec (+ cnt step))))))

(my-display (make-range 6 25 6)) ; prints the numbers

;; one with higher order procedures
;; uses SRFI-1 List Librarys unfold instead of named let
(define (make-range start end step)
  (unfold (lambda (x) (< end x))
          values
          (lambda (x) (+ x step))
          start))

我不建议您使用do循环。使用命名的let或更高阶的程序并将打印部件保留在外面。

我非常喜欢SICP video lectures。它们有点古老,因此是今天版本的旧版本,但是有人制作了support for it in racket。当您了解一种lisp语言时,它很容易学习a different dialect,尤其是以后的Scheme报告。

答案 1 :(得分:0)

> (define (mydisplay xs)
    (for-each (lambda (x) (display x) (newline)) xs))
> (mydisplay '(3 4 "dog" 9))
3
4
dog
9
> (do ((i 6 (+ i 6)))
      ((not (< i 25)))
    (display i) (newline))
6
12
18
24

答案 2 :(得分:0)

正如您将发现的,有许多方法可以在Scheme中循环。我将从最基本的,即尾递归调用开始。

for (int i = 6; i < 25; i+=6)
{
  cout << i << endl;
}

(let loop ([i 6])
  (if (< i 25) 
      (begin
        (display i)
        (newline)
        (loop (+ i 6)))))

上面使用的构造称为named let,您将在Scheme代码中一遍又一遍地看到它。

请注意,上面使用单臂if。如果您的Scheme实施具有when,则变为:

(let loop ([i 6])
  (when (< i 25) 
    (display i)
    (newline)
    (loop (+ i 6))))