r3wp [groups: 83 posts: 189283]
  • Home
  • Script library
  • AltME Archive
  • Mailing list
  • Articles Index
  • Site search
 

World: r3wp

[Core] Discuss core issues

Fork
31-Mar-2008
[9806x4]
Thanks Gabriele, I think I understand, and knowing the actual answer 
is helpful in understanding the fundamental springs and pulleys that 
make the REBOL machine work.
One of the first errors I encountered while trying to run an installer 
that was built in REBOL was that a state machine driven by a variable 
was failing to match a case and falling through to a default, due 
to a spurious linefeed on one of the cases that was read in.  It 
was attempting to match foo, but had foo^/ ... and so it fell through 
to the wrong case.  So I have been tinkering with a checked enum 
for REBOL.
If anyone has input on to the approach, I'd appreciate feedback: 
http://pastebin.com/d698d3c16
Oops, deleted some spurious code and that made a typo, will make 
a better version that prints section headers for the tests...
Anton
1-Apr-2008
[9810x5]
I guess you figured it out already, but you can use TRIM to remove 
leading and trailing whitespace from your input.
I'm not sure why you are taking this approach, but it seems to be 
something which you might implement to make another language more 
useful :) I don't think it's needed in rebol. Perhaps you could explain 
how you're using this enum/switch in more detail...
A small tip:
	for index 1 (length? cases) 1 [
is usually better as:
	repeat index length? cases [
(I almost never use FOR. I use REPEAT very often).
Fork, perhaps you can show us the original (approximate) example 
from your installer state machine, with a few example inputs and 
expected results. Then we can see what started all this :)
Fork
1-Apr-2008
[9815x5]
Here is a better documented version:
http://pastebin.com/m2e06f2b7
I explain the cases in the header
Here is the output with performance data of the testing:
http://pastebin.com/m20abc2ca
Anton
1-Apr-2008
[9820]
Ok, that explains the enum object well. However, it looks like a 
waste of time to me ! (sorry) but I haven't felt I needed this in 
rebol for many years !
Fork
1-Apr-2008
[9821x2]
I suppose it depends on what kind of code you write
This specific case came up when I tried to install a large, professional 
grade REBOL system written by people who are as I understand it very 
good at REBOL
Anton
1-Apr-2008
[9823]
That may be true.
Fork
1-Apr-2008
[9824]
There is no integrated debugger, and so tracking this kind of stuff 
down isn't as easy as it might otherwise be
Anton
1-Apr-2008
[9825]
Can we see what the specifics of the original case are with respect 
to the enum ?
Fork
1-Apr-2008
[9826x5]
nextstep: cgi 'nextstep
So it was getting a CGI variable in an HTTP post
Then it did switch/default nextstep [ (various cases, pages long) 
] [ the default case ]
A bug in the cgi system left a trailing newline on the nextstep variable
SO instead of being "apache1" it was "apache1^"
Anton
1-Apr-2008
[9831x3]
Ok, so you saw the enum object as an extra level of protection against 
this kind of bug.
To more strictly validate input.
Or was it just to catch where the bug was ?
Fork
1-Apr-2008
[9834x2]
It validates on all sides, it protects against programmer error in 
the usage as well as things like this where the data source or function 
has a problem.
I do like REBOL from what I've seen so far!  But I saw somewhere 
that it was being compared to modeling clay... it's a paradigm shift 
for people who are used to systems that do a lot of global analysis 
of your program before it runs the first line of code to catch basic 
errors.
Anton
1-Apr-2008
[9836x2]
Yes, definitely.
make-enum-type should define 'ret local.
Fork
1-Apr-2008
[9838]
I do remember that, though I don't exactly remember what happens 
if you don't do it
Anton
1-Apr-2008
[9839]
It sets 'ret global. Check this by running the script then probe 
ret in the console.
Fork
1-Apr-2008
[9840x4]
Ah, ok
So same for test-block
(start/end)
And pretty much everything else... I'll go over it.  I should probably 
use "function" as I don't care so much for /local
Anton
1-Apr-2008
[9844]
Yes, but that's just your test code. Usually I don't bother being 
so strict with test code because I know I'm going to throw away the 
console afterwards. The reusable library part is the important part 
to be watertight.
Fork
1-Apr-2008
[9845]
I get the feeling that I'm going to want to have an analysis tool 
which will read through the functions, find any variable: assignments, 
and ensure they're in the local list unless there's some sort of 
indication they should be global.  Because it seems relatively uncommon 
that I would, inside a function, set things in the global space. 
 I'd be happy to use something wordier (set?) for that
Anton
1-Apr-2008
[9846]
I recommend FUNC over FUNCTION because having "/local" written makes 
it clearer and explicit what the locals are, and is shorter when 
there are no locals. Compare:

When there are no locals, func wins, because less characters to type.
	func []
	function [][]

When there are locals, same number of characters written, but func 
more clearly specifies the locals.
	func [/local]
	function [][]

Additionally, when you are modifying your func spec back and forth 
so that there is a need, or no longer a need, for locals, then func 
wins by less typing needed.
Fork
1-Apr-2008
[9847x4]
Hm, well, it's not a tremendous deal but I feel like always being 
forced to remember typing in that second group would remind me that 
I need to think about what goes in it
Is there a way to set things locally in a do block?
Or do you have to do a nameless function to get a local context?
e.g. do func[/local v] [v: 1+2]
Anton
1-Apr-2008
[9851x2]
I go without such a tool for analysing function local variable consistency, 
which, I think, turns out to be a difficult problem to solve. Some 
people have written alternative function creators which somehow make 
set-words into locals by default (Ladislav ? with his lfunc ?) or 
something like that. I just maintain a strict habit of checking for 
accidental globals. It's good to review your use of variables regularly 
anyway, and be aware of what context they're bound to.
use [v][v: 1 + 2]
Fork
1-Apr-2008
[9853]
Ah, an lfunc, that sounds nice
Anton
1-Apr-2008
[9854x2]
do [
	use [v][v: 1 + 2]
]
context [
	v: 1 + 2
	print v
]