2016-05-10 4 views
1

Я учусь, как использовать структуры с MIT-схемой, и я пытался «перевести» следующую функцию от C к схеме:Изменение структурных полей внутри функции?

static inline void 
body_integrate(struct body *body, double dt) 
{                   
    body->vx += dt * body->fx/body->mass; 
    body->vy += dt * body->fy/body->mass; 
    body->rx += dt * body->vx; 
    body->ry += dt * body->vy;           
} 

Со следующими определениями

(define-structure body rx ry vx vy fx fy mass) 

(define integrate (lambda (body dt) (
    (set-body-vx! body (+ (body-vx body) (* dt (/ (body-fx body) (body-mass body))))) 
    (set-body-vy! body (+ (body-vy body) (* dt (/ (body-fy body) (body-mass body))))) 
    (set-body-rx! body (+ (body-rx body) (* dt (body-vx body)))) 
    (set-body-ry! body (+ (body-ry body) (* dt (body-vy body)))) 
))) 

я получаю:

MIT/GNU Scheme running under GNU/Linux 
Type `^C' (control-C) followed by `H' to obtain information about interrupts. 

Copyright (C) 2011 Massachusetts Institute of Technology 
This is free software; see the source for copying conditions. There is NO warranty; not even for 
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 

Image saved on Thursday November 5, 2015 at 8:44:48 PM 
    Release 9.1.1 || Microcode 15.3 || Runtime 15.7 || SF 4.41 || LIAR/x86-64 4.118 || Edwin 3.116 
;Loading "body.ss"... done 

1 ]=> (define b (make-body 1.0 1.0 2.0 2.0 10.0 10.0 0.1)) 

;Value: b 

1 ]=> (integrate b 5.0)  

;The object #!unspecific is not applicable. 
;To continue, call RESTART with an option number: 
; (RESTART 2) => Specify a procedure to use in its place. 
; (RESTART 1) => Return to read-eval-print level 1. 

2 error> 

у меня есть чувство, что я не могу сделать несколько (set-body-X! ...) внутри integrate. Но как я должен это сделать?

+1

У вас есть дополнительный набор парсенов вокруг тела вашей лямбды. Удалите их, и ваш код должен работать нормально. –

+0

Возможный дубликат [Я получил «приложение схемы не процедуру» в последнем рекурсивном вызове функции] (http://stackoverflow.com/questions/12183096/i-got-scheme-application-not-a-procedure- в-последней рекурсивного вызова в своем-фу) –

ответ

3

Открывающиеся круглые скобки справа в конце первой строки неверны, на Схеме, когда вы окружаете выражение с помощью (), оно рассматривается как приложение-функция, и это не то, что вы хотите здесь.

В любом случае было бы более идиоматично создавать новую структуру с новыми значениями, вместо того, чтобы изменять параметр - помните, что схема поощряет стиль функционального программирования, и вам следует избегать мутирующих значений; кроме того, модификация параметра считается плохой стиль на большинстве языков программирования (это нормально в C, хотя). Попробуйте следующее:

(define (integrate body dt) 
    (make-body (+ (body-rx body) (* dt (body-vx body))) 
      (+ (body-ry body) (* dt (body-vy body))) 
      (+ (body-vx body) (* dt (/ (body-fx body) (body-mass body)))) 
      (+ (body-vy body) (* dt (/ (body-fy body) (body-mass body)))) 
      (body-fx body) 
      (body-fy body) 
      (body-mass body))) 
Смежные вопросы