I am learning how to use structures with MIT-scheme and am trying to "translate" the following function from C to scheme:
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;
}
With the following definitions
(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))))
)))
I get:
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>
I have the feeling I can't do multiple (set-body-X! ...) inside integrate. But then how should I proceed to do this?
The opening parentheses right at the end of the first line is incorrect, in Scheme when you surround an expression with () it's treated as a function application, and that's not what you want here.
Anyway, it'd be more idiomatic to create a new structure with the new values, instead of modifying a parameter - remember, Scheme encourages a functional programming style, and you should avoid mutating values; besides modifying a parameter is considered bad style in most programming languages (that's ok in C, though). Try this:
(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)))
Related
I have my string in clsp format : "(a (q 2 (i (= (sha256 11) 5) (q 4 (c 2 (c 23 (c 47 ()))) ()) (q 8 (q . 'Bad password'))) 1) (c (q . 51) 1))"
When I entered it on this website conversion,(https://pawket.app/#/) in clvm section.
Result (Translated): ff02ffff01ff02ffff03ffff09ffff0bff0b80ff0580ffff01ff04ffff04ff02ffff04ff17ffff04ff2fff80808080ff8080ffff01ff08ffff018c4261642070617373776f72648080ff0180ffff04ffff0133ff018080
Could you help me to find the conversion algorithm? I have tried to get the byte format, but it didn't succed.
How are assoc and assq implemented in Scheme?
So what is the intern code of those two procedures?
Ultimately, it doesn't matter how it's implemented as long as it adheres to the behaviour specified in the standard (see section 6.4 of r7rs small).
In Guile, it looks like assq is implemented like this:
SCM_DEFINE (scm_assq, "assq", 2, 0, 0,
(SCM key, SCM alist),
"#deffnx {Scheme Procedure} assv key alist\n"
"#deffnx {Scheme Procedure} assoc key alist\n"
"Fetch the entry in #var{alist} that is associated with #var{key}. To\n"
"decide whether the argument #var{key} matches a particular entry in\n"
"#var{alist}, #code{assq} compares keys with #code{eq?}, #code{assv}\n"
"uses #code{eqv?} and #code{assoc} uses #code{equal?}. If #var{key}\n"
"cannot be found in #var{alist} (according to whichever equality\n"
"predicate is in use), then return #code{#f}. These functions\n"
"return the entire alist entry found (i.e. both the key and the value).")
#define FUNC_NAME s_scm_assq
{
SCM ls = alist;
for(; scm_is_pair (ls); ls = SCM_CDR (ls))
{
SCM tmp = SCM_CAR (ls);
SCM_ASSERT_TYPE (scm_is_pair (tmp), alist, SCM_ARG2, FUNC_NAME,
"association list");
if (scm_is_eq (SCM_CAR (tmp), key))
return tmp;
}
SCM_ASSERT_TYPE (SCM_NULL_OR_NIL_P (ls), alist, SCM_ARG2, FUNC_NAME,
"association list");
return SCM_BOOL_F;
}
#undef FUNC_NAME
Which is the C equivalent of (excluding some type checks):
(define (assq key alist)
(let loop ((ls alist))
(if (pair? ls)
(let ((tmp (car ls)))
(if (eq? (car tmp) key)
tmp
(loop (cdr ls))))
#f)))
In elisp to replace an occurrence of a string in a buffer I would do
(search-forward "aaa" nil 't)
(replace-match "bbb")
If between the search and the replace I modify the buffer, the following seems to happen:
(match-end 1) <- (min (point-max) (match-end 1))
(match-beginning 1) <- (min (match-beginning 1) (match-end 1))
Moreover if (match-end 1)==(match-beginning 1) replace-match calls insert at (match-end 1) (both of which gets updated to point to the end of the inserted string) whereas if (match-end 1)>(match-beginning 1) replace-match updates the string between (match-beginning 1) and (match-end 1) (and they get updated to point to the beginning and end of the inserted string)
So the second question is why the different behaviours?
I'm using SBCL. When something goes wrong in my program, SBCL will print a long list of back trace informations. This is annoying sometimes, and I have to scroll back and back to find out what the error message was. Can I customize the error outputs(e.g., shorten the back trace list)?
See: *backtrace-frame-count*.
I did some experimenting with sbcl:
(defun crash-big-stack (&optional (c 20))
(if (= c 0)
(error "crash boooooom")
(another-crash (- c 1))))
(defun another-crash (&optional c)
(crash-big-stack c))
1) I am using SBCL 1.0.57.0 which wont give any stacktrace if not asked (using slime though will result in a stacktrace), the only scenario where sbcl crashes and prints the complete stacktrace is when you either use (sb-ext:disable-debugger) or provide the toplevel argument sbcl --disable-debugger
SBCL (without (sb-ext:disable-debugger)):
* (crash-big-stack)
debugger invoked on a SIMPLE-ERROR in thread
#<THREAD "main thread" RUNNING {1002978CA3}>:
crash boooooom
Type HELP for debugger help, or (SB-EXT:QUIT) to exit from SBCL.
restarts (invokable by number or by possibly-abbreviated name):
0: [ABORT] Exit debugger, returning to top level.
(CRASH-BIG-STACK 0)
0]
SBCL (with (sb-ext:disable-debugger)):
(crash-big-stack)
unhandled SIMPLE-ERROR in thread #<SB-THREAD:THREAD "main thread" RUNNING
{1002978CA3}>:
crash boooooom
0: (SB-DEBUG::MAP-BACKTRACE
#<CLOSURE (LAMBDA # :IN BACKTRACE) {100465352B}>
:START
0
:COUNT
128)
1: (BACKTRACE 128 #<SYNONYM-STREAM :SYMBOL SB-SYS:*STDERR* {1000169AE3}>)
2: (SB-DEBUG::DEBUGGER-DISABLED-HOOK
#<SIMPLE-ERROR "crash boooooom" {1004651C23}>
#<unavailable argument>)
3: (SB-DEBUG::RUN-HOOK
*INVOKE-DEBUGGER-HOOK*
#<SIMPLE-ERROR "crash boooooom" {1004651C23}>)
4: (INVOKE-DEBUGGER #<SIMPLE-ERROR "crash boooooom" {1004651C23}>)
5: (ERROR "crash boooooom")
6: (CRASH-BIG-STACK 0)
7: (SB-INT:SIMPLE-EVAL-IN-LEXENV (CRASH-BIG-STACK) #<NULL-LEXENV>)
8: (EVAL (CRASH-BIG-STACK))
9: (INTERACTIVE-EVAL (CRASH-BIG-STACK) :EVAL NIL)
10: (SB-IMPL::REPL-FUN NIL)
11: ((LAMBDA () :IN SB-IMPL::TOPLEVEL-REPL))
12: (SB-IMPL::%WITH-REBOUND-IO-SYNTAX
#<CLOSURE (LAMBDA # :IN SB-IMPL::TOPLEVEL-REPL) {100450355B}>)
13: (SB-IMPL::TOPLEVEL-REPL NIL)
14: (SB-IMPL::TOPLEVEL-INIT)
15: ((FLET #:WITHOUT-INTERRUPTS-BODY-236911 :IN SAVE-LISP-AND-DIE))
16: ((LABELS SB-IMPL::RESTART-LISP :IN SAVE-LISP-AND-DIE))
unhandled condition in --disable-debugger mode, quitting
As far as the SBCL manual goes, there is no way to influence the predefined behavior of the SBCL debugger interface, but you can provide your own by setting sb-ext:*invoke-debugger-hook*
* (defun crash-big-stack (&optional (c 20))
(if (= c 0)
(error "crash boooooom")
(let ((waste (another-crash (- c 1))))
(+ waste 42))))
CRASH-BIG-STACK
* (defun another-crash (&optional c)
(crash-big-stack c))
ANOTHER-CRASH
* (setf sb-ext:*invoke-debugger-hook* #'(lambda(&rest args) (sb-ext:exit)))
#<FUNCTION (LAMBDA (&REST ARGS)) {10045CEF1B}>
* (crash-big-stack)
~:
I have the following code:
(define (play-loop strat0 strat1 strat2 game-limit)
(define (play-loop-iter strat0 strat1 strat2 count history0 history1 history2 limit)
(cond ((= count limit) (print-out-results history0 history1 history2 limit))
(else (let ((result0 (strat0 history0 history1 history2))
(result1 (strat1 history0 history1 history2)
(result2 (strat2 history0 history1 history2)))
(play-loop-iter strat0 strat1 strat2 (+ 1 count)
(extend-history result0 history0)
(extend-history result1 history1)
(extend-history result2 history2)
limit)))))
(play-loop-iter strat0 strat1 strat2 0 '() '() '() game-limit)))
When I run it in racket it gives me the following error:
begin (possibly implicit): no expression after a sequence of internal definitions in:...
I seems everything is OK but there is an error and looked me very interesting.
What is the problem?
Thank you...
It's telling you that your play-loop function only contains the definition of the play-loop-iter function and no other expression in its body.
It looks like you want the call to play-loop-iter to be part of play-loop's body, but it's not - it's part of play-loop-iter's body. Check the parentheses.
You are likely missing a paren after (result1 (strat1 history0 history1 history2)