I am very new to scheme, and I am having trouble getting simple cond functions that I make to print in DrRacket ide. When I run these two functions:
(define (test x)
(cond
[(zero? x) (error "doesn't get here, either")]
[(positive? x) 'here]))
(define (compare x y)
(cond [(equal? x y) "Is Equal"]))
it prints:
> test 12
#<procedure:test>
12
> compare 12 12
#<procedure:compare>
12
12
Why will it not output any of the errors, or "Is Equal"? It works fine if I run the cond statements directly and replace the variables.
You're not actually calling the new procedures, you must surround the procedure name and its arguments between brackets (), just as you did with all the other procedures you're using in your solution! This is the way:
(test 12)
=> 'here
(compare 12 12)
=> "Is Equal"
Related
I am learning Common Lisp (SBCL).
I want to create a facility to invoke two (or more) macros with several similar expressions that differ only in some parameters.
I would like to define the base of the expression, then modify it with the parameters I supply. For this a lambda function definition came to mind.
As far as I know, there is no analogue to funcall for macros, so I've also wrapped the macros in lambdas.
I feel like I'm overcomplicating with with all these lambda-s and funcall-s. Is there a more elegant way?
The macros are from an external lib, so I'd prefer not to modify them. (Specifically, the fiveam testing library's finishes and signals.)
Here is a sample code:
(defmacro macro1 (body) ())
(defmacro macro2 (body) ())
(defun check-expr-with-args (do-m func args)
(dolist (arg args)
(format t "~a " arg)
(funcall do-m (lambda () (funcall func arg)))))
(let ((test-expr
#'(lambda (val) (format t "~a" val)))
(cases (list
(list #'(lambda (func) ( macro1 (funcall func)))
(list 1 2 3 4 5))
(list #'(lambda (func) ( macro2 (funcall func)))
(list -4 -5 -6 -7 -8 -9)))))
(dolist (c cases)
(check-expr-with-args (first c) test-expr (second c))))
Originally I've tried to pass the macro names to my check-expr-with-args function, and the expressions in quoted form, relying on lexical scoping for the parameter insertion. That didn't work out.
I think you can write a wrapper macro that produces code that invokes macro1 (and macro2). For example here I'm defining m1 that takes (i) a test expression and (ii) an expression that is expected to evaluates at runtime to a list of values.
(defmacro m1 (test-expr input-expr)
(let ((arg (gensym)))
`(dolist (,arg ,input-expr)
(macro1 ,test-expr ,arg))))
Both test-expr and input-expr are injected in a dolist expression, which binds a variable named arg. Here arg is a fresh symbol introduced with gensym, to avoid accidentally shadowing a variable or symbol-macro possibly used in test-expr.
For example:
(m1 (some-test-p) (list 1 2 3 4))
The above expands as:
(DOLIST (#:G1909 (LIST 1 2 3 4))
(MACRO1 (SOME-TEST-P) #:G1909))
The resulting expression contains MACRO1, which will also be expanded. But it is now wrapped in an expression that iterates over some list computed at runtime. Here, it is a constant but you could replace it with any other expression.
In conclusion, it is often best to combine macros at the macro level, by expanding your own macros into other ones.
I want to create a facility to invoke two (or more) macros
(defmacro invoke-macros (macro-forms)
`(progn ,#macro-forms))
with several similar expressions that differ only in some parameters.
(defmacro invoke-macros (macro-names &rest macro-arguments)
`(progn ,#(loop for m in macro-names
appending (loop for a in macro-arguments
collecting `(,m ,#a)))))
Check:
[1]> (macroexpand '(invoke-macros (m1 m2) (a b c) (d e f)))
(PROGN (M1 A B C) (M1 D E F) (M2 A B C) (M2 D E F)) ;
T
Of course, this works with any operators, including functions, not only macros; we should call this invoke-operators. Or some better name reflecting that we are creating a cartesian product from operators and argument syntax.
If we need the returned values, we can change progn to list. Or possibly values if the number of combinations isn't expected to be large.
If this had to be a function:
(defun invoke-ops (op-names &rest op-arguments)
(loop for o in op-names
appending (loop for a in op-arguments
collecting (eval `(,o ,#a)))))
Check:
[1]> (invoke-ops '(list +) '(1 2) '(10 20))
((1 2) (10 20) 3 30)
Since invoke-ops is now a function, we have to quote the arguments.
There is no funcall for macros. If you gain access to the expander function of a macro, then there is a funcall, but all it does is perform the code transformation; it won't invoke the macro.
The only ways to invoke the code generated by a macro are: you can eval the code, or you can compile the code and funcall it. The latter approach requires a function, so you place the code into a lambda expression first:
(funcall (compile nil `(lambda () ,code-output-by-macro)))
The nil argument of compile is the function name; we are telling compile that we are not dealing with a named function definition. We supply the code in the second argument. In some Common Lisp implementations, there is no evaluator; the eval function does something similar to:
(defun eval (code)
(funcall (compile nil `(lambda () ,code))))
I am trying to make a helper function that will take input of switched syntax.
Helper function needs to be able to do:
> (num sqr) ; where num=6, and sqr is the math function square.
36
Originally, the built-in syntax would be:
>(sqr num) ; where num=6
36
Since I cannot declare 'num' as a function and a variable at the same time, I will need to nest another procedure into it. Below is what I have so far:
(define (num func)
(display func + 6))
Now, I know that 'display' won't easily do what I'd like it to do unlike other programming languages. Is there another method in place of 'display' that I can use? I think this is the easiest way to do it, but I am new so I'm not sure which is an appropriate method. 'func' will need to be able to take math functions like 'sqr' 'sqrt' 'add1'...etc.
If you just want (num sqr) to work like in your code you can do this:
(define (num fun)
(fun 6))
(num sqr) ; ==> 36
(num add1) ; ==> 7
But num won't be 6.
A solution might be to make yourself a module language, perhaps called #!lefthanded-racket where the parser for code just reverses all lists. Thus you can supply it code like:
#!lefthanded-racket
(6 num define)
(num sqr) ; ==> 36
(num add1) ; ==> 7
((((((1 y -) x ack) (1 x -) ack) (y x))
(2 (1 _))
((y 2 *) (y 0))
(0 (0 _))
(y x) match*)
(y x ack) define)
(4 2 ack) ; ==> 65536
For the simple solution, where you just override the default reader and deep reverse the lists you'll have problems with dotted lists. In order to get that right you need to write a parser.
The code that is run won't be in reverse, only the code you write. There is some documentation on how to create your own language. Also this practical example might be helpful too.
Do you mean something like this?
#lang racket
(define ((partial func) arg)
(func arg))
((partial sqr) 6)
The output is 36.
I am trying to define two functions using Scheme. One is the close_to function which looks like this:
(define (close_to x y)(if(< (abs (- x y)) 0.0001)(#t)#f))
it should return true if the number x and y has a difference that is smaller than 0.0001 and false otherwise. However, it keeps throwing the error:
function call: expected a function after the open parenthesis, but received true
when I call it
(close_to 4 3.99999999)
The second function is the improve function which looks like this:
(define (improve x y)(average y /(x y)))
it should return the average of y and x/y. Similarly, I am getting the error:
function call: expected a function after the open parenthesis, but received 1
when I call it
(improve 1 2)
What am I doing wrong? Can anyone help me?
Your problem is the (#t) and (#f).
#t is not a function. Rather, rewrite the first one like this:
(define (close_to x y)
(if (< (abs (- x y)) 0.0001)
#t
#f))
The other is an exercise for the reader.
I'm trying to define a function in Racket which takes no arguments. All the examples that I have seen take one or more arguments.
How can I do that?
(define (fun1)
"hello")
(define fun2
(lambda ()
"world"))
(define fun3
(thunk
"I am back"))
(fun1)
=> "hello"
(fun2)
=> "world"
(fun3)
=> "I am back"
EDIT
If, as #Joshua suggests, you want a procedure which can take any argument(s) and ignore them, the equivalent definitions would be:
(define (fun1 . x)
"hello")
(define fun2
(lambda x
"world"))
(define fun3
(thunk*
"I am back"))
(fun1)
(fun1 1 2 3)
=> "hello"
(fun 2)
(fun2 4 5 6 7)
=> "world"
(fun3)
(fun3 8 9)
=> "I am back"
The answer can be found in HtDP 2e here:
http://www.ccs.neu.edu/home/matthias/HtDP2e/part_one.html#%28part._sec~3afuncs%29
"...Here are some silly examples:
(define (f x) 1)
(define (g x y) (+ 1 1))
(define (h x y z) (+ (* 2 2) 3))"
...then later...
"The examples are silly because the expressions inside the functions do not involve the variables. Since variables are about inputs, not mentioning them in the expressions means that the function’s output is independent of their input. We don’t need to write functions or programs if the output is always the same." (emphasis mine)
That is the answer to your question: you do not need to define no-argument functions, just define them as constants.
So instead of:
(define (fun) "hello")
You just need:
(define not-a-fun "hello")
You can simply say
(define (hello-world)
(displayln "Hello world"))
(hello-world)
I'm supposed to define the function n! (N-Factorial). The thing is I don't know how to.
Here is what I have so far, can someone please help with this? I don't understand the conditionals in Racket, so an explanation would be great!
(define fact (lambda (n) (if (> n 0)) (* n < n)))
You'll have to take a good look at the documentation first, this is a very simple example but you have to understand the basics before attempting a solution, and make sure you know how to write a recursive procedure. Some comments:
(define fact
(lambda (n)
(if (> n 0)
; a conditional must have two parts:
; where is the consequent? here goes the advance of the recursion
; where is the alternative? here goes the base case of the recursion
)
(* n < n))) ; this line is outside the conditional, and it's just wrong
Notice that the last expression is incorrect, I don't know what it's supposed to do, but as it is it'll raise an error. Delete it, and concentrate on writing the body of the conditional.
The trick with scheme (or lisp) is to understand each little bit between each set of brackets as you build them up into more complex forms.
So lets start with the conditionals. if takes 3 arguments. It evaluates the first, and if that's true, if returns the second, and if the first argument is false it returns the third.
(if #t "some value" "some other value") ; => "some value"
(if #f "some value" "some other value") ; => "some other value"
(if (<= 1 0) "done" "go again") ; => "go again"
cond would work too - you can read the racket introduction to conditionals here: http://docs.racket-lang.org/guide/syntax-overview.html#%28part._.Conditionals_with_if__and__or__and_cond%29
You can define functions in two different ways. You're using the anonymous function approach, which is fine, but you don't need a lambda in this case, so the simpler syntax is:
(define (function-name arguments) result)
For example:
(define (previous-number n)
(- n 1))
(previous-number 3) ; => 2
Using a lambda like you have achieves the same thing, using different syntax (don't worry about any other differences for now):
(define previous-number* (lambda (n) (- n 1)))
(previous-number* 3) ; => 2
By the way - that '*' is just another character in that name, nothing special (see http://docs.racket-lang.org/guide/syntax-overview.html#%28part._.Identifiers%29). A '!' at the end of a function name often means that that function has side effects, but n! is a fine name for your function in this case.
So lets go back to your original question and put the function definition and conditional together. We'll use the "recurrence relation" from the wiki definition because it makes for a nice recursive function: If n is less than 1, then the factorial is 1. Otherwise, the factorial is n times the factorial of one less than n. In code, that looks like:
(define (n! n)
(if (<= n 1) ; If n is less than 1,
1 ; then the factorial is 1
(* n (n! (- n 1))))) ; Otherwise, the factorial is n times the factorial of one less than n.
That last clause is a little denser than I'd like, so lets just work though it down for n = 2:
(define n 2)
(* n (n! (- n 1)))
; =>
(* 2 (n! (- 2 1)))
(* 2 (n! 1))
(* 2 1)
2
Also, if you're using Racket, it's really easy to confirm that it's working as we expect:
(check-expect (n! 0) 1)
(check-expect (n! 1) 1)
(check-expect (n! 20) 2432902008176640000)