I'm starting out with chicken scheme. The code below works in the mit-scheme repl but doesn't with csi. csi has filter defined in the docs but I get an unbound variable error when I run the code below.
CHICKEN
(c) 2008-2015, The CHICKEN Team
(c) 2000-2007, Felix L. Winkelmann
Version 4.10.0 (rev b259631)
macosx-unix-clang-x86-64 [ 64bit manyargs dload ptables ]
compiled 2015-08-04 on yves.more-magic.net (Linux)
#;1> (filter odd? '(1 2 3 ))
Error: unbound variable: filter
Call history:
<syntax> (filter odd? (quote (1 2 3)))
<syntax> (quote (1 2 3))
<syntax> (##core#quote (1 2 3))
<eval> (filter odd? (quote (1 2 3))) <--
#;1>
filter is defined in the srfi-1 module, so you must first load that module to make it available:
CHICKEN
(c) 2008-2014, The Chicken Team
(c) 2000-2007, Felix L. Winkelmann
Version 4.9.0.1 (stability/4.9.0) (rev 8b3189b)
linux-unix-gnu-x86-64 [ 64bit manyargs dload ptables ]
bootstrapped 2014-06-07
#;1> (use srfi-1)
; loading /var/lib//chicken/7/srfi-1.import.so ...
; loading library srfi-1 ...
#;2> (filter odd? '(1 2 3 ))
(1 3)
#;3>
Not sure which filter procedure you are referring but it seems one of the filter listed on the doc is only available during macro expansions:
http://api.call-cc.org/doc/bindings#sec:filter
The one you can use in runtime is defined in SRFI-1 library. To use it, you can simply add the following:
(use srfi-1)
Related
For example if there's the expression:
(map (lambda(x) (add1 x)) '(1 2 3))
It evaluates to:
'(2 3 4)
How to display all the intermediate steps which in this case will be:
(map (lambda(x) (add1 x)) '(2 2 3))
(map (lambda(x) (add1 x)) '(2 3 3))
I think the best way to do this would be to start by making your own lambda calculus interpreter and adding the extra scheme features you need, and then modifying that interpreter to produce the execution trace that you want.
This could get you started with writing an interpreter http://matt.might.net/articles/implementing-a-programming-language/
I am trying to get pattern matching working, but I can only get it working in the Chicken interpreter - not the compiler.
Here is an example of it in the interpreter:
CHICKEN
(c) 2008-2015, The CHICKEN Team
(c) 2000-2007, Felix L. Winkelmann
Version 4.10.0 (rev b259631)
freebsd-unix-clang-x86-64 [ 64bit manyargs dload ptables ]
compiled 2015-08-04 on yves.more-magic.net (Linux)
#;1> (use matchable)
; loading /usr/local/lib/chicken/7/matchable.import.so ...
; loading /usr/local/lib/chicken/7/chicken.import.so ...
; loading /usr/local/lib/chicken/7/lolevel.import.so ...
; loading /usr/local/lib/chicken/7/matchable.so ...
#;2> (match '((1 2) (3 4)) [(a . b) b] [() 0])
((3 4))
#;3>
Here is the compiled version:
(declare (uses matchable))
(match '((1 2) (3 4))
[(a . b) b]
[() 0])
This fails (csc src/test.scm):
Syntax error: (src/test.scm:4) - malformed expression: (a . b)
inside expression `(match ...)'
Expansion history:
<syntax> (##core#begin (match (quote ((1 2) (3 4))) ((a . b) b) (() 0)))
<syntax> (match (quote ((1 2) (3 4))) ((a . b) b) (() 0))
<syntax> (quote ((1 2) (3 4)))
<syntax> (##core#quote ((1 2) (3 4)))
<syntax> ((a . b) b)
<syntax> (##core#let ((g0 (a . b))) (g0 b))
<syntax> (a . b) <--
What did I miss?
You'll need to load the import library at compile time. The declare statement simply says that it depends on matchable at runtime.
Simply do the same you did in the interpreter: (use matchable) instead of (declare (uses matchable)).
I've written the following Scheme code:
(define (last-pair list1)
(if (null? cdr list1)
car list1
(last-pair (cdr list1))))
(define (rev list1)
(if (null? list1)
list1
(append (rev (cdr list1)) (list (car list1)))))
in a file called test.scm.
At terminal, I run:
load "test.scm"
Then I try:
(last-pair (list 1 2 3))
;Value 15: (3)
which is correct.
Then I try:
(rev (list 1 2 3))
;Unbound variable: rev
;To continue, call RESTART with an option number:
; (RESTART 4) => Specify a value to use instead of rev.
; (RESTART 3) => Define rev to a given value.
; (RESTART 2) => Return to read-eval-print level 2.
; (RESTART 1) => Return to read-eval-print level 1.
Seems that it's loading my file properly since it loads last-pair, but I'm not sure why I'm getting the above error...
Thanks!
You will need to write
(load "test.scm")
at the repl. Just load "test.scm" probably doesn't load the file.
I think there is a builtin last-pair which makes it confusing that your last-pair example works and the rev one doesn't.
I'm using Chicken Scheme 4.9.0.1 on a Cloud9 hosted workspace, built from source.
I was trying it out with this (I mostly code with python, so I apologize for the weird parens syntax):
(define load-module
(lambda (filepath)
(begin
(load filepath)
)
)
)
(define print
(lambda (command)
(begin
(display command)
(newline)
)
)
)
(load-module "../src/Basics.scm")
(print (exponent 5 2))
where exponent was:
(define (exponent num pow)
(if (equal? pow 1)
num
(* num (exponent num (- pow 1))
)
)
)
But it gives me the following error:
Started /home/ubuntu/workspace/test.scm
CHICKEN
(c) 2008-2014, The Chicken Team
(c) 2000-2007, Felix L. Winkelmann
Version 4.9.0.1 (stability/4.9.0) (rev 8b3189b)
linux-unix-gnu-x86-64 [ 64bit manyargs dload ptables ]
bootstrapped 2014-06-07
; loading /home/ubuntu/workspace/project1/src/test.scm ...
; loading ../src/Basics.scm ...
Error: unbound variable: pow
Call history:
<eval> [append] (cons item (reverse target))
<eval> [append] (reverse target)
<eval> [append] (reverse (cons item (reverse target)))
<eval> [append] (cons item (reverse target))
<eval> [append] (reverse target)
<eval> [append] (reverse (cons item (reverse target)))
<eval> [append] (cons item (reverse target))
<eval> [append] (reverse target)
<eval> [append] (reverse (cons item (reverse target)))
<eval> [append] (cons item (reverse target))
<eval> [append] (reverse target)
<syntax> (print (exponent 5 2))
<syntax> (exponent 5 2)
<eval> (print (exponent 5 2))
<eval> (exponent 5 2)
<eval> [exponent] (equal? pow 1) <--
I tried the same procedure on a different scheme implementation (biwascheme, using their online REPL) and it worked. When I added the code directly into the file that i was working on without loading it from a separate file, then it works.
Why does it give that unbound variable error only when it loads from a separate file?
Works fine for me. Compiled Chicken with the same version on Ubuntu, down to the specific revision.
Your call history looks very strange. More specifically:
<eval> [append] (reverse target)
<syntax> (print (exponent 5 2))
The [append] (reverse target) portion looks weird. Your exponent function (as described) does not call that. Even assuming the history was wrong and that was actually inside the print function, I've checked library.scm and that history does not make sense either.
This leads me to believe that the Basics.scm file being loaded is, for some reason, not the one you are expecting and you ended up with a different, non-working version of exponent.
You could ask Chicken to display the contents of the file to make sure. Something such as:
(with-input-from-file "../src/Basics.scm"
(lambda ()
(display (read))))
The result should match the expected content.
I am using a softer who has a build-in scheme interpreter. I know the "environment" name is (the-environment). How can I find all the functions and symbols in the environment ?
(define p (open-output-file "d:/test.txt"))
(display (the-environment) p)
can this will display all the functions ?
Thanks in advance.
Joe
As Eli Barzilay pointed out, whether or not you can reflectively find all the names bound in an environment depends on which implementation of Scheme you are using.
I infer from your question that you are working within MIT Scheme, since you said the "name" of the environment is (the-environment)
From my own experimentation with MIT Scheme (release 9.1.1), you can indeed enumerate the names of the bindings bound in an environment:
1 ]=> (define (add1 n) (+ n 1))
;Value: add1
1 ]=> (add1 3)
;Value: 4
1 ]=> (environment-bound-names (the-environment))
;Value 13: (add1)
1 ]=>
I was a little surprised when I first encountered the above; I had expected to see many more bindings in the environment than just the single one I had defined myself.
Is it because you need to walk up to the parent environments, recursively? Well:
1 ]=> (environment-parent (the-environment))
;Value: #f
1 ]=>
It seems like in addition to the bindings you can access by inspecting (the-environment), one must also inspect the bindings accessible via system-global-environment:
1 ]=> (define global-names (environment-bound-names system-global-environment))
;Value: global-names
1 ]=> (length global-names)
;Value: 4050
1 ]=> (not (null? (memq '+ global-names)))
;Value: #t
1 ]=> (car global-names)
;Value: valid-hash-number?
From there, one can use functions like environment-lookup to extract the values bound within each environment:
1 ]=> (environment-lookup system-global-environment '+)
;Value 14: #[arity-dispatched-procedure 14]
1 ]=> ((environment-lookup system-global-environment '+) 2 3)
;Value: 5
(This could be useful, for example, if you wanted to filter the global-names list to just the names that are bound to procedures in the system global environment.)
FYI: I did not know the above off the top of my head; but luckily, MIT Scheme, like a number of other Lisp dialects, offers an apropos function that is very useful when you think you know part of the name of a function you are seeking. (apropos n) prints out all the bound symbols that have n in their name; so in my case, I made a guess and ran (apropos 'env) to see all of the symbols that are related to environments. That list is a little too long to transcribe here as an example, but here is something similar:
1 ]=> (apropos 'lookup)
#[package 14 (user)]
#[package 15 ()]
1d-table/lookup
dld-lookup-symbol
environment-lookup
environment-lookup-macro
environment-safe-lookup
hash-table/lookup
rb-tree/lookup
wt-tree/lookup
;Unspecified return value