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

Help function for contracts

 [1/7] from: jan:skibinski:sympatico:ca at: 17-Oct-2002 14:59


Hi, As an exercise in learning the basics of Rebol I made a little script supporting the Design By Contract. (Yes, I am aware of Maartens' contract.r) I uploaded it as file dbc.r to the library. The script provides, among few other things, the help' function which extends the standard help with notion of assertions. Attached is an output from <help' factorial>. It tells us quite a bit about how the example "factorial" function should be used: - It does not accept negative inputs, x - It limits the input to x <= 12, if x is an integer - etc., etc. Suggestions on how to improve the script are welcome and expected. For example, I am not sure how to control the layout of sources of "contracted" functions. Also, my script lost its "neat" appearance after upload. I edited the stuff in MS notepad, since I cannot afford using anything sophisticated, such as Jedit editor, due to too little memory on my machine. 128 Mb is not enough any more. :-). Used to run (with some limitations) in 32 Mb on Linux boxes. Anyway, enjoy the script if you find it useful, Jan P.S. I am begining to like and appreciate Rebol. =================================================== USAGE: FACTORIAL x DESCRIPTION: Factorial of a number 'x' computed recursively without a help of an accumulator. Example of a function with assertions. FACTORIAL is a function value. ARGUMENTS: x -- (Type: integer decimal) (SPECIAL ATTRIBUTES) catch PRECONDITIONS: [ [x >= 0] [implies (integer? x) (x <= 12)] [implies (decimal? x) (x <= 170)] [implies (decimal? x) (integral? x)] ] POSTCONDITIONS: [ [result >= 1] [result <= max-factorial] [(type? x) == (type? result)] ]

 [2/7] from: greggirwin:mindspring at: 17-Oct-2002 13:53


Hi Jan, Thanks! I'll have to make some time to check in out in depth. I'm a big fan of DbC, and have played around with some ideas myself. In CONTRACT, you're doing this: x: copy [require pre] x/2: pre y: copy [ensure post result] y/2: post Is there a reason you're using two separate steps, rather than something like this: x: copy reduce ['require pre] y: copy reduce ['ensure post 'result] Also, what do you think about ordering the parameters to CONTRACT in the order that they are applied (as it were): spec pre local body post ? I've also toyed with using refinements for specifying pre and post conditions, plus some other wacky function specification dialect ideas. << Also, my script lost its "neat" appearance after upload. I edited the stuff in MS notepad, since I cannot afford using anything sophisticated, such as Jedit editor, due to too little memory on my machine. >> Have you tried ConTEXT or NoteTab-light? --Gregg

 [3/7] from: jan:skibinski:sympatico:ca at: 17-Oct-2002 16:21


Gregg,
> Is there a reason you're using two separate steps, rather than something > like this: > > x: copy reduce ['require pre] > y: copy reduce ['ensure post 'result]
None. As I said I am in the process of learning and some of the idioms are not there yet when I need them. :-) Thanks!
> Also, what do you think about ordering the parameters to CONTRACT in the > order that they are applied (as it were): spec pre local body post ? I've > also toyed with using refinements for specifying pre and post conditions, > plus some other wacky function specification dialect ideas.
Interesting. Keep in touch. We should be able to selectively enable/disable the assertion without side effects. But the side effects are probably the best handled by script developers rather than by DBC. Thanks for the pointers to editors. I'll check them out. Jan

 [4/7] from: g:santilli:tiscalinet:it at: 18-Oct-2002 0:50


Hi Jan, On Thursday, October 17, 2002, 10:21:34 PM, you wrote:
>> x: copy reduce ['require pre] >> y: copy reduce ['ensure post 'result]
JS> None. As I said I am in the process of learning and some of the idioms JS> are not there yet when I need them. :-) BTW, COPY should not be needed if you use REDUCE. Regards, Gabriele. -- Gabriele Santilli <[g--santilli--tiscalinet--it]> -- REBOL Programmer Amigan -- AGI L'Aquila -- REB: http://web.tiscali.it/rebol/index.r

 [5/7] from: jan:skibinski:sympatico:ca at: 18-Oct-2002 20:13


Gregg Irwin wrote:
> Also, what do you think about ordering the parameters to CONTRACT in the > order that they are applied (as it were): spec pre local body post ?
I just posted the updated version of dbc.r The blocks have been reordered, as you suggested. I also added a wrapper, which takes a regular existing function and wraps a contract arount it, as in: g: wrap-dbc pre :f post I might extend it a bit to handle native! functions too. Some fiddling was required because a spec copied from a function f, such as: ["Comment" x [integer!]] would get converted by the "make function! spec body" into: ["Comment" x [datatype!]] Apparently what looked and was printed as 'word was not a 'word at all! :-) One question: How to programmatically insert line breaks into a series of blocks? The reason for this is that I'd like to maintain a neat layout of a source code produced by the wrapper. Inside the wrap-dbc you will see an ugly trick with empty blocks that almost does what I want. body: reduce [ [] 'require pre [] to-set-word 'result 'do fun-body [] 'ensure post [] 'result ] Best wishes, Jan

 [6/7] from: greggirwin::mindspring::com at: 19-Oct-2002 9:46


Hi Jan, << One question: How to programmatically insert line breaks into a series of blocks? >> That's a tricky one. If you use a layout in your code, the line hints are preserved, but I haven't found a way to simulate them. If you're using objects, you can MOLD them to make REBOL do the layout for you, but it doesn't help with blocks.
>> o: make object! [a: 0 b: 1 c: [ca: 2 cb: 3]] >> mold o
== { make object! [ a: 0 b: 1 c: [ca: 2 cb: 3] ]}
>> o: make object! [a: 0 b: 1 c: make object! [ca: 2 cb: 3]] >> mold o
== { make object! [ a: 0 b: 1 c: make object! [ ca: 2 cb: 3 ] ]}
>> third o
== [a: 0 b: 1 c: make object! [ ca: 2 cb: 3 ]] --Gregg

 [7/7] from: jan:skibinski:sympatico:ca at: 19-Oct-2002 17:38


Hi Gregg,
> << One question: How to programmatically insert line breaks into > a series of blocks? >> > > That's a tricky one. If you use a layout in your code, the line hints are > preserved, but I haven't found a way to simulate them.
Actually, I found reasonable solution: use 'compose/deep instead of 'reduce. This snippet appears to produce acceptable layout - clearly delineating the contract structure: ----------------- compose/deep [ require [(pre)] result: do [(fun-body)] ensure [(post)] result ] -------------- I'll update the dbc.r tonight. Regards, Jan