📜 ⬆️ ⬇️

Object-oriented function approach in Scheme

image Hey. In this article I would like to once more highlight the issue of object programming in the Scheme language, as it is considered in the book "Structure and Interpretation of Computer Programs."
Next, I suggest that those who have never programmed on Scheme download DrRacket and try to walk through the steps of the examples in this article. Experienced programmers Scheme, Racket ... this article will be very boring, as it is written for beginners and people who want to "touch" the racket.

And so in order. Diff to start in DrRacket IDE.
Create a new program file. Save it.
Insert the directive pointing to the language at the beginning of the file:
#lang racket 

Define the function:
 (define (func1 x) x) ;    x,  x 

You can use the function like this:
 (func1 10) ;   10 


Now we define another function:
 (define (func2) "func2") 

Now let's try to define a variable such that it applies the first function to the second and returns the second function:
 (define x (func1 func2)) ;  x -     func2 

You must use x as a function:
 (x) ;   "func2" 

Here we used the possibility that a function can return functions, and their result can be defined as variables.
Next, let's create an object that encapsulates internal variables and other functions:
 (define (MyObject field1 field2) ;         field1  field2 (let ((f1 field1) ;    f1,   field1 (f2 field2)) ; ... (define (get-f1) f1) ;     f1 (define (get-f2) f2) ; ... (define (set-f1 x) (set! f1 x)) ;  f1  x (define (set-f2 x) (set! f2 x)) ; ... ;     (define (dispatch m) ;       (cond ((eq? m 'get-f1) get-f1) ;  m  get-f1,    get-f1 ((eq? m 'set-f1) set-f1) ; ... ((eq? m 'get-f2) get-f2) ; ... ((eq? m 'set-f2) set-f2) ; ... ) ) dispatch)) ;     MyObject    

Well, the object is defined, now let's make an instance of the MyObject object:
 (define Obj1 (MyObject " Hello " " world!!! ")) ;  Obj1  

Then just use the instance as we want:
 (display ((Obj1 'get-f1))) ;  - display -  printf,    ;  ((Obj1 'get-f1))    ,    get-f1 (display ((Obj1 'get-f2))) ;  (newline) ;     ;   " Hello world!!! " 

Create a new instance of the same object:
 (define Obj2 (MyObject " Hello " " habra!!! ")) ; ; : "Hello Hello habra!!! world!!!" 

Let's try to perform:
 (display ((Obj1 'get-f1))) (display ((Obj1 'get-f2))) (newline) (display ((Obj2 'get-f1))) (display ((Obj2 'get-f2))) (newline) ;   "Hello world!!!" ;  "Hello habra!!!" 

What struck me was that each instance returns the same functions, but their behavior is not the same.
That is, in Scheme, unlike C ++, functions take variables and functions for calculation from their own instance.
This feature greatly helps the organization of lists of functions for changing the internal states of different instances of one or more objects:
 (define func-list (list (Obj1 'get-f1) (Obj2 'get-f1) (Obj2 'get-f2) (Obj1 'get-f2))) 

We print the execution of each function from this list as follows:
(map (lambda (x) (display (x))) func-list)
; Result: “Hello Hello habra !!! world !!! "

')

Source: https://habr.com/ru/post/144598/


All Articles