When is none not none?
[1/8] from: jonkelly:fastmail:fm at: 26-Jul-2007 23:51
Hi,
newbie alert. I'm confused.
I managed to finally get the attached script (t3.r) to work as I expect.
It's a binary tree insertion function. BUT, if you change all the
empty blocks for none (t4.r), (which was how I tried to start out) it
barfs, saying none is a word.
I was trying to do a purely function version but that made my head hurt.
Jonathan.
-- Binary/unsupported file stripped by Ecartis --
-- Type: text/x-rebol
-- File: t3.r
-- Binary/unsupported file stripped by Ecartis --
-- Type: text/x-rebol
-- File: t4.r
[2/8] from: jonkelly:fastmail:fm at: 26-Jul-2007 23:55
How annoying is that! :/
This is the working version ...
REBOL [
Title: "Binary tree insertion with terminals = []"
Date: 2-Jul-2007
File: %t2.r
Author: "Jonathan Kelly"
Version: 0.0.1
]
add: func [ blk val ] [
print [ "add" blk type? blk blk = [] val]
either blk = [] [
print "at A"
compose [ (val) [] [] ]
] [
either blk/1 = val [
print "at equals"
blk
] [
either val > blk/1 [
print "at greater"
poke blk 3 (add blk/3 val)
] [
print "at less"
poke blk 2 (add blk/2 val)
]
blk
]
]
]
tt: add [] "c"
prin [ "tt is " ]
probe tt
print []
tt: add tt "b"
prin [ "tt is " ]
probe tt
print []
tt: add tt "e"
prin [ "tt is " ]
probe tt
print []
tt: add tt "d"
prin [ "tt is " ]
probe tt
print []
[3/8] from: jonkelly:fastmail:fm at: 26-Jul-2007 23:56
and this is the not working version
REBOL [
Title: "Binary tree insertion with terminals = none"
Date: 2-Jul-2007
File: %t2.r
Author: "Jonathan Kelly"
Version: 0.0.1
]
add: func [ blk val ] [
print [ "add" blk type? blk blk = none val]
either blk = none [
print "at A"
compose [ (val) none none ]
] [
either blk/1 = val [
print "at equals"
blk
] [
either val > blk/1 [
print "at greater"
poke blk 3 (add blk/3 val)
] [
print "at less"
poke blk 2 (add blk/2 val)
]
blk
]
]
]
tt: add none "c"
prin [ "tt is " ]
probe tt
print []
tt: add tt "b"
prin [ "tt is " ]
probe tt
print []
tt: add tt "e"
prin [ "tt is " ]
probe tt
print []
tt: add tt "d"
prin [ "tt is " ]
probe tt
print []
[4/8] from: jonkelly:fastmail:fm at: 27-Jul-2007 0:03
Damn. Why is it you only see these things seconds after you've posted it
to the whole world?? :)
> compose [ (val) none none ]
should be compose [ (val) (none) (none) ]
and it works.
So none is not none when it's the word and not the value.
[5/8] from: henrik:webz:dk at: 26-Jul-2007 16:31
On 26/07/2007, at 16:03, Jonathan Kelly wrote:
> compose [ (val) (none) (none) ]
Alternatively:
reduce [val none none]
And of curiosity, you get none back as a word, which produces an error:
reduce [val 'none 'none]
--
Regards,
Henrik Mikael Kristensen
[6/8] from: moliad::gmail::com at: 26-Jul-2007 11:47
Hi Jonathan,
Welcome to Rebol, hope you have a blast.
what you are experiencing is a subtlety of static run-time loading and
binding. some functions evaluate values and others do not. in this case,
compose loads a block and leaves everything within AS-IS. so since the
interpreter has to put the none somewhere as something, it stays a word,
gets bound to the global definition of none, but isn't evaluated, so its not
yet a none *value*.
I have had the same (I thought "strange", at the time) problems with the
true and false values, which have no lexical form which allows them to be
explicitly cast as a datatype.
since many of us have lived through this exact issue, I can already warn you
about loading data files. nested blocks, do not recursively get evaluated
by load, so you can end up with this same problem when saving out blocks and
objects and stuff.
a good way to identify this is to use the mold/all function which
*serializes* the data. in fact, I have replaced probe in my setup so that
it molds/all in order to clearly identify datatypes.
ex of mold/all usage:
>>a: mold/all compose [none (none)]
>>probe a
== "[none #[none]]"
this allows you to realize without chance of a subtle error, just what is
going on. Note that mold returns a string. then whenever you do a load of
that string, you know that it will return exactly, value-wise, like it was.
HTH !
-MAx
On 7/26/07, Henrik Mikael Kristensen <henrik-webz.dk> wrote:
[7/8] from: lmecir::mbox::vol::cz at: 30-Jul-2007 12:01
Maxim Olivier-Adlhoch napsal(a):
> Hi Jonathan,
>
> Welcome to Rebol, hope you have a blast.
>
> what you are experiencing is a subtlety of static run-time loading and
> binding.
Binding is slightly off-topic in this case, "static run-time" is a
contradictio in adjecto.
> some functions evaluate values and others do not. in this case,
> compose loads a block and leaves everything within AS-IS.
Wrong. The interpreter loads the block before evaluating the expression.
Compose does not. (Do you want a proof?)
> so since the
> interpreter has to put the none somewhere as something, it stays a word,
<<quoted lines omitted: 3>>
> true and false values, which have no lexical form which allows them to be
> explicitly cast as a datatype.
Wrong. Here are the lexical forms of some Rebol values popularly thought
not having lexical form:
values: [#[unset!] #[none] #[false] #[true]]
As opposed to that, when writing:
words: [unset! none false true]
the Words block will just contain words.
> since many of us have lived through this exact issue, I can already warn you
> about loading data files.
> nested blocks, do not recursively get evaluated
> by load, so you can end up with this same problem when saving out blocks and
> objects and stuff.
>
Confusing. Nested blocks are processed by Load in exactly the same way
it processes the top-level block. The Load function does just what it is
supposed to. Example:
code: load "none [true false]"
produces a block containing one word and a nested block containing two
words. This means, that Load evaluates neither the nested nor the
top-level block.
> a good way to identify this is to use the mold/all function which
> *serializes* the data. in fact, I have replaced probe in my setup so that
> it molds/all in order to clearly identify datatypes.
This is my Probe version:
probe: func [
{Prints molded Value. Returns Value.}
value [any-type!]
] [
print case [
not value? 'value ["#[unset!]"]
error? :value [rejoin ["#[error!" mold/all copy skip second
disarm :value 2 "]"]]
true [mold/all :value]
]
return get/any 'value
]
example:
probe compose [none #[none] (none) false #[false] (false) true
#[true] (true)]
-L
[8/8] from: moliad::gmail::com at: 30-Jul-2007 15:00
On 7/30/07, Ladislav Mecir <lmecir-mbox.vol.cz> wrote:
> Maxim Olivier-Adlhoch napsal(a):
> > Hi Jonathan,
<<quoted lines omitted: 5>>
> Binding is slightly off-topic in this case, "static run-time" is a
> contradictio in adjecto.
hum... I didn't say static dynamic. the binding is static (its not a scope)
and is applied at run time, manually (as words are encountered during
execution of your application which is usually at load time), but can also
be while building objects, using bind, etc.
> some functions evaluate values and others do not. in this case,
> > compose loads a block and leaves everything within AS-IS.
> Wrong. The interpreter loads the block before evaluating the expression.
> Compose does not. (Do you want a proof?)
yes the interpreter itself does the loading. but the nuance was in the fact
that some functions need blocks which are bound and others dont care... I
should have been a bit more volubile I guess.. in this case compose does not
evaluate anything except parens.
> > so since the
> > interpreter has to put the none somewhere as something, it stays a word,
<<quoted lines omitted: 9>>
> Wrong. Here are the lexical forms of some Rebol values popularly thought
> not having lexical form:
not talking about serialized form. direct unserialized notation
an extension of what I was saying :-) , so we agree, if you want to be sure
the interpreter knows what none is.. use #[none] I use it often in my code.
for the recursive block loading, its a more complex example which will
illustrate what I meant, but I have no time right now :-( it might be
within a specific datatype (like object!), but at some point, one needs to
run 'DO on top of 'LOAD, whereas saving in serialised form alleviates this
dangerous step.
thanks for adding precision to my words ;-)
-MAx
Notes
- Quoted lines have been omitted from some messages.
View the message alone to see the lines that have been omitted