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

World: r3wp

[Core] Discuss core issues

BrianH
23-Feb-2010
[15860x2]
As for EMPTY? and TAIL?, a function has no way of knowing what it 
is called. That error message generated from within the TAIL? port! 
action guessed wrong.
Oh, it gets trickier (in theory - I've had to do a lot of scientific 
method on the internals, not decompiling). I think that DO does some 
of the function call work, and the function type itself does the 
rest through an internal action. DO handles the evaluation rules 
and builds the stack frame, then passes along that stack frame to 
the function dispatch action of the function type for it to redirect 
to the real code in a type-specific way.


Now it definitely works that way, the only question is whether the 
type-specific dispatch code is built into DO itself, accessed through 
the action dispatch mechanism, or action code called directly without 
going through the action dispatch mechanism. Only Carl or a decompiler 
could say for sure. But really, it doesn't matter because the behavior 
is the same in any case.
Steeve
23-Feb-2010
[15862]
Working with schemes, i saw another one thing really disturbing.
Seems that LAST and FIRST use PICK.

But LAST and FIRST are natives and PICK is an action. I always thought 
that ACTIONS may use NATIVES but not the reverse.
BrianH
23-Feb-2010
[15863x4]
Nope, at least not in R3. Natives can call actions, and even call 
function! functions too.
And apparently the type-checking of the left argument of an op! is 
done differently that the type checking of other arguments. Since 
this type checking is apparently done by DO, the type spec of the 
op! or action! function specs is apparently there for documentation, 
not actually used. Instead, DO checks whether the corresponding action 
is supported by the type and goes by that, rather than duplicating 
effort.
Mezzanine functions called by native functions are generally called 
"intrinsics", and there are several of them. DO, MAKE module! or 
port!, and the startup code call intrinsics.
This is how LOAD can be a mezzanine, btw, and still be called by 
DO. And it's how the module system can be mostly mezzanine too.
Steeve
23-Feb-2010
[15867x2]
yep, i begin to know them really well.
Btw, i think make-port should be corrected in some ways
when i construct ports with a spec block, i would rather prefer to 
use dialect (using delect) instead of passing a prototype of the 
spec object
BrianH
23-Feb-2010
[15869]
Yeah, I've cleaned up begin and make-module a bit, and rewritten 
DO completely many times, but make-port is still on my list.
Steeve
23-Feb-2010
[15870]
i.e.
open [ 10.45.12.12    2450]
instead of
open [scheme: 'tcp host: 10.45.12.12 port-id: 2450]
BrianH
23-Feb-2010
[15871]
It actually does use a dialect already, that just resembles an object 
spec.
Steeve
23-Feb-2010
[15872x2]
not really a dialect, just a bunch of case/if
using  DELECT would allow a more versatile syntax.
BrianH
23-Feb-2010
[15874x2]
MAKE-SCHEME is earlier on my list though.
I'm not doing anything with DELECT until after it's settled. A complete 
rewrite of DELECT with a new dialect model is scheduled for the next 
host kit release.
Steeve
23-Feb-2010
[15876x2]
i take the risk (using delect), I onl
I only hope the rewrite will just add more capabilities
Graham
23-Feb-2010
[15878]
Maybe we should also have a set! datatype ( need to use a different 
name though ) to indicate a unique unordered collection
BrianH
23-Feb-2010
[15879]
And that dialect you mention is ambiguous - you need the keywords.
Steeve
23-Feb-2010
[15880x2]
it was an just example. We can have default behaviour for several 
data-type, and use keywords only to  allow  disambiguation
a tuple is an IP by default,
an integer is a port-id by default.
etc...
BrianH
23-Feb-2010
[15882]
And a scheme is nothing by default.
Graham
23-Feb-2010
[15883]
userid and password and domains are ...the same
Steeve
23-Feb-2010
[15884]
a word is scheme by default :)
open [http 12.34.45.56 80]
BrianH
23-Feb-2010
[15885]
Graham, we have set functions that work with the block! type, we 
don't need a set! type. There is a budget for built-in types - we 
can only have a limited number of them. There has to be a major need 
that can't be handled easily enough otherwise for a new built-in 
datatype to be added. A set! type might merit a user-defined datatype, 
or a spoofed datatype like the ones I added to 2.7.7+, but it's not 
an extreme enough difference from the behavior of block! with set 
functions to merit a full datatype.
Graham
23-Feb-2010
[15886]
Seems a bit of overhead if you're trying to maintain a set if you 
have to check each time you add something if it already exists or 
not.
BrianH
23-Feb-2010
[15887]
Which is why I want an INCLUDE function, the opposite of EXCLUDE.
Steeve
23-Feb-2010
[15888]
bitsets are exactly what you need graham (only working with sets 
of integers or chars, though)
BrianH
23-Feb-2010
[15889]
Maps work well for that too, using #[true] as the value or #[none] 
for not there. Works great, works with FOREACH.
Steeve
23-Feb-2010
[15890]
but heavy :)
BrianH
23-Feb-2010
[15891x2]
For other types than integers or chars, it's really not that heavy. 
The space to store one extra value slot each is nothing incomparison 
to the overhead of bitsets for sparse data with poor locality.
Remember, bitsets include the zeros, maps don't necessarily include 
the nones.
Steeve
23-Feb-2010
[15893x2]
true, but bitsets have  lightning speed in comparison.
there is nothing faster
BrianH
23-Feb-2010
[15895x2]
Only for integers and chars. And can be hundreds of megabytes in 
RAM for some datasets.
It's best to pick one based on your data.
Steeve
23-Feb-2010
[15897]
sure
BrianH
23-Feb-2010
[15898]
On the other hand, if your data has good locality you can do a bitset 
minus a base value and it can still be small. Say if you are doing 
the numbers from 100000 to 100100 just subtract 100000 first.
Steeve
23-Feb-2010
[15899x2]
i think we can combine the 2 technics to gether map! + bitset!
map! as a primary index , and bitsets for linked indexes when data 
have good localities
BrianH
23-Feb-2010
[15901x2]
Yup. Not a bad project, and it should even be fast in mezzanine code. 
Maybe as a user-defined index type if you like, though a set of related 
functions would do.
Though sparse-bitset! would be a more accurate name due to the integer/char 
restriction for contents.
Steeve
23-Feb-2010
[15903x5]
i remember having an algo done with R2 to simulate hash! using bitsets 
and blocks
i should search for...
Found ...

f: fast-dic: context [
	size: 100000

 hash: 128 - 1	;** hash size speed up the search, must be a power 
 of 2 - 1 (ie. 15, 31, 63, 127, 257 ...)
	master: copy/deep head insert/dup/only [] [] hash + 1
	index: make bitset! size
	flag: func [idx [integer!]][
		unless find index idx [
			insert index idx

   insert/only insert tail pick master idx and hash + 1 idx copy []
		]
	]
	flag?: func [idx [integer!]][find index idx]
	deflag: func [idx [integer!]][
		remove/part index idx
		remove/part find pick master idx and hash + 1 idx 2
	]
]
.Hum...  it was not finished...
Obviously it was done to speed up the search
BrianH
23-Feb-2010
[15908x2]
A sparse index lookup with map!/bitset! in R3 would just be: find 
select index to-integer x / period x
You could wrap the structure in accessors that would do the work. 
It's doable.