Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 2 years ago.
Improve this question
I'm new here. I'm soon to have a test, a test language scheme, and I'm getting ready for it.
I have a question that I try to solve for a few hours but do not even understand how to start it.
The question goes like this:
There is a new expression of this form:
(get-procedure-body <exp>)
This expression receives a single expression as an argument, evaluates it, and if a user procedure type value is obtained, returns
Her body.
Question in scheme language
Hello everyone, I'm new here. I have a test soon, a test language test, and I'm getting ready for it.
I have a question that I try to solve for a few hours but do not even understand how to start it.
The question goes like this:
There is a new expression of this form:
This expression receives a single expression as an argument, evaluates it, and if a user procedure type value is obtained, returns
Her body.
Here are the possible cases after the revaluation of :
If the returned value is a user procedure - its body must be returned
If the returned value is a primitive procedure - “Hidden Implementation! primitive“
If the value is not a procedure, print "procedure-non: error"
Possible output of the operation of the function:
(get-procedure-body f)
> ((display x) (* x y))
(get-procedure-body (lambda (x) (h x)) )
> ((h x))
(get-procedure-body +)
> “primitive! Implementation hidden”
(get-procedure-body 1)
> “error: non-procedure”
(get-procedure-body (+ 1 1))
> “error: non-procedure”
The question goes like this:
Add support for body-procedure-get expressions as a kernel expression (write all required changes)
I would be happy if someone could at least help me, I tried to explain myself, if something is not clear, tell me, I will explain more. This is difficult language for me, especially since it does not have much support.
I could not even figure out what to do.
Getting the body of a procedure is not part of Scheme and not Common Lisp standard, however if you have made a Scheme interpreter (eval) with support for user procedures you most likely have the code in question in your chosen data structure and making the non standard primitive get-procedure-body would be exposing the same procedure from the host language. Eg. The book SICP does have something named very similar as part of their interpreter.
As for using Racket I once made this to be able to do something similar:
#lang racket
(struct proc (src obj)
#:property prop:procedure
(struct-field-index obj)
#:transparent
#:methods gen:custom-write
[(define (write-proc x port mode)
((case mode
[(#t) write]
[(#f) display]
[else pretty-print])
(proc-src x)
port))])
(define-syntax lambda*
(syntax-rules ()
((_ . rest)
(proc '(lambda* . rest) (lambda . rest)))))
(define test (lambda* (x y) (+ x y)))
test ; ==> #(struct:closure (lambda* (x y) (+ x y)) #<procedure>)
(proc-src test) ; ==> (lambda* (x y) (+ x y))
(proc-obj test) ; ==> #<procedure>
((proc-obj test) 1 2) ; ==> 3
(test 1 2) ; ==> 3
Now this solution turns the problem upside down. Since I don't have a way to get the source from a system I make syntax that stores the source alongside the procedure object and use a struct feature to package those. As a procedure using lambda* would work the same as lambda with the exception of introspection.
Related
I'm currently trying to gain an understanding about side effects in general with regard to functional programming, racket to be exact. It's my understanding that it relates to changing the state of some variable, like a global one.
Here's some code that I've written;
; Define a variable with the value of 5
(define x 5)
; Define a function to add 1 to x
(define addX
(+ 1 x))
; Test out values
x
addX
x
Which outputs 5 6 5.
Shouldn't the last value be 6? Or is the fundamental principle that I'm missing, the fact that the value is stateless when using functional programming?
The way your code is written, you can think of x as a constant – ie, addX does not mutate the x binding.
It's like the same as (pseudocode)
constant X = 5
constant addX = X + 1
print(X) ; 5
print(addX) ; 6
print(X) ; 5
Functional programming requires the immutable data structures. If you approach scheme/racket with notions from other (imperative style) languages, you'll struggle and the code you produce will be very bad.
(+ 1 x) is an expression. The result of this expression, in the case where we have already (define x 5), is 6. That value just... percolates up to whatever tried to evaluate it. Whether we ask DrRacket to evaluate it, or we assign it to something else, like (define addX (+ 1 x)), what is changing is the expression is becoming the value.
So, if you want to assign a value to an identifier that is already introduced, you need to tell the interpreter to do this assignment. That form is set!, as in,
(define addX #f)
addX ; => #f
(set! addX (+ 1 x))
addX ; => 6
so i am trying to understand this piece of code, and after staring at it for far too long i decided to ask here if anyone could help me understand how and why it works
(define knock-knock
(letrec ([dig (lambda (i)
(cons (* i (list-ref knock-knock (- i 1)))
(dig (+ i 1))))])
(cons 1 (dig 1))))
the function is then called by name with the value:
(list-ref knock-knock 5)
So my main problem is that i can not see where the letrec would end. the other thing is that i am not given a list, so what is the 4th element in the list that i am supposed to reference in line 3?
First, a note: this is not normal Scheme, as it requires lazy evaluation.
In lazy evaluation, values are only computed when they are needed. So, for defining knock-knock, we can just do
(cons 1 <thunk: (dig 1)>)
i.e., we generate a pair, but we don't need the second element, so we defer its evaluation until later.
When we actually want to evaluate the second element, we will already have knock-knock defined, so we can reference it.
The next element is computed by taking the previous (i-1-st) element, and multiplies it by i. So this will generate the series {n!}: 1,1,2,6,24,...
A straightforward translation of this code to the (normally lazy) Haskell language goes like this:
knock :: [Int]
knock = 1 : dig 1
where dig i = (i * knock !! (i-1)) : dig (i+1)
I defined a generic function taking 2 arguments:
(defgeneric interact (a b))
The order of the arguments should not be important, so (interact x y) and (interact y x) should be the same, but I don't want to define two methods that do the same for every combination of different objects.
A Method-Combination of this type should help:
(defmethod interact :around (a b)
(if (some-function a b)
;;some-function has to be true if (eq (class-of a) (class-of b))
;;else (some-function a b) is (not (some-function b a))
;;similar #'<=
(call-next method)
(interact b a))
But I would have to know #'some-function and be able to know the type of the arguments I have to define.
Edit: both proposed approaches have a few limitations discussed in the comments below. Please read them before using this answer!
Can I suggest two options - a working but hacky option for when you only have two arguments, and a vaguely sketched out generic approach which I think should work but I haven't written:
Option 1:
(defparameter *in-interact-generic-call* nil)
(defgeneric interact (x y))
(defmethod interact ((x T) (y T))
; this can be called on pretty much anything
(if *in-interact-generic-call*
(cause-some-kind-of-error) ; Replace this with a more sensible error call
(let ((*in-interact-generic-call* T))
(interact y x))))
(defmethod interact ((x integer) (y string))
; example
(print x )(prin1 y))
(interact 5 "hello") ; should print 5 "hello"
(interact "hello" 5) ; should print 5 "hello"
;(interact "hello" "hello") ; should cause an error
Essentially the idea is to define a generic function which always matches anything, use it to try to swap the arguments (to see if that matches anything better) and if it's already swapped the arguments then to raise some kind of error (I've not really done that right here).
Option 2
Define the generic function as something like interact-impl. Actually call the standard function (defined by defun) interact.
In interact, define a loop over all permutations of the order of your arguments. For each permutation try calling interact-impl (e.g. using (apply #'interact-impl current-permutation).)
At least in sbcl, no matching arguments gives me a simple-error. You probably would want to do a more detailed check that it's actually the right error. Thus the code in interact looks something like
; completely untested!
(do (all-permutations all-permutations (cdr all-permutations))
(...) ; some code to detect when all permutations are exhausted and raise an error
(let (current-permutation (first all-permutations))
(handler-case
(return (apply #'interact-impl current-permutation))
(simple-error () nil)) ; ignore and try the next option
)
)
So what you are looking for is an arbitrary linear order on the class objects.
How about string order on class names?
(defun class-less-p (a b)
"Lexicographic order on printable representation of class names."
(let* ((class-a (class-of a))
(name-a (symbol-name class-a))
(pack-a (package-name (symbol-package name-a)))
(class-b (class-of b))
(name-b (symbol-name class-b))
(pack-b (package-name (symbol-package name-b))))
(or (string< pack-a pack-b)
(and (string= pack-a pack-b)
(string<= name-a name-b)))))
I attempted to follow the solution provided in this question, but it simply didn't work.
Essentially, my function works like so:
(define (item-price size normal-addons premium-addons discount)
(define price 0)
(+ price (* normal-addon-cost normal-addons) (* premium-addon-cost premium-addons) size)
(cond
.. some conditions here
[else price]))
However, I am met with the following error:
define: expected only one expression for the function body, but found 2 extra parts
Now, I've tried wrapping the body of the function in a 'begin', however when run it claims that 'begin' is not defined. I am using the Beginner Student language version as oppose to straight-up Racket. Any insight on a workaround?
The problem remains the same: in the language that's being used, we can't write more than one expression inside a function body, we can't use begin to pack more than one expression, and both let and lambda (which would have allowed us to create local bindings) are forbidden. That's a lot of restrictions, but we can get around using a helper function that calculates the price each time:
(define normal-addon-cost 10) ; just an example
(define premium-addon-cost 100) ; just an example
(define (price size normal-addons premium-addons)
(+ (* normal-addon-cost normal-addons)
(* premium-addon-cost premium-addons)
size))
(define (item-price size normal-addons premium-addons discount)
(cond
... some conditions here ...
[else (price size normal-addons premium-addons)]))
Alternatively: if price is used only once, simply in-line the expression that calculates it, there's no need to create a local variable or a helper function.
I want to create a function that can determine the definition of an arbitrary function in scheme. If we call such a function "definition", it would work as such:
(define (triple x) (* 3 x))
(definition triple) would return "(triple x) (* 3 x)".
There would be some implementation problems (such as with n-arity), but I'm concerned mostly with whether or not the definition of individual functions are easily retrievable in Scheme.
As a continuation, is there a way to create a function that can determine the parameters of an arbitrary function? Such that:
(parameters +) returns (number number) or something similar.
These questions both fall under the question of how functions are stored in Scheme - I found some sources which claimed that function definitions are stored with the function name, but I couldn't find out how exactly they were stored.
If this is impossible - is there a language where function definitions are easily retrievable?
There is nothing like that in Scheme. Individual implementations might have that, though.
In Common Lisp there is the standard function function-lambda-expression, which might be able to retrieve source code - depending on the implementation.
Example in LispWorks (reformatted to improve readability here):
CL-USER 65 > (defun triple (x) (* 3 x))
TRIPLE
CL-USER 66 > (function-lambda-expression #'triple)
(LAMBDA (X)
(DECLARE (SYSTEM::SOURCE-LEVEL #<EQ Hash Table{0} 42201D392B>))
(DECLARE (LAMBDA-NAME TRIPLE))
(* 3 X))
NIL
TRIPLE
SBCL:
* (defun triple (x) (* 3 x))
TRIPLE
* (function-lambda-expression #'triple)
(SB-INT:NAMED-LAMBDA TRIPLE
(X)
(BLOCK TRIPLE (* 3 X)))
NIL
TRIPLE
As you can see it returns three values: the code, whether it is a closure and the name of the function.