Comments on: Changes in MAKE function!
As you know, the datatype creator make accepts a datatype specifier or a prototype:
s: make string! 123
s: make t 123
It is most useful in the case of objects:
ob1: make object! [a: 10]
ob2: make ob1 [b: 20]
During R3 testing, this was listed as a bug:
f1: func [a] [print a]
f2: make :f1 
That expression would read: make f2 using f1 as the prototype.
To make that work, it had to be defined. Here it is the definition...
First, recognize that in R3 the general constructor is:
f: make function [ [spec] [body] ]
Just use source on func to see such details.
So, now you know the format for make function prototype. It is the same.
f2: make :f1  ; just copy the function
f3: make :f1 [[body]] ; keep spec the same, use new body
f4: make :f1 [[spec][body]] ; replace spec and body
The f3 case is the most useful. It lets you "inherit" the function specification (e.g. argument list), but redefine the body of the function. F2 and f4 cases are just for completion of the form.
As a trivial example:
mo-string: make :to-string [[mold value]]
An additional note: you can also use copy now, instead of the f2 case above.
f5: copy :f1
Note that all parts are deep copied and rebound to the new function context.
I'm not sure how much it's useful to share the spec block because if you modify body, you should change description as well, which is in the shared spec.|
It can be useful for debugging : I like to change the behaviour of some function in another part of the script (replace by console output,force the return of a specific value,...)
Isn't it ?
not sure above is consistent. How is that first element of function spec block refers once to body, and for the second time to spec of the function? So, as for me, I might get used to it, but I have objection to how 'f3 is explained. If we want to have it consistent, it should look:
f3: make :f1 [  [body] ]
It is both consistent with 'f2 (you use empty block for the copy of supposed element, and, the order of blocks is still kept correct - first one is spec, second one is body.
I know it might not look so elegant as yours 'f3, but imo users might appreciate it, when dynamically inspecting function definition. In your example, we will have to check for the length of the block first, to just find out, if the first element is spec, or a body ...
Petr,  is a valid spec, so how would REBOL tell the difference between f3 an f4 in your notation?|
I find pekrs point valid, so how about
f3: make :f1 [none [body]]
Like goldevil I have had uses of this pattern, though being able to keep the spec, but change the main description would be very handy.
Brian, maybe I don't understand the issue properly, but what do you mean? Isn't difference between 'f3 and 'f4 clear?
f3: make :f1 [  [body] ]
f4: make :f1 [ [spec] [body] ]
Pekr, how would you do this using your example?
;I have -
f1: func [a][print "I take one parameter"]
;and I want -
f2: func [print "I take no parameter"]
f2: make f1 [[print "I take no parameter"]]
Using your example, I'm not able to make a function with empty spec, which is valid REBOL function. But with Ingo's example it's possible, using [none [body]].
What about the functions make them special from regular objects? Instead of the definition of a function being
f1: make function [ [spec] [body] ]
Let it be:
f1: make function [
Now it works just as one would expect, is more flexible (why not add documentation: and other fields?) and it's possible to add extra information into a function if desired:
f2: make :f1 [
rev-2: "Fixed by Bob on 12/11/07"
body: [ new code here ]
Functions are not objects and I really like the difference in REBOL. I'm not a fan of OOP. I do like the idea of creating new functions with a template made from the interface of the old function. I like this implementation.|
Post a Comment:
You can post a comment here. Keep it on-topic.