Can anyone tell me what is the null value representation in mit-scheme? In the SICP book, it should be "nil" but it doesn't work.
Thanks.
'() should work. Basically, nil in scheme is the empty list, so quoting an empty list gives you nil.
There is the history.
visit http://web.archive.org/web/20070808004043/http://wiki.wordaligned.org/sicp/published/FrequentlyAskedQuestions
Original(broken): http://wiki.wordaligned.org/sicp/published/FrequentlyAskedQuestions
Text from the above FAQ (in case of Internet Archive breakage):
Why isn’t “nil” working?
The quick answer is: nil is no longer part of Scheme, use '() instead. The long answer follows…
Early examples in Chapter 2 use nil as a list terminator, but when these examples are run using (e.g.) MIT Scheme, you get:
;Unbound variable: nil
Similarly, using () or null in place of nil may work on some implementations, but neither is portable. The Wizard Book addresses the issue in this footnote
It’s remarkable how much energy in the standardization of Lisp dialects has been dissipated in arguments that are literally over nothing: Should nil be an ordinary name? Should the value of nil be a symbol? Should it be a list? Should it be a pair? In Scheme, nil is an ordinary name, which we use in this section as a variable whose value is the end-of-list marker (just as true is an ordinary variable that has a true value). Other dialects of Lisp, including Common Lisp, treat nil as a special symbol. The authors of this book, who have endured too many language standardization brawls, would like to avoid the entire issue. Once we have introduced quotation in section 2.3, we will denote the empty list as ‘() and dispense with the variable nil entirely.
Since this was written, nil has been excised from the Scheme standard—but the bottom line holds: use ‘(), not nil. In an email to the accu-sicp list, Mike notes:
It’s a troublesome thing, this nil/null/'() business. Scheme48 and
scm don't define null, and guile defines it but as a procedure akin to
common lisp's null (to go with its nil which behaves like cl's nil,
which itself is distinct from '()—maybe this had something to do
with fsf's plans to re-do emacs in guile). I think the best bet is to
replace the authors’ use of nil with ‘().
[Copied with just a touch of typographical clean up, to better match Markdown and usual ASCII input into the languages/implementations in question.]
I use MIT/GNU Scheme microcode 15.3, () and '() all works. (as you said, nil and null doesn't work).
1 ]=> ()
;Value: ()
1 ]=> '()
;Value: ()
1 ]=> (cons 1 ())
;Value 2: (1)
1 ]=> (cons 1 '())
;Value 3: (1)
(list ) '() and () can represent null. for example,
(define (transpose mat) (accumulate-n cons () mat))
or substitute () with '() or (list ).
Related
I created a function which gets two string parameters. The function simply adds each string length. below is a code.
(defun add_twostring_length (mystr1 mystr2)
(+ (length mystr1) (length mystr2))
)
When I call add_twostring_length function like this,
(add_twostring_length "cpp" "lisp")
output is correct. 7
But, when I call the same function in the manner of using comma,
(add_twostring_length "cpp", "lisp")
I got an error message.
Error: Comma not inside a backquote.
[condition type: READER-ERROR]
I want to call function in the manner of (add_twostring_length "cpp", "lisp").
What is the wrong with the code?
picture showing error message
You might as well ask "why can't I call the function without parentheses?" In lisp, you call functions as an sexpr with the function in the car and the arguments in the cdr. There are no commas involved -- that's the syntax of lisp.
What you want is possible, but I will strongly advice against using it:
(set-macro-character #\,
#'(lambda (stream char)
(read stream t nil t)))
The above code creates the so called "read macro". At read-time common lisp will find all occurrences of , and ignore them. This makes possible calling functions like so:
(+ 1, 2, 3) ; => 6
However this will break escaping in templates:
`(1 2 ,(+ 3 4)) ; => (1 2 (+ 3 4))
Perhaps it is possible to make the read macro more intelligent, but I don't want to delve deeper into this, because I don't like the idea. Sorry.
I'm working through the Programming Languages: Application and Interpretation book chapter 6 http://cs.brown.edu/courses/cs173/2012/book/From_Substitution_to_Environments.html
I've applied a fix as described in the book but the cons is not adding the type to the empty list refered to in the source.
I think it's a pass-by-value/pass-by-ref thing, any clues on how to set the mt-env when it's not being passed in as a parameter?
#lang plai-typed
;; Binding types
(define-type Binding
[bind (name : symbol) (val : number)])
;; some helper functions:
(define-type-alias Env (listof Binding))
(define mt-env empty)
(define extend-env cons)
;; testing function
(define (addBinding [b : Binding] [env : Env])
(extend-env b env)
)
(addBinding (bind 'x 5) mt-env) ;; returns (list (bind x 5))
(display mt-env) ;; returns empty list
Below is a link to the complete code for context if required, the interp function's appC case is the specific location of my problem area, thanks.
https://github.com/MickDuprez/plai/blob/master/Chapter%206/chapter-6.rkt
After re-reading the last part of this chapter a few times I don't think there is a simple solution to this problem. The 'change' only makes the revised interpreter behave the same as the previous 'substitution' interpreter but highlights the problem of scope with a special test case.
This is eluded to in the next part '6.4 Scope' where the author writes:
"The broken environment interpreter above implements what is known as dynamic scope."
I'm sure this will be addressed in future chapters, thanks for looking anyway.
Let's call this function "dynamic-define".
Basically I want to write a macro or lambda that works like this:
$ (dynamic-define "variable" 123)
$ variable
$ => 123
I tried it:
(define-syntax dynamic-define
(syntax-rules ()
((_ string <body>)
(eval `(define ,(string->symbol string) <body>)))))
and it works as expected but doesn't seem to be a good solution.
I tried to use without eval like this:
(define-syntax dynamic-define
(syntax-rules ()
((_ string <body>)
(define (string->symbol string) <body>))))
But when I try to use I get this error:
Error: invalid syntax (define (string->symbol "variable") 123)
What should I do?
(PLEASE: edit this question to fit native English and erase this line please)
You're running against a fundamental problem: you cannot do a real dynamic define in a "clean" way, hence your attempt using eval. Note that the two solutions above are both not dynamic -- all they give you is the ability to write "foo" instead of foo. As I said elsewhere, using eval is usually bad, and in this case it's worse since it's eval that is used from a macro which makes it very weird. This is in addition to having an implicit quasi-quote in your macro that makes things even more confusing. You could just as well define the whole thing as a plain function:
(define (dynamic-define string <body>)
(eval `(define ,(string->symbol string) ,<body>)))
If you really need this to work, then it's best to take a step back and think about what it is that you need, exactly. On one hand, the above solutions are not dynamic since they require using the macro with a string syntax
(dynamic-define "foo" 123) ; instead of (define foo 123)
but how would it look to have a real dynamic definition that takes in a string? You'd probably expect this to define b:
(define a "b")
(dynamic-define a 123)
but this only becomes more confusing when you consider how it interacts with other bindings. For example:
(define y 123)
(define (foo s)
(define x 456)
(dynamic-define s 789)
(+ x y))
Now, assuming that dynamic-define does what you want it to do, think about what you'd get with (foo "x") and (foo "y"). Worse, consider (foo "s") and (foo "+"). And even worse, what about
(foo (random-element '("x" "y" "s" "+" "define")))
? Clearly, if this dynamic-define really does some dynamic definition, then there is no sense that you can make of this code without knowing ahead of time what name foo will be called with. Without being able to make such sense, compilation goes out the window -- but much more importantly, correctness (or generally, the meaning of your code) dies.
In my experience, this kind of pattern is much better handled with hash tables and similar devices.
using define-macro
#> (define-macro (dynamic-define varstr val)
`(define ,(string->symbol varstr) ,val))
#> (dynamic-define "variable" 123)
#> variable
123
using syntax-case
#> (define-syntax dynamic-define
(lambda (stx)
(syntax-case stx ()
((k varstr val)
(with-syntax ([var (datum->syntax-object
#'k
(string->symbol (syntax-object->datum #'varstr)))])
#'(define var val))))))
#> (dynamic-define "variable" 123)
#> variable
123
How to add a common prefix/suffix to a list of strings?
For example:
From ("abc" "123" "xy")
To ("pre_abc" "pre_123" "pre_xy")
Try
(mapcar (lambda (c) (concat "pre_" x)) '("abc" "123" "xy"))
In Emacs without third-party libraries you use mapcar function to apply a function to every element of the list, as #sds have shown. However if you program in Elisp heavily, i recommend installing 2 third-party libraries, dash.el for list manipulation and s.el for string manipulation. These libraries introduce a huge amount of auxiliary functions with a consistent naming scheme. dash.el also have anaphoric versions for many functions, which makes code even less verbose. So to add a prefix for every string in a list you could use --map and s-prepend (s-append for suffixes):
(--map (s-prepend "x" it) '("a" "b" "c")) ;; => ("xa" "xb" "xc")
The operation to prepend is (concatenate 'string <strings ...)
So you could achieve your goal with
(cl-loop
for item in '("abc" "123" "xy")
collect (concatenate 'string "pre_" item))
A more general way to compose/generate strings would be to use format
using format would be
(cl-loop
for item in '("abc" "123" "xy")
collect (format nil "pre_~S" item))
Note using cl-lib package
I'd like to export or replicate a scheme environment in another guile process. The algorithm I'm imagining would do something like this to serialize:
(map (lambda (var val) (display (quasiquote (define ,var ,val))
(newline))
(get-current-environment))
And then I'd read/eval that on the other end.
However, while there are functions that return the current environment, they are in some internal format that I can't just map across. How can I "walk" the environment as the above? Alternatively, how else can I replicate an environment into another process?
you may decompose the so-called "current-environment" like this:
(define (get-current-binding-list)
(let* ((e (current-module)) ;; assume checking current-module
(h (struct-ref e 0)) ;; index 0 is current vars hashtable
)
(hash-map->list cons h) ;; return a vars binding list
))
and you can call (get-current-binding-list) to get variables binding list in current-module.
Please note that each element in this list is a pair of symbol and variable type, say, (symbol-name . variable-type). So you may print it like this:
for a instance ,you got a var binding:
(define abc 5)
then:
(let ((vl (get-current-binding-list)))
(assoc-ref vl 'abc)
)
==> #<variable 9bb5108 value: 5>
This result is a "variable type" of variable "abc". You can get it's value with variable-ref procedure.
So you can trace all the bindings and do something ,in your code ,it's simply print var-name and var-value.
I know my answer is too brief, but I think there's enough information to help you to find more details in the manual.
Hope this will help you.
You can't really serialize Scheme environment. I don't known even it's possible to (portably) serialize continuations. Oh, and don't forget about FFIs. Ports and threads are unserializable too.