Mailing List Archive: 49091 messages
  • Home
  • Script library
  • AltME Archive
  • Mailing list
  • Articles Index
  • Site search
 

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