I'm taking a functional programming course, using the book SICP as reference. Several places in the book, I have come across the use of '->' arrows in procedure definitions.
Examples:
(define (segments->painter segment-list)
(lambda ...
(define (tree->list tree)
(if (...
(define (scheme-number->complex n)
(make-complex-from-real ...
So, what does the '->' arrow mean? Is it a naming convention to indicate that the procedure transforms one thing into another; such as tree-into-list?
If not; what does the arrow represent?
Thanks!
As #sepp2k mentions -> is part of the name and doesn't mean anything in it self.
The convention is to use -> in names for "conversion" (used loosely) functions.
The function string->list has a string as input and produces a list of characters.
In most cases you can pronounce -> as "to". That is string->list is pronounced "string to list" if you were to read code aloud.
Is it a naming convention to indicate that the procedure transforms one thing into another; such as tree-into-list?
Exactly.
Related
I am trying to understand what is the type of the following statement in Scheme:
#&\a
what is the type of the expression above?
is it a comment?
In Racket, #&\a is an immutable box containing a symbol.
(box? #&\a) ; #t
(unbox #&\a) ; 'a
(symbol? (unbox #&\a)) ; #t
(immutable? #&\a) ; #t
Refer to Reading Boxes.
#&\a is not valid Scheme code.
Anything starting with # is typically a reader macro of some sort. In Scheme all from reading numbers in specific bases, vector literals and booleans start with the # and this is remnants from the time Scheme was interpreted under a MacLISP host. It would use reader macro to do the right thing at read time. Common Lisp has the same functionality today.
Examples:
'#(1 2 3) ; a vector of 3 elements
#f ; boolean false (everything else is thruthy)
#x10 ; 16 read in hexadecimal
It's not uncommon for an implementation to expand features beyond the report and the report does not ban this. Thus any implementation can add other reader macros and it won't affect Scheme code since you'll never use those in Scheme code, only in the implementers new Scheme dialect. I don't think there exist one Scheme implementation that only implement the report and nothing else.
I am reading an article which uses Scheme for describing an implementation. I know a bit of Common Lisp but no Scheme.
I am hoping you will be so kind as to explain two Scheme code samples and show me how they correspond to Common Lisp.
First, what does this Scheme mean:
(define (content cell)
(cell ’content))
I believe it means this: define a function named content which has one argument named cell. In Common Lisp it is written as:
(defun content (cell)
(...))
Am I right so far?
I am uncertain what the function's body is doing. Is the argument (cell) actually a function and the body is invoking the function, passing it a symbol, which happens to be the name of the current function? Is this the corresponding Common Lisp:
(defun content (cell)
(funcall cell ’content))
Here is the second Scheme code sample:
(define nothing #(*the-nothing*))
I believe it is creating a global variable and initializing it to #(*the-number*)). So the corresponding Common Lisp is:
(defvar nothing #(*the-nothing*))
Is that right? Does the pound symbol (#) have a special meaning? I'm guessing that *the-nothing* is referring to a global variable, yes?
Broadly speaking: yes to both, with one major caveat. More specifically, the first one is accepting an argument called cell and calling it with the symbol 'content. (BTW, your unicode quotation mark is freaking me out a bit. Is that just a copy-paste issue?)
In the second case, the hash is a shortcut for defining a vector. So, for instance:
(vector? #(abc)) ;; evaluates to #t
However, the hash also has quoting behavior. Just as the first element of
'(a b c)
is the symbol 'a (and not the value of the variable named a), the first value in the vector
#(*the-nothing*)
is the symbol '*the-nothing*, rather than the value of a global variable.
The problem is quite difficult to explain because I need to collect my thoughts, so bear with me. I've been able to reduce the problem to a minimal example for illustrative purposes. The example will not make any sense as to what this would be useful for, but I digress. Say I want to extend the racket language to write things that look like this:
(define-something
(['a] 'whatever)
(['b 'c] 'whatever2))
Between the square brackets is a sequence of one or more symbols, followed by a sequence of racket expressions (the whatever's, which are not important for the problem statement)
The example would match a macro that looks something like this:
(define-syntax (define-something stx)
(syntax-case stx ()
[(_ ([symb ...] body ...) ...)
#'()]))
Actually here we match 0 or more symbols, but we can assume there is always going to be at least one.
In the macro's body I want to generate function definitions using the concatenated symbols as the identifier. So for our silly example the macro would expand to something like:
(define (a) 'whatever)
(define (bc) 'whatever2)
I have found a similar question where the poster generates functions using a pre-defined list of strings, but I am not that fluent with macro's so I have not been able to translate the concepts to solve my problem. I thought perhaps I could try generating a similar list (by concatenating the symbols) and applying their tactic, but I've been getting way too confused with all the ellipses in my macro definition. I'm also a bit confused about their use of an ellipsis in with-syntax.
It’s possible to solve this with with-syntax and syntax-case, but the easiest way to do this is by using syntax-parse’s syntax classes. By defining a syntax class that parses a list of symbols and produces a single concatenated identifier, you can lift the symbol parsing out of the macro body:
(require (for-syntax syntax/parse
racket/string))
(begin-for-syntax
(define-syntax-class sym-list
#:attributes [concatenated-id]
(pattern (~and stx (sym:id ...))
#:attr concatenated-id
(let* ([syms (syntax->datum #'(sym ...))]
[strs (map symbol->string syms)]
[str (string-append* strs)]
[sym (string->symbol str)])
(datum->syntax #'stx sym #'stx #'stx)))))
Now you can define your macro pretty easily:
(define-syntax (define-something stx)
(syntax-parse stx
[(_ (syms:sym-list body ...) ...)
#'(begin
(define (syms.concatenated-id) body ...)
...)]))
Note that this uses unquoted symbols in the name clause, so it would work like this:
(define-something
([a] 'whatever)
([b c] 'whatever2))
The names can’t be expressions that evaluate to symbols because the information needs to be known at compile-time to be available to macro expansion. Since you mentioned in a comment that this is for an FRP-like system, your signal graph will need to be static, like Elm’s is for example. If you want the ability to construct a dynamic signal graph, you’ll need a more complex strategy than macros since that information will need to be resolved at runtime.
I've started trying to learn the innards of Scheme evaluation, and one aspect of quasiquotation, unquoting, evaluation and cons-cells is confusing me. If you can recommend any good references on the subject I'd be very grateful.
The R7RS draft has this example in section 4.2.8 on quasiquotation.
`(( foo ,(- 10 3)) ,#(cdr '(c)) . ,(car '(cons)))
(It's in the R4RS spec too, so this isn't a new thing.)
According to the spec this should evaluate to:
((foo 7) . cons)
I'm having some trouble understanding why. To my mind, the . removes the unquote from the start of the inner list, meaning it won't be evaluated as a procedure.
Here's a simpler expression that demonstrates the same problem:
`(foo . ,(car '(bar)))
Using the same logic as above, this should evaluate to:
(foo . bar)
And indeed it does evaluate to that on the Scheme systems I've tried.
However, to my understanding it shouldn't evaluate to that, so I want to find out where I'm going wrong.
My understanding of Scheme evaluation is (OK, simplified) if it's the first keyword after an open-bracket, call that procedure with the remainder of the list as the parameters.
My understanding of the spec is that ',' is exactly equivalent to wrapping the next expression in an '(unquote' procedure.
My understanding of the dot notation is that, for general display purposes, you remove the dot and opening parenthesis (and matching closing parenthesis), as described here:
In general, the rule for printing a pair is as follows: use the dot
notation always, but if the dot is immediately followed by an open
parenthesis, then remove the dot, the open parenthesis, and the
matching close parenthesis.
So:
`(foo . ,(car '(bar)))
Could equally be rendered as:
(quasiquote (foo unquote (car (quote (bar)))))
(In fact, this is how jsScheme will render the input in its log window.)
However, when it comes to evaluating this:
(quasiquote (foo unquote (car (quote (bar)))))
Why is the 'unquote' evaluated (as a procedure?), unquoting and evaluating the (car...) list? Surely it should just be treated as a quoted symbol, since it's not after an opening bracket?
I can think of a number of possible answers - 'unquote' isn't a regular procedure, the 'unquote' is evaluated outside of the regular evaluation process, there's a different way to indicate a procedure to be called other than a '(' followed by the procedure's symbol - but I'm not sure which is right, or how to dig for more information.
Most of the scheme implementations I've seen handle this using a macro rather than in the same language as the evaluator, and I'm having difficulty figuring out what's supposed to be going on. Can someone explain, or show me any good references on the subject?
You are correct in that there are macros involved: in particular, quasiquote is a macro, and unquote and unquote-splicing are literals. None of those are procedures, so normal evaluation rules do not apply.
Thus, it's possible to give (quasiquote (foo bar baz unquote x)) the special treatment it needs, despite unquote not being the first syntax element.
(define (rec base height)
(let ((product (* base height))(half 0.5))
(let ((sum (* product half)))
(display "Area is")
(display sum))))
let: expected only one expression after the name-defining sequence, but found one extra part in: (display sum)
I am having the error as above, I don't know which part goes wrong
In full Scheme, this is allowed. However, you are probably using one of the teaching variants of Scheme (such as Intermediate Student or Advanced Student) that Racket provides, which disallows functions with more than one expression.
I'd say you can work around it by using begin, but Intermediate Student doesn't provide begin either (Advanced Student appears to, which helps). If you're using Intermediate Student, I guess you're just not meant to use multiple expressions, and that's that. :-)
The beginning and intermediate student languages really aren't a good fit for programs that use I/O. If your teacher is assigning problems that require you to use one of these languages and also require you to print something out, that would be a somewhat inappropriate assignment.
For the record, I certainly make mistakes like this myself....