I'd like to write a pattern that only matches on a single datum like 'a or 'hello but not anything else. I don't think the following works as it matches on everything (like (list 1 2 3))right?
(define (f x)
(match x (e (printf "hi~n"))))
Datums can be used as patterns. Here is an example:
#lang racket
(define (f x)
(match x
["hello" "x is hello"]
[_ "x is not hello"]))
(f "hello")
(f 42)
The result is:
"x is hello"
"x is not hello"
Also if you want to use a fixed symbol as a pattern use 'hello and not just hello. The first 'hello matches a single symbol but hello is a pattern variable and matches everything.
Related
I am trying to have my program add a string to another string, if in the right format.
My current code is
(define (addString e)
(match e
[`(+ , x, y) (string-append x y)]))
So when I run (addString (+ "a" "b")) it returns "ab"
However, it gives an error: "match: no matching clause for `+". What am I doing wrong?
Almost there! you just need to quote the input. Also, the , inside the match clause should be written right besides the variable you want to evaluate (although it works the way you have it, but it can be a little confusing). This is what I mean:
(define (addString e)
(match e
[`(+ ,x ,y) (string-append x y)]))
It works as expected:
(addString '(+ "a" "b"))
=> "ab"
Can anyone explain the part with the flet operator please ? :
(defun read-3-numbers-&-format-sum ()
(flet ((prompt (string)
(format t "~&~a: " string)
(read nil 'eof nil)))
(let ((x (prompt "first number"))
(y (prompt "second number"))
(z (prompt "third number")))
(format t "~&the sum of ~a, ~a, & ~a is:~%~%~a~%"
x y z (+ x y z)))))
Your source for Common Lisp documentation is the Common Lisp Hyperspec, which can be found at different places on the internet.
Look up flet there: http://clhs.lisp.se/Body/s_flet_.htm#flet
It establishes a local function definition. Its scope is its body (i. e. where the let form is in this case). The function definition works like a “normal” function defined with defun otherwise.
actually i am trying to perfectly understand clojure and particularly symbols
(def a 1)
(type a)
;;=>java.lang.Long
(type 'a)
;;=>clojure.lang.Symbol
I know that type is a function so its arguments get evaluated first so i perfectly understand why the code above work this way .In the flowing code i decided to delay the evaluation using macro
(defmacro m-type [x] (type x))
(m-type a)
;;==>clojure.lang.Symbol
and i am fine with that but what i fail to uderstand is this:
(m-type 'a)
;;=>clojure.lang.Cons
why the type of 'a is a cons
the character ' is interpreted by the clojure reader as a reader-macro which expands to a list containing the symbol quote followed by whatever follows the ', so in your call to (m-type 'a) the 'a is expanding to:
user> (macroexpand-1 ''a)
(quote a)
then calling type on the list (quote a) which is a Cons.
This may be a bit more clear if we make the m-type macro print the arguments as it sees them while it is evaluating:
user> (defmacro m-type [x] (println "x is " x) (type x))
#'user/m-type
user> (m-type 'a)
x is (quote a)
clojure.lang.Cons
I have a string, which holds a a list structure like ((p X) (q (f X))) and I would really like to find a function that interprets/converts this string as a list of lists just like if it was a '((p X) (q (f X))).
(list "((p X) (q (f X)))") just makes it a single element list.
(intern "((p X) (q (f X)))") encloses it in | symbols.
How does
(read-from-string "((p X) (q (f X)))")
work for you? Documentation found here.
"((p X) (q (f X)))" is a string in Lisp. Strings are enclosed in ".
LIST creates a list with its arguments as elements.
So (list "((p X) (q (f X)))") creates a list with the string as the element.
INTERN creates a symbol.
(intern "((p X) (q (f X)))") creates a symbol with the string argument as its name. In Common Lisp symbols can have arbitrary names, even including characters like ( and ). Such symbols are printed enclosed in |. Example: |((p X) (q (f X)))| is a symbol with such a strange name.
Parsing an s-expression is called reading in Lisp. The functions to do so are for example READ and READ-FROM-STRING.
There are two basic ways to read the s-expression:
CL-USER 1 > (read-from-string "((p X) (q (f X)))")
((P X) (Q (F X)))
17
But you can also open an input stream based on the string using WITH-INPUT-FROM-STRINGand then use the usual READ:
CL-USER 2 > (with-input-from-string (stream "((p X) (q (f X)))")
(read stream))
((P X) (Q (F X)))
about the define-match-expansion, there are rare materials and example codes to illustrate the concepts. I am having a hard time to "decode" what the documentation says:
(define-match-expander id proc-expr)
(define-match-expander id proc-expr proc-expr)
Binds id to a match expander.
The first proc-expr subexpression must
evaluate to a transformer that
produces a pat for match. Whenever id
appears as the beginning of a pattern,
this transformer is given, at
expansion time, a syntax object
corresponding to the entire pattern
(including id). The pattern is the
replaced with the result of the
transformer.
A transformer produced by a second
proc-expr subexpression is used when
id is used in an expression context.
Using the second proc-expr, id can be
given meaning both inside and outside
patterns.
Can anyone give some example codes to illustrate the two usages of the define-match-expander here?
The idea behind match-expander is that you can extend the 'match' form to handle new pattern forms of your own design.
So, here's a (somewhat pointless) example that defines an "aba" match form that matches patterns of one thing followed by another thing followed by the first thing again (hence, "aba"):
#lang racket
(define-match-expander aba
(lambda (stx)
(syntax-case stx ()
[(_ a b) #'(list a b a)])))
(match '(3 4 3)
[(aba x y) (printf "x = ~a, y = ~a" x y)])
The second form allows you to add a separate expansion to be used outside of match patterns, like this:
#lang racket
(define-match-expander aba
(lambda (stx)
(syntax-case stx ()
[(_ a b) #'(list a b a)]))
(lambda (stx)
#'(error "please don't use aba outside of patterns.")))
(match '(3 4 3)
[(aba x y) (printf "x = ~a, y = ~a\n" x y)])
(aba x y)
Caveat: whuffo the extra pair of parens around the pattern? Not sure, sorry.
This is a really old question, but I'd like to add the example using "syntax-rules" for the same "aba" pattern:
(define-match-expander aba
(syntax-rules ()
[(aba a b) (list a b a)]))
(match '(3 4 3)
[(aba x y) (printf "x = ~a, y = ~a" x y)])
Left-hand side (aba a b) is the thing going in the match, the right-hand side (list a b a) is the substitution.
(match '(3 4 3)
[(aba x y) (printf "x = ~a, y = ~a" x y)])
is replaced by
(match '(3 4 3)
[(list x y x) (printf "x = ~a, y = ~a" x y)])
The nice part is that the new matcher works for ALL "match-whatever" functions, like:
(match-define (aba x y) (list 1 2 1))
(printf "x = ~a, y = ~a" x y