Home   Archive   Permalink



Not sure what I don't understand about objects

I thought I was so clever. I have this module that produces a report in html format, and to produce a 'line' of the report (which is a row in html), I call a function with a block of words, and inside that function I 'get' the values of the words and put them into the html file. Works fine. Then today, I was using the same module in another program, and the values I wanted to put in the html format were in an object, and when I tried to pass those data names to my module, I got the error message shown below. So instead of passing words to the procedure and getting the value inside the procedure, I had to reduce the words first and pass the values into the procedure, and then things worked again. Actually, that probably is a better way. But anyway, I don't understand the difference in the two approaches, shown in the code sample below, and I am wondering if someone can explain.    
    
Thank you.
    
R E B O L []
    
OUTSIDE-OBJECT-VALUE: none     ;; Word with value, not in object
MODEL: make object! [         ;; Word with value, inside object
     INSIDE-OBJECT-VALUE: none
]
    
OUTSIDE-OBJECT-VALUE: copy 'OUTSIDE VALUE'     ;; Set values to words
MODEL/INSIDE-OBJECT-VALUE: copy 'INSIDE VALUE'
    
;; -- Print values by 'getting' values of passed words
PRINT-VALUE-NOTREDUCED: func [
     NAME-BLOCK
] [
     foreach NAME NAME-BLOCK [
         print get NAME        ;; Passed the word, so must use 'get'
     ]
]
    
;; -- Print values from pre-reduced data
PRINT-VALUE-REDUCED: func [
     NAME-BLOCK
] [
     foreach NAME NAME-BLOCK [
         print NAME            ;; Passed the value, so just print it
     ]
]
    
PRINT-VALUE-NOTREDUCED [OUTSIDE-OBJECT-VALUE] ;; passing just the word, I think
PRINT-VALUE-REDUCED reduce [MODEL/INSIDE-OBJECT-VALUE] ;; reduce first and pass values
PRINT-VALUE-NOTREDUCED [MODEL/INSIDE-OBJECT-VALUE] ;; this produces the error
    
halt
    
OUTSIDE VALUE
INSIDE VALUE
** Script Error: get expected word argument of type: any-word object none
** Where: PRINT-VALUE-NOTREDUCED
** Near: print get NAME
>>


posted by:   Steven White       22-Feb-2016/17:15:03-8:00



You are passing a path to GET, which doesn't work in R2.

posted by:   MarkI       22-Feb-2016/23:41:57-8:00



An R2 tweak to handle getting the value from a path is:
    
PRINT-VALUE-NOTREDUCED: func [
     NAME-BLOCK
] [
     foreach NAME NAME-BLOCK [
         either path? NAME [
             print do NAME
             ][
             print get NAME        ;; Passed the word, so must use "get"
             ]
     ]
]


posted by:   Sunanda       24-Feb-2016/18:37:29-8:00



First:
    
You mention "the procedure" thrice. But REBOL doesn't have procedures. Compiled languages Pascal do.
    
In a language like Pascal, many would classify a procedure as a "sub-routine" or "sub-program." It's a code block of execution to which the flow of execution can be diverted to execute statements of a language in the order in which those statements appear as written. Procedures do not take input, but produce side effects to data contained in global variables (actual RAM addresses declared by type to restrict the size of RAM requested).
    
Until you get scientific with your language, you will have a harder time understanding reality.
    
Now to fix your problem, you might consider a specification block for your function that restricts the datatype! Why? No surprises.
    
A function should take input of a kind or kinds and return output of a kind. Certainly, it would be clearer and easier to maintain if you did something like this:
        
;; -- Print values by 'getting' values of passed words
say: func [
     b [block!]
] [
     forall b [
         print b/1
     ]
]
    
Then, given this:
    
m: make object! [        
     a: none
]
        
x: copy "OUTSIDE VALUE"
m/a: copy "INSIDE VALUE"
        
You could do this.
    
>> say reduce [x]
OUTSIDE VALUE    
    
>> say reduce [get in m 'a]
INSIDE VALUE
    
That is more or less how all of the built-in words of the RVC ("REBOL") Dictionary work.
    
    
And if you desired to handle either block! or string! you could write another version, something like:
    
say: func [
     bs [block! string!]
] [
        any [
            if string? bs [ print bs]
         forall bs [
             print bs/1
         ]
     ]
]
    
>> say x
OUTSIDE VALUE
>> say get in m 'a
INSIDE VALUE
>> say reduce [x]
OUTSIDE VALUE
>> say reduce [get in m 'a]
INSIDE VALUE
    


posted by:   Time Series Lord       5-Oct-2016/19:08:30-7:00



Thank you. Your explanation reminds me the one lesson I remember from calculus. The teacher insisted that in the notation for the limit of a function, the small Greek letter "delta" must be spoken of as "the change in x" because how a person talks about things influences how a person understands things. I come from a background of procedures and side effects, and I do realize that I keep trying to bend REBOL into my paradigm. But, as they say in some circles, the first step to solving a problem is knowing that you have one.

posted by:   Steven White       6-Oct-2016/9:33:16-7:00



It's cool Steven. You seem like a guy who really wants to master REBOL.
    
The interesting bit about REBOL is this. All words in blocks are data. So you're not really programming with REBOL. In a way, you're kind of like writing in a well-defined pseudo-code. Said another way, you're writing a description of what you would like something to do if it were transformed into code.
    
func is a like special kind of parse that tells the RVC to parse your blocks of data the specification block! and the body block! and interpret those blocks with meaning as if they were code of the do dialect.
    
Like Carl Sassenrath said, "REBOL is much deeper than it first seems. On the surface you see a reflection that looks much like other scripting languages but that is an illusion I put there to help people get started with it. REBOL is actually much more than a scripting language and it is also much more powerful in its design than other scripting language, or even most programming languages."
    
If workers in carpentry called every tool a thing, how would anyone know which to use in the next moment a band saw, hammer, circular saw, drill?
    
The words of computer science mean something. Alas, many teachers of it are bad at teaching because they lack language precision with their field. Said another way, they do not understand themselves what they are trying to teach others.
    
Also, most are no longer taught about hardware and the connection between hardware and programming languages as software. Yet, knowing this is vital to understanding what languages are trying to do for programmers.
    
You would need to learn a bit about the history of programming languages, but not too much, to learn how assembly and macro assembly arose and from that how compilers arose for languages like Fortran and Algo. And then if you learned about how structured programming came about to overcome spaghetti code, you would have enough of a background to get a clear distinction between procedures and functions.
    


posted by:   Time Series Lord       6-Oct-2016/13:10:40-7:00