Assigning the result of an expression to a variable - lisp

Working with DrScheme (language-- Pretty Big). Trying to pass the result of an expression to a variable that can later be used in another expression. Here is a simplified version of the problem:
Definitions window:
(define (tot a b c) (+ a b c))
(define (tot2) (+ (tot a b c) 1))
Interpreter window
> (tot 5 6 7)
18
> (tot2)
. . reference to undefined identifier: a
The result I want, of course, is 19. It would be easy to have DrScheme do all the algebra at once, but I need to have it solve the first expression, then solve the second expression based on the result of the first.

Is this what you are looking for?
(define (tot a b c) (+ a b c))
(define (tot2 a b c) (+ (tot a b c) 1))
Then
(tot2 5 6 7)
should result in 19.
If you want tot2 assigned to the integer value rather than to a function,
(define (tot a b c) (+ a b c))
(define tot2 (+ (tot 5 6 7) 1))
assigns the result of the expression (+ (tot 5 6 7) 1) to the name tot2

Scheme is lexically scoped: so a, b, and c will only exist for the dynamic extent of tot.
The dynamic extent of a procedure call is the period between when the call is initiated and when it returns (via gnu).

You're imagining a "persistence" that isn't there, though it's probably plausible, given prior experience with math.
That is: if I'm solving a math problem, and I say that x equals 5, well then x should stay equal to five for the remainder of the problem; until I erase the board, for instance.
So, can you write a programming language like this? Yes! In fact, I could write a small macro in DrScheme for you that produced exactly the behavior you appear to be looking for: it would set up a global table of variables so that every variable binding caused an update to this single table of variables.
BUT! All of the programmers I surveyed (one) (okay, it was me) agreed that this would be a very bad idea.
To see why, imagine that I have a large program that contains several variables called 'a'. Then, any time someone in part A of the program calls a function with a variable named 'a', then part B of the program will suddenly change its behavior. This will make it nearly impossible to reason about the behavior of larger programs.
More generally, this is the problem with "state" and "mutation".
For this reason, you cannot refer to variables other than the ones that are "in scope". That is, those variables whose binding form (in this case a 'define') encloses the reference.

Based on your comments on John's answer, I think what you want is just to assign the result of each function call to a variable (either one variable for each or stick them all in a list) and then add those results together.

After reading through everyone's comments, I realized that I was confusing two issues: having the interpreter evaluate an expression with variables, and actually supplying values for those variables. Because of this confusion, the questions I asked did not make sense. Here's a simplified version of the solution. As you can see, it is embarrassingly simple-- I just used "read" to have the user enter the values.
(define a (read))
(define b (read))
(define c (read))
(define d (read))
(define ee (read))
(define f (read))
(define tot (+ a b c))
(define tot2 (+ d ee f))
(define grandtotal (+ tot tot2))
(display grandtotal)
I used this approach with the actual program and now have a nice little application that totals my hours worked for the week. Thanks everyone for your patient assistance.

Related

Generate code in macro lisp

I would like to generate code: (nth 0 x) (nth 1 x) ... (nth n x)
where x is just some variable name, and n is some number.
I'm trying do this in a following way:
(defmacro gen(n)
(loop for i from 1 to n do
`(nth i x))
)
Checking how it expands by:
(print (macroexpand-1 '(gen 5)))
Console output is: NIL. How to do it properly?
You need to replace do with collect in your loop.
Note however that your macro captures the variable x from the calling environment.
Generally speaking, "macros are advanced material", if you are not comfortable with loop, you probably should not be writing them.
Consider what the value of the following code is:
(loop for i from 1 to 5
do `(nth ,i x))
Since there's no collection happening, the return value of the loop is nil. If we change do to collect:
(loop for i from 1 to 5
collect `(nth ,i x))
We see that we are getting somewhere. However, the resulting list is not actually valid Common Lisp code (and relies on there being a variable x in the environment where the macro is used).
It is not clear what you want to do with these (just run them? they're side-effect free, so just wrapping this in a progn feels somewhat useless), but you need to either cons a progn, list or similar to the front of the list of lists to make it into valid code.
(defmacro gen (n &key (var 'x) (accumulator 'list))
(cons accumulator
(loop for i from 1 to n
collect `(nth ,i ,var))))
This eventually gives us this macro that seems to actually do something approaching "valid".

unbound identifier in module error ( palindrome number )

I'm a noob in scheme ... I am trying to make an exercise so that it will check if a number is a palindrome or not ( I know how to do it in c, c++ and java). But I keep getting this error "c: unbound identifier in module in: c". I searched wide and far for the error, and yes there are tens of topics on it, but all on complicated stuff that have nothing to do with my punny code. My question is, can somebody please explain to me what does the error actually mean and how can I avoid it ? My code so far :
#lang racket
(define (palindrome n)
(if (> 10 n) #t
(check n)
)
)
(define (check n)
(if (> n 0)
((= c (modulo n 10))
(= x (+ (* x 10) c))
(= n (/ n 10)))
(checkp )
)
)
(define (checkp k)
(if (= k n) #t
#f)
)
The error reported occurs in the check procedure. All those references to the variables called c and x will fail, what are those variables supposed to be? where do they come from? Remember: in Scheme = is used for comparing two numbers, not for assignment.
There are other problems. The last line of check is calling checkp, but you forgot to pass the parameter. Also the syntax in the if expression is wrong, you can't write more than two conditions in it (the "consequent" and the "alternative"), if you need more than two conditions you should use cond.
Please be careful with those parentheses, you must not use them to group expressions (they're not like curly braces!). In Scheme, if you surround an expression with () it means function application, and that's not what you want to do in check.
And in the checkp procedure we have the same problem: the variable n is unbound. It's just like in any other programming language: you have to make sure that the variables come from somewhere (a parameter, a local variable, a global definition, etc.), they can't simply appear out of thin air.
UPDATE
After the update, now it's clear what you wanted to do. I'm sorry to say this, but you don't have a good grasp of even the most basic concepts of the language. All along you needed to do an iteration (typically implemented via recursion), but this is reflected nowhere in your code - you'll have to grab a good book or tutorial on Sceheme, to get the basics right. This is how the code in Java or C would look like in Scheme:
(define (check k)
(let loop ((x 0) (n k))
(if (zero? n)
(= k x)
(loop (+ (* 10 x) (remainder n 10)) (quotient n 10)))))
(define (palindrome)
(display "Enter the number: ")
(if (check (read))
(display "The number is a palindrome")
(display "The number is not a palindrome")))
Use it like this:
(palindrome)
Enter the number: 12321
The number is a palindrome

Where's foldl1 and foldr1 in Racket?

Racket has only foldl and foldr, which require initial value. Haskell in addition has foldl1 and foldr1, which instead of applying a function on the initial value and the first element, applies to first and second element. Currently i implemented them as:
(define (foldl1 f xs)
(foldl f (first xs) (rest xs)))
Is there a better way?
There is a better way, just (require srfi/1) and use reduce and reduce-right. :-D
What you are describing looks like reduce in CL. Your procedure looks ok except it would fail if the list is empty.
Be aware that first and rest are not the same as car and cdr since they only work on proper lists. eg.
(first '(a b c d e . f))
;;==>
;;first: contract violation
;; expected: (and/c list? (not/c empty?))
;; given: '(a b c d e . f)
Now. For racket to signal here it must have traversed the whole list to make sure it ends with null and since it didn't it signaled an error. I did a small test and found out that sorting a 2 million list used 32% more time with first/rest.

What is the proper way to construct a clojure macro from lists of symbols?

Imagine the following code to dynamically create a macro:
(def a (list '+ 1 2))
(def b (list '- 10 5))
(def c (list '/ 22 2))
(defmacro gg [h]
(let [k# `~h]
k#))
The intent is to pass a vector of symbols to a macro, do some evaluation on each element of the vector such that it returns a nice macro-esque form, then have the macro combine them into a nice macro and evaluate it. The above example works all except the actual evaluation.
When I run it I get:
(gg [a b c])
=> [(+ 1 2) (- 10 5) (/ 22 2)]
What is the secret to passing a symbol that is a list of symbols and getting a macro to evaluate them? I have tried lots of combinations of quoting and have yet to hit the right one.
The real purpose of this question is to build an Archimedes Ogre query based on a definition of a path through the graph. If someone has an example of that, I would be grateful.
EDIT:
(defmacro gg2 [h]
`(do ~#(map identity h)))
(macroexpand '(gg2 [a b c]))
=> (do a b c)
(gg2 [a b c])
=> (/ 22 2)
I was hoping to get 11 rather than the form.
You don't need a macro. Macros don't do what you're looking for here. What you are looking for is eval.
(def a '/)
(def b 22)
(def c 2)
(eval (list* [a b c]))
=> 11
Of course, you can write a macro which expands into (eval (list* ...)) if you want. It could just as well be a function though.
This is a very common mistake when starting out with macros; trying to write a macro which depends on the run-time value of its arguments. Macros run at compile-time, and generally the values of the symbols which you pass to a macro are not yet available when the macro is expanded.
About the use of eval, some cautions are in order. No one said it better than Paul Graham:
Generally it is not a good idea to call eval at runtime, for two reasons:
It’s inefficient: eval is handed a raw list, and either has to compile it on the spot, or evaluate it in an interpreter. Either way is slower than compiling the code beforehand, and just calling it.
It’s less powerful, because the expression is evaluated with no lexical context. Among other things, this means that you can’t refer to ordinary variables visible outside the expression being evaluated.
Usually, calling eval explicitly is like buying something in an airport gift-shop. Having waited till the last moment, you have to pay high prices for a limited selection of second-rate goods.

What would the consequences be of allowing special forms to be treated as normal values?

I discovered that special forms can not be passed as arguments or saved in variables, both in Clojure:
user=> (defn my-func
[op]
(op 1 2 3))
#'user/my-func
user=> (my-func +)
6
user=> (my-func if)
java.lang.Exception: Unable to resolve symbol: if in this context (NO_SOURCE_FILE:5)
user=> (def my-if if)
java.lang.Exception: Unable to resolve symbol: if in this context (NO_SOURCE_FILE:9)
and in Racket/Scheme:
> (define (my-func op)
(op 1 2 3))
> (my-func +)
6
> (my-func if)
if: bad syntax in: if
> (define my-if if)
*if: bad syntax in: if
That's cool, I'm fine with that, I know that I can just write a function to wrap a special form and then pass that function.
But I'd like to know why Lisps have this restriction, and what negative consequences allowing this would have. Are they any major dialects that do allow that?
It makes evaluation more complicated and compilation hard.
If you have a form (a b c), then you need to resolve at runtime the value of a and then apply it somehow to the forms b and c.
The simpler model of a few limited number of special forms and otherwise strict evaluation is then gone.
See also: FEXPR
Special forms are not functions: functions take values as arguments, whereas special forms take forms. For example, look at your example of if:
(if 1 2 3)
Okay, that's easy, since 2 and 3 are already values. But what about this?
(define (modadd a b n)
(if (zero? n) #f (modulo (+ a b) n)))
In this case, the if is actually receiving the #f and (modulo (+ a b) n) as forms, not as values. And this is important! (modulo x n) will fail if n is 0: that is why it's left unevaluated until we know that n is not 0.
The trouble with being able to pass special forms as first-class objects is that higher-order functions cannot call those objects using predictable semantics: is it a function object, so that you're passing in values, or is it a special form, so that you're passing in forms? This gets to be a huge mess.
Yes, you can write a wrapper function, like my modadd, that encapsulates if. However, there is no way you can just reimplement if as a function, while still preserving the only-evaluate-one-of-the-branches behaviour.