Search code examples
schemelispcommon-lispracketsicp

add support to new expression scheme language


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.


Solution

  • 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.