How are assoc and assq implemented in Scheme? - scheme

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)))

Related

In ClojureScript, Set multiple properties of a javascript object at once

I am using doto to assign properties of a Dom element in ClojureScript, as below:
(let [img
(doto (.createElement js/document "img")
(set! -src "bunny-512.png")
(set! -height 64)
(set! -width 64))]
;...
)
Is there a way to do set all the properties at once via a map of properties+values instead?
Was thinking something like:
(let [img (.createElement js/document "img")]
(set! img {:src "bunny-512.png" :height 64 :width 64})
But that does not work ...
Try something like this:
(defn set-props [o property-map]
(doseq [[k v] property-map]
(.setAttribute o (name k) v)))
Test:
(def mg (.createElement js/document "img"))
cljs.user=> (set-props mg {:src "foo.png" :height 128 :width 128})
nil
cljs.user=> (.-src mg)
".../foo.png"
cljs.user=> (.-width mg)
128
cljs.user=> (.-height mg)
128

Which variable is set by `search-forward` in elisp?

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?

Modifying structure fields within function?

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)))

Can I customize the format of error outputs of common lisp?

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)
~:

a strange error in racket "no expression after a sequence of internal definitions"

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)

Resources