Total newbie to Scheme here.
I've been stuck on a scheme problem for sometime now. I don't understand how to code this right. I've looked every where on this site and others, and I just can't get this to work.
the problem: define a function Square that squares its parameters. If the parameter is not a number, print the message "invalid_input".
Here is what I have tried:
(define (square x) (cond
((number? x) (* x x))
(else (display "invalid_input\n"))
)
)
I've also tried this:
(define (square x) (cond
((number? x) (* x x))
((not (number? x)) (display "invalid_input\n"))
)
)
And this:
(define (square x) (if
(number? x) (* x x) (display "invalid_input\n")
)
)
None of these have worked when I call square like this (square h).
I keep getting this error on Linux
scheme#(guile-user)> (square h)
;;; <stdin>:44:0: warning: possibly unbound variable `h'
<unnamed port>:44:0: In procedure #<procedure 7fcc7d0a0b60 at <current input>:44:0 ()>:
<unnamed port>:44:0: In procedure module-lookup: Unbound variable: h
Entering a new prompt. Type `,bt' for a backtrace or `,q' to continue.
Shouldn't it print "invalid_input" since 'h' is not a number?
help me out here please. thank you
Functions always evaluate their arguments in Scheme. With (square h), h is an unbound variable; when h is evaluated, an error is issued since h is not bound. You can see that the OP definitions work as intended by trying (square 'h) or (square "h"). In the first case 'h is a symbol, and in the second "h" is a string; these are not numbers, so "invalid_input" is printed.
OP should work on following lispy conventions when formatting Scheme code; it is very bad style in lisps to scatter closing parentheses over multiple lines. Here is the same code in a more readable style, typical of lisps:
(define (square x)
(cond ((number? x) (* x x))
(else
(display "invalid_input\n"))))
Your code works fine. But you have do define h in order to use it.
$ guile
GNU Guile 2.0.13
Copyright (C) 1995-2016 Free Software Foundation, Inc.
Guile comes with ABSOLUTELY NO WARRANTY; for details type `,show w'.
This program is free software, and you are welcome to redistribute it
under certain conditions; type `,show c' for details.
Enter `,help' for help.
Your function is correct.
scheme#(guile-user)> (define (square x)
(if (number? x)
(* x x)
(display "invalid_input\n")))
And works as expected:
scheme#(guile-user)> (square 5)
$1 = 25
But if you pass an undefined value, you will get an error:
scheme#(guile-user)> (square h)
;;; <stdin>:6:0: warning: possibly unbound variable `h'
<unnamed port>:6:0: In procedure #<procedure 5595e9575c20 at <current input>:6:0 ()>:
<unnamed port>:6:0: In procedure module-lookup: Unbound variable: h
Entering a new prompt. Type `,bt' for a backtrace or `,q' to continue.
scheme#(guile-user) [1]> ,q
You have to make sure, that h is defined.
scheme#(guile-user)> (let ((h 5)) (square h))
$2 = 25
This is the same as in every other language. Try it in C:
int square (int x) {
return x * x;
}
int main (int argc, char** argv)
{
printf ("%d", square (h));
}
Related
Total lisp beginner here.
I'm wondering how to convert a character to symbol. Simply what I want is convert #\a to a
Here what I have done so far:
(defun convert(char)
(if(eq char #\a)
(setq char 'a))
char)
This one is works actually but I don't want to add 26 conditions(letters in alphabet) and make a long-dumb code.
Also I'm wondering is there any functions in common lisp that converts character list to symbol list like: (#\h #\e #\l #\l #\o) to (h e l l o) ? I have found intern and make-symbol related to that but they require string as parameter.
CL-USER 230 > (intern (string #\Q))
Q
NIL
CL-USER 231 > (intern (string #\q))
\q
NIL
Btw., your code has a bunch of improvements necessary:
(defun convert(char) ;
(if(eq char #\a) ; use EQL instead of EQ for characters
; indentation is wrong
(setq char 'a)) ; indentation is wrong
char) ; indentation is wrong
Better write it as:
(defun convert (char)
(if (eql char #\a)
'a
char))
or
(defun convert (char)
(case char
(#\a 'a)
(#\b 'b)
(otherwise char)))
As mentioned above, the 'real' solution is:
(defun convert (char)
(intern (string char)))
(defun converter (c)
(if (characterp c)
(make-symbol (string c))))
You could use make-symbol and convert the symbol to a string.
(setq my-sym (converter #\a))
Answering my own question after a while:
Also I'm wondering is there any functions in common lisp that converts character list to symbol list like: (#\h #\e #\l #\l #\o) to (h e l l o) ?
I can convert single character to symbol with this convert function:
(defun convert (c)
(if (characterp c)
(intern (string c))))
Since one of main ideas of LISP is "processing a list" I can use one of map functions to apply one operation to every single element of the list.
(mapcar #'convert '(#\h #\e #\l #\l #\o))
Here mapcar function will result the list of symbols:
(|h| |e| |l| |l| |o|)
My question is:
Given two natural number returns a list with all the numbers between a and b
I tried this...
* (define (intervalo l s)(cond [(= l s)(make-list l)]
[(< l s)]
[(> l s) empty ])) *
When you say "between a and b", do you mean including the lower bound only? including the upper bound only? Or including both?
Let's make a decision and consider a "half open interval" i.e. the lower bound is included but the upper bound isn't
First, think about what kind of Data the function takes in. As the question states — Natural numbers. Now let's formulate the problem as a brief sentence: "list of numbers from l to s, including l but excluding s"
Some examples:
interval from 0 to 0 will yield an empty list
interval from 1 to 3 will result in (list 1 2)
interval from 3 to 1 is...? It's not valid.
[Refinement] An "assumption" needs be added: the upper bound should be less than or equal to the lower bound.
;; Nat Nat -> [Listof Nat]
;; all nats in [l, s) in order
;; ASUMPTION: (<= l s)
(define (intervalo l s)
(if (= l s) '() (cons l (intervalo (+ l 1) s))))
Racket already provides a range function which can be used as a reference implementation for testing.
An explicit error message can be added for a (> l s) case (the if would be converted to a cond): (raise-arguments-error 'intervalo "lower bound greater than upper bound" "lower" l "upper" s)
I want to define the Thue-Morse Sequence (or the fair-sharing sequence) in terms of an initial element, 0, and the rule defining the next section of the list in terms of the entire list up until this point. i.e.
fair 0 = [0]
--fair 1 = [0,1]
--fair 2 = [0,1,1,0]
--fair 3 = [0,1,1,0,1,0,0,1]
fair n = fair (n - 1) ++ map (1-) (fair (n - 1))
This works fine to generate the list up to any predefined length, but it seems ineffective to not just define the entire list at once, and use take if I need a predefined amount.
My first attempt at defining the entire list was fair = 0 : map (1-) fair but of course, this populates the list as it goes, so it doesn't ever (need to) reenter the list (and returns [0,1,0,1,0,1...]). What I want is some way to define the list so that when it reaches a not-yet-defined element in the list, it defines the next 'chunk' by reentering the list only until that point, (rather than the computation 'chasing' the new values as they're produced), so the steps in computing the list would be akin to this procedure:
begin with initial list, [0]
map (1-) over the existing list, producing [1]
append this to the existing list, producing [0,1]
map (1-) over the existing list, producing [1,0]
append this to the existing list, producing [0,1,1,0]
map (1-) over the existing list, producing [1,0,0,1]
append this to the existing list, producing [0,1,1,0,1,0,0,1]
The Wikipedia article I linked above has a helpful gif to illustrate this process.
As I presume you can see, this would continue indefinitely as new elements are needed. However, I can't for the life of me find a way to successfully encode this in a recursive function.
I have tried
reenter f xs = reenter f (xs ++ map f xs)
fair = reenter (1-) [0]
But while the logic seems correct, it hangs without producing anything, probably due to the immediate recursive call (though I thought haskell's lazy evaluation might take care of that, despite it being a rather complex case).
As you noted, you can't do the recursive call immediately - you first need to return the next result, and then recursively call, as in your last try:
Prelude> reenter prev_list = inverted_prev_list ++ reenter (prev_list ++ inverted_prev_list) where inverted_prev_list = map (1-) prev_list
Prelude> f = [0] ++ reenter [0]
Prelude> take 20 f
[0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,1,0,0,1]
Following is code in Racket, another functional programming language, using the steps listed in the question.
(define (f n)
(define (invert s) ; sub-function to invert the numbers
(list->string
(for/list ((i (string->list s)))
(if (equal? i #\0) #\1 #\0))))
(let loop ((c 1)
(s "0")) ; starting string is "0"
(if (> c n)
s
(loop (add1 c)
(string-append s (invert s))))))
Testing:
(f 1)
(f 2)
(f 3)
(f 4)
(f 5)
Output:
"01"
"0110"
"01101001"
"0110100110010110"
"01101001100101101001011001101001"
For infinite series:
(define (f)
(define (invert s)
(list->string
(for/list ((i (string->list s)))
(if (equal? i #\0) #\1 #\0))))
(let loop ((s "0"))
(define ss (string-append s (invert s)))
(println ss)
(loop ss)))
To run:
(f)
This may give some ideas regarding a Haskell solution to this problem.
I want to create a function that could read my 2 input lists and combine what are inside the lists in to 1 lists, which allows me to use this 1 list for another function.
I have tried to use let function
(defun sumup(p1 p2)
(let ((sum (append(list p1 p2)) ))
(format t "the sum is ~a" sum)
(poly sum)
) )
and when i enter the input lists
(sumup+ '(5 (x 2)) '(3 (x 2)))
it gives results as
the sum is ((5 (x 2)) (3 (x 2)))
the poly term is (8 (x 2))
Here is the function poly, which will read the input list, and do the addition.
(defun poly (p1)
(let((x1(car(car(cdr(car p1))))) (x2(car(car(cdr(car(cdr p1))))))
(e1(car(cdr(car(cdr(car p1)))))) (e2(car(cdr(car(cdr(car(cdr p1)))))))
(c1(car(car p1))) (c2(car(car(cdr p1))))
(remainder(cdr(cdr p1)))
)
(if(and(null remainder)(null c2))
(format t "the poly term is (~a (~a ~a))" c1 x1 e1)
)
(if(and(equal x1 x2)(equal e1 e2))
(poly(append (list(list(+ c1 c2)(list x1 e1))) remainder)))
)
)
so with this function poly
(poly '((5(x 3))(3(x 3))(1(x 3))(4(x 3))))
you will get
the poly term is (13 (x 3))
so my chosen format to represent 5x^2 will be (5(x 2)) this is why i quote.
the sumup function is able to combine 2 terms now,but if
(sumup+ '(5 (x 2)) '((3 (x 2)) (2 (x 2))))
i will get
the sum is ((5 (x 2)) ((3 (x 2)) (2 (x 2))))
how can i change it to be ((5 (x 2)) (3 (x 2)) (2 (x 2)) which can be use for poly function?
The expression '(sum) denotes a list literal. It is a shorthand for the quote operator, and means exactly the same thing as (quote (sum)).
The quote operator suppresses evaluation of its argument as an expression and produces the argument literally; i.e. it means "don't try to call a function called sum; just give me the actual list (sum): a one element list containing the symbol sum".
So for instance (quote (+ 2 2)) or, using the usual shorthand, '(+ 2 2) returns (+ 2 2), literally. If we drop the quote, and evaluate (+ 2 2) then we get 4.
Now if we take '(sum) and simply drop the quote, it won't work, because now we're evaluating the form (sum) which expresses a call to a function whose name is sum, with no arguments. Of course, no such function exists, so the call is erroneous.
There is a special kind of "energized quote" in Lisp which resembles the regular quote. It is called backquote. To use the backquote, we replace the apostrophe ' shorthand with a backtick: `.
Like quote, backquote suppresses evaluation. However, inside a backquote, we can indicate elements which are exceptions to the "do not evaluate" rule, by preceding them with the comma, like this:
`(,sum)
If we have a variable called sum which holds a list (or any other object) and in that scope we evaluate the above backquote, that backquote will compute a list of one element which contains that object. Exactly as if we evaluated the expression (list sum).
More complicated quasiquote example:
(let ((a "hello")
(b 42))
`(1 2 3 ,a 4 ,b b ,(+ 2 2) (+ 2 2)))
-> (1 2 3 "hello" 4 42 b 4 (+ 2 2))
The objects inside the backquote not preceded by a comma are all taken literally: the b is not evaluated as a variable but stays b, the (+ 2 2) stays (+ 2 2) and isn't reduced to 4, unlike the ,(+ 2 2).
Incidentally, inside the poly function, you have this expression:
(append (list (list (+ c1 c2) (list x1 e1))) remainder)
This is a little hard to read. Even though no quoted material is being used, it is still an excellent target for the application of the backquote. With backquote, we can rewrite the expression like this:
`((,(+ c1 c2) (,x1 ,e1)) ,#remainder)
All the distracting clutter of the append and list calls goes away, and we just see the shape of the list being constructed.
Technical note: the backquote isn't a shorthand for any specific form syntax in Common Lisp. Whereas 'X means (quote X), as discussed, `X doesn't have such a correspondence; how it works is different in different implementations of Common Lisp. The comma also doesn't have a specific target syntax. In the Lisp dialect known as Scheme, `X corresponds to (quasiquote X) and ,Y corresponds to (unquote Y). This is defined by the Scheme language and so is that way in all implementations. Backquote is also known as "quasiquote", especially among Scheme programmers.
Assuming defun implies common lisp. Append is defined here.
((5 (x 2))) is a list containing the list (5 (x 2)).
I suspect you are looking for
(sumup (5 (x 2)) (3 (x 2)) )
On the other hand, poly is being called with a quoted list of a single argument, so it's possible you actually want:
(poly sum)
Overall, I think we need to see poly. I'm not clear why you're quoting everything.
I'm taking a list name as input with a single quote ('), but after doing a few operations, I want to actually evaluate it instead of treat it as an atom.
So for example, just for simplicity sake, I have the following list:
(setf LT '(A B C))
I have a function called SEP. To run the function, I must run it as (SEP 'LT). So as you can see, LISP will interpret LT as an atom instead of evaluate it as a list, which is not what I want.
So essentially, I want (SEP 'LT) to really become (SEP '(A B C)) somehow.
The input format can't be changed. Any help would be appreciated. Thanks!
If LT is a top-level variable, defined with defvar, then you can get its value with symbol-value as such:
* (symbol-value 'lt)
(A B C)
* (defun sep (name)
(assert (symbolp name))
(let ((value (symbol-value name)))
...