make <object-type> append
[1/5] from: gjones05::mail::orion::org at: 14-Jun-2001 6:59
In working on the http scheme and transparent cookie management, I've been using
construct that RT uses in forging headers. I can understand what the end result
is, but I do not really *understand* the construct. Here is an example:
account: make object! [
name: make string! 100
]
account: make account [
balance: $2000
]
This sequence creates:
make object! [
name: ""
balance: $2000.00
]
Now for the make -type- append version:
account: make account append [
phone: make issue! 10] [state: make string! 2]
Adds two fields to the object:
make object! [
name: ""
balance: $2000.00
phone: #
state: ""
]
The second block following append may be empty but must be present.
Using make in this way seems to be equivalent to:
account: make object! [
name: make string! 100
]
account: make account [
balance: $2000
]
account: make account [
phone: make issue! 10
state: make string! 2
]
Can someone help me to understand what, why, and/or how append is being used in
this context? I could find no documentation that addresses this point.
Thanks.
--Scott Jones
[2/5] from: petr:krenzelok:trz:cz at: 14-Jun-2001 14:26
Hi Scot,
nothing special going on imo :-) Let's forget object construct and use only:
->> append [phone: make issue! 10] [state: make string! 2]
== [phone: make issue! 10 state: make string! 2]
Are you still wondering, why does 'append need second value to joing first one?
Because it is imo 'append's nature :-)
So - append just appends second block to first one and then it is passed to object
creation process .... I just hope I am not completly wrong :-)
Cheers,
-pekr-
[3/5] from: gjones05:mail:orion at: 14-Jun-2001 7:51
From: "Petr Krenzelok"
...
> So - append just appends second block to first one and then it is passed to
object
> creation process .... I just hope I am not completly wrong :-)
Yes, PeKr,
That makes perfect sense and is great way to think about it. I just had an "Ah
ha" experience. It seems so obvious now that I don't know why that didn't occur
to me earlier. Thanks!
--Scott Jones
[4/5] from: joel:neely:fedex at: 14-Jun-2001 7:52
Hi, Scott,
Forgive me if I insult your intelligence by proceeding in very
small steps; that's just my own style for picking apart the
pieces of a puzzle with several components, so it's about me
and not about you.
GS Jones wrote:
...
> account: make object! [
> name: make string! 100
<<quoted lines omitted: 7>>
> balance: $2000.00
> ]
First tricky point: MAKE requires two arguments, a type and
a spec. However the type parameter can be an example or
prototype, instead of being a literal type. If the first
argument to MAKE is an object, MAKE will create another object
with all of the attributes of the prototype. However, the
second argument -- the spec -- is still required, as REBOL
non-syntax doesn't cater well to variable numbers of arguments.
Therefore, if we have
>> source account
account:
make object! [
name: ""
balance: $2000.00
phone: #
state: ""
]
(the final state of your transcript), we can say
>> other-account: make account []
>> source other-account
other-account:
make object! [
name: ""
balance: $2000.00
phone: #
state: ""
]
So (pardon the reiteration) MAKE always takes two arguments:
1) a (proto)type, and
2) a spec (which provides attributes, in the case of an
object creation.
> Now for the make -type- append version:
> account: make account append [
<<quoted lines omitted: 6>>
> state: ""
> ]
At this point, it's important to parse that expression to see
what's happening. We could have written that last line as:
>> account: make account (append [phone: make issue! 10]
[state: make string! 2])
(***WITHOUT*** the line break; unlike strings and blocks,
REBOL won't continue parens in interactive mode.)
The point is that the second argument (spec) to MAKE is simply
the result produced by APPEND.
> The second block following append may be empty but must be
> present.
>
APPEND takes two arguments. You can append an empty block to
another block, but you can't omit the second argument entirely.
>> append [1 2 3] []
== [1 2 3]
>> append [1 2 3]
** Script Error: append is missing its value argument
** Near: append [1 2 3]
> Using make in this way seems to be equivalent to:
> account: make object! [
<<quoted lines omitted: 7>>
> state: make string! 2
> ]
Exactly. Because the value of the APPEND in your prior code is
>> append [
[ phone: make issue! 10] [state: make string! 2]
== [
phone: make issue! 10 state: make string! 2]
(a single block, which can serve as the spec for MAKE).
> Can someone help me to understand what, why, and/or how
> append is being used in this context? I could find no
> documentation that addresses this point.
>
I have no idea *why* one would APPEND two literal blocks before
supplying them as a spec for MAKE (instead of simply writing
their content as a single block), but I hope the above makes
it more clear *what* is happening:
1) APPEND constructs a block from two blocks.
2) MAKE uses that result as the spec argument when creating
a new object, based on the old value of ACCOUNT as its
prototype.
3) ACCOUNT is set to refer to that new object.
AFAICT, you can use any expression that constructs a correctly-
formed block to supply the second (spec) argument to MAKE. e.g.:
>> account: make object! [
[ name: make string! 100
[ ]
>> account: make account [
[ balance: $2000
[ ]
>> account: make account reduce [
[ to-set-word "phone" 'make 'issue! 5 + 5
[ to-set-word "state" 'make type? "foo" 1 + 1
[ ]
>> source account
account:
make object! [
name: ""
balance: $2000.00
phone: #
state: ""
]
That just happens to be a particularly awkward way to do it! ;-)
-jn-
------------------------------------------------------------
Programming languages: compact, powerful, simple ...
Pick any two!
joel'dot'neely'at'fedex'dot'com
[5/5] from: gjones05:mail:orion at: 14-Jun-2001 8:37
From: "Joel Neely"
> Forgive me if I insult your intelligence by
> proceeding in very small steps; that's just
> my own style for picking apart the pieces
> of a puzzle with several components, so
> it's about me and not about you.
Hi, Joel,
One has to have intelligence, in order for the intelligence to be insulted!
;-)
The stepwise approach serves as a type of assertion checking for erroneous
assumptions. If PeKr had not beat you to the Send key, your explanation would
have guaranteed that I understood. Thanks for taking the time. Just a couple
more comments for your edification...
...
> I have no idea *why* one would APPEND two literal blocks before
> supplying them as a spec for MAKE (instead of simply writing
> their content as a single block), but I hope the above makes
> it more clear *what* is happening:
Yes, it does. I left out the context in which RT uses this method, but I'll
explain further below.
...
> AFAICT, you can use any expression that constructs a correctly-
> formed block to supply the second (spec) argument to MAKE. e.g.:
For some reason I developed a mental block (a stuttering paradigm shift?). I
had it in my head that this construct was some special form of make!, forgetting
that append is just passing along the second parameter (the spcification, in
this case). Like I said to PeKr, it is embarrassingly obvious now. I am always
glad to learn, so it was worth it.
...
> That just happens to be a particularly awkward way to do it! ;-)
The context in which RT used this construct was to conditionally pass another
specification to the make.
Here is the snippet:
HTTP-Get-Header: make HTTP-Get-Header append [
Referer: either find port/url #"?" [head clear find copy port/url #"?"]
[port/url]
Content-Type: "application/x-www-form-urlencoded"
Content-Length: length? post-data/2
] either block? post-data/3 [post-data/3] [[]]
This was slightly shorter than using a second conditional make, like:
HTTP-Get-Header: make HTTP-Get-Header [
Referer: either find port/url #"?" [head clear find copy port/url #"?"]
[port/url]
Content-Type: "application/x-www-form-urlencoded"
Content-Length: length? post-data/2
]
if block? post-data/3 [
HTTP-Get-Header: make HTTP-Get-Header [
post-data/3
]
I guess I am still getting used to the functional aspect of functional
programming. It is happening less often.
Thanks again for the thorough discussion.
--Scott Jones
Notes
- Quoted lines have been omitted from some messages.
View the message alone to see the lines that have been omitted