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

World: r3wp

[Core] Discuss core issues

Gregg
27-Jan-2010
[15691x2]
forskip+: func [
        "Like FORSKIP, but with local FIRST? and LAST? support."
        [throw catch]

        'word [word!] {Word set to each position in series and changed as 
        a result}
        skip-num [integer!] "Number of values to skip each time"
        body [block!] "Block to evaluate each time"
        /local orig result
    ][

        if not positive? skip-num [throw make error! join [script invalid-arg] 
        skip-num]
        if not any [
            series? get word
            port? get word
        ] [

            throw make error! {forskip/forall expected word argument to refer 
            to a series or port!}
        ]
        orig: get word
        use [first? last?] [
            first?: true
            last?:  false
            body: bind/copy body 'first?

            while [any [not tail? get word (set word orig false)]] [
                if tail? skip get word skip-num [last?: true]
                set/any 'result do body
                set word skip get word skip-num
                first?: false
                get/any 'result
            ]
        ]
    ]
b: [a b c d e]

forskip+ b 1 [
    if first? [print 'first] 
    print b/1 
    if last? [print 'last]
]
BrianH
27-Jan-2010
[15693x2]
FIRST? seems like HEAD? with an assumed parameter, and LAST? seems 
like SINGLE? with an assumed parameter.
SINGLE? is in R3 and will be in 2.7.8.
Gregg
27-Jan-2010
[15695x2]
The idea is that it could apply to all the interator funcs, so you 
don't have different types of checks for FOR/LOOP/REPEAT, FORSKIP, 
or FOREACH.
And LAST? wouldn't be like SINGLE? in the context of FORSKIP with 
a bump value other than 1.
BrianH
27-Jan-2010
[15697]
Ah, good point. Too bad we can't write mezzanine loop functions in 
R3 yet :(
Graham
27-Jan-2010
[15698x2]
Can the R2/forward stuff be used with 2.7.6 or does it require 2.7.7 
?
I think you said you were aiming for 2.7.5
BrianH
27-Jan-2010
[15700x3]
I'm aiming at 2.5.0, but I've only hit 2.7.5 so far.
Much of the R2/Forward stuff has been incorporated into 2.7.7 already, 
and most of the rest (except maybe 3 functions) will be in 2.7.8.
It's a good thing the Power Mezz package is license compatible too, 
since some of those seem like good, non-disruptive adds.
Graham
27-Jan-2010
[15703x2]
Ok I'll see if I can use them inside the sdk...
I've been writing stuff using R3 functions ... and it seems a waste 
of my time to rewrite for R2
BrianH
27-Jan-2010
[15705x3]
That's why I wrote R2/Forward in the first place :)
The R2/Forward functions that are unlikely to be incorporated in 
R2 directly are APPEND, REMOLD and LIST-DIR; the first two because 
they demonstrate the problem with adding too many options to a function, 
and the latter because it isn't good enough yet, even in the R3 version.
Watch out for native functions that already existed in R2 and which 
were changed in R3: Those changes haven't been backported.
Graham
27-Jan-2010
[15708]
oh .... nothing straight forward
BrianH
27-Jan-2010
[15709x4]
There aren't many native changes in R3 except architectural: R3's 
main changes:

- Fixes the off-by-one error for PICK and POKE (and path indexes) 
of non-positive indexes

- Ordinal functions now return #[none] on out-of-bounds rather than 
throwing an error
- Expansion of capabilities of FOREACH, subjects of SELECT

- Datatype conversion changes, mostly minor except to/from binaries

- Removed "features" that were more trouble than they were worth, 
and have been replaced by new features (backported)

- Removed features that haven't been replaced yet (like [throw] function 
attributes)
- Major changes in the port and GUI models and PARSE
Note that the off-by-one error of AT with non-positive indexes probably 
won't be fixed.
CureCode dismissed tickets are a good place to start - most of those 
were requests for R2 compatibility where inappropriate.
I apologize - most of the CureCode dismissed tickets are requests 
by meijeru for consistency. Only some are compatibility requests.
Maxim
28-Jan-2010
[15713]
is there a listing of changed natives?  I rarely find that they make 
things better, if they change the api of a function.
BrianH
28-Jan-2010
[15714x2]
There hasn't yet been a final list, but someone (probably me) should 
go through CureCode and make a draft list in DocBase. And there's 
the change list for the releases too, though that is mostly CureCode 
references.
Almost all of the changes have been for the better, though some were 
mostly for greater consistency. Changing the API is OK if the old 
one was really bad, and if there is a rationale for having any change 
be OK. For instance, changes are much more restricted in new R2 releases 
since the continuing existence and development of R2 is the justification 
for allowing the more radical changes in R3.
Maxim
28-Jan-2010
[15716x2]
if it means I have to revise 5 MB of code, any change isn't welcome 
 ;-)
unless I have a  precise list of changes so I can quickly detect 
side-effects.
BrianH
28-Jan-2010
[15718]
In theory, the combined test suite and combined docs should tell 
you the differences. When I get the time I can compile a list of 
relevant CureCode tickets.
Maxim
28-Jan-2010
[15719x2]
We really need a simple list of changes compiled in a single file, 
I have no clue how and when the process of 2.7.7 occured, and really, 
I've got A LOT of other "cats to whip".


FYI, this not a negative comment, just stating that unless someone 
builds a (similar to prior versions) simple list of all changes, 
I won't be able to use 2.7.7... as previous versions have bitten 
me, I can't risk running code in an untrusted environment... I feel 
others with serious tools and services might feel the same..  a single 
little change change cause havoc like data destruction which is only 
apparent, once the process is done.
(same for 2.7.8) 


the point being that all the effort going into it ends up being wasted 
on the most serious users.
BrianH
28-Jan-2010
[15721]
There were no changes in 2.7.7 that would cause semantic blowups, 
unless your code would fail when any of the new words are defined. 
The same will be the case with 2.7.8 (except the LATIN1? and ASCII? 
functions will no longer work poorly). I was just waiting for Carl 
to get done with the web site changes so there would be a place to 
put the release notes - they're already in the blog comments.
Maxim
28-Jan-2010
[15722]
ok, perfect.
BrianH
28-Jan-2010
[15723]
The blog comments here: http://www.rebol.com/cgi-bin/blog.r?view=0447#comments
BrianH
30-Jan-2010
[15724x11]
Here's the source to the new 2.7.8 functions that were posted earlier 
today, for those who haven't seen it on chat. I'm posting one function 
per message so bear with me for a sec. Not posting them in !REBOL2 
because that is just for release discussion.
; Fake immediate! and internal! typesets, for documentation
immediate!: reduce [

 none! logic! integer! decimal! money! char! pair! tuple! time! date!
	datatype! word! set-word! get-word! lit-word! refinement! event!
] ; percent! typeset!
internal!: reduce [end! unset! symbol!] ; frame! handle!
resolve: func [

 "Copy context by setting values in the target from those in the source."
	[catch]
	target [object! port!]
	source [object! port!]

 /only from [block! integer!] "Only specific words (exports) or new 
 words in target (index to tail)"

 /all "Set all words, even those in the target that already have a 
 value"
][
	either only [
		from: either integer? from [

   ; Only set words in the target positioned at the number from or later
			unless positive? from [throw-error 'script 'out-of-range from]
			intersect words-of source at words-of target from
		] [

   ; Only set the words in the target that are also in the from block
			intersect words-of source intersect words-of target from
		]
		foreach word from pick [

   [unless value? in target word [error? set/any in target word get/any 
   word]]
			[error? set/any in target word get/any word]
		] not all ; See below for what this means
	] [

  either all [ ; Override all target words even if they have values
			error? set/any bind words-of source target get/any source
		] [ ; Only set target words if they aren't yet set
			foreach word intersect words-of source words-of target [

    unless value? in target word [error? set/any in target word get/any 
    word]
			]
		]
	]
	also target set [source target from] none
]
; Note: This is native in R3 and supports module! too.

; Implementation note: INTERSECT returns the values from its first 
argument,

; and WORDS-OF returns a block of words that are bound to its argument, 
so
;     intersect words-of source words-of target
; returns a block of words bound to source.
single?: funco [
	"Returns TRUE if the series length is 1."

 series  [series! port! tuple! bitset! struct!] ; map! object! gob! 
 any-word!
][1 = length? :series]

; Note: Type spec same as LENGTH?, which also supports the extra 
types in R3
collect-words: func [

 "Collect unique words used in a block (used for context construction)."
	block [block!]
	/deep "Include nested blocks"
	/set "Only include set-words"
	/ignore "Ignore prior words"
	words [object! port! block!] "Words to ignore"
	/local rule word blk w
][

 deep: either deep [[path! | set-path! | lit-path! | into rule]] [any-block!]
	word: either set [set-word!] [any-word!]
	blk: []
	parse block rule: [
		set w word (insert tail blk to-word to-string w) | deep | skip
	]
	also either ignore [
		unless block? words [words: words-of words]
		difference blk intersect blk words
	] [
		unique blk
	] (clear blk set [block words] none)
]
; Note: In R3 this is native, called by MAKE OBJECT!

;   The words are not supposed to be bound, thus the to-word to-string.
ascii?: funct [

 "Returns TRUE if value or string is in ASCII character range (below 
 128)."
	value [string! file! email! url! tag! issue! char! integer!]
] compose [
	ascii: (charset [#"^(00)" - #"^(7F)"])

 either any-string? value [parse/all/case value [any ascii]] [value 
 < 128]
]
; Note: Native in R3.
latin1?: func [

 "Returns TRUE if value or string is in Latin-1 character range (below 
 256)."

 value [string! file! email! url! tag! issue! char! integer!] ; Not 
 binary!
][ ; R2 has Latin-1 chars and strings
	either integer? value [value < 256] [true]
]

; Note: Native (and more meaningful) in R3. For forwards compatibility.
invalid-utf?: funct [

 "Checks for proper UTF encoding and returns NONE if correct or position 
 where the error occurred."
	data [binary!]
	/utf "Check encodings other than UTF-8"
	num [integer!] "Bit size - positive for BE negative for LE"
] compose [
	ascii: (charset [#"^(00)" - #"^(7F)"])
	utf8+1: (charset [#"^(C2)" - #"^(DF)"])
	utf8+2: (charset [#"^(E0)" - #"^(EF)"])
	utf8+3: (charset [#"^(F0)" - #"^(F4)"])
	utf8rest: (charset [#"^(80)" - #"^(BF)"])
	switch/default any [num 8] [
		8 [ ; UTF-8
			unless parse/all/case data [(pos: none) any [
				pos: ascii | utf8+1 utf8rest |
				utf8+2 2 utf8rest | utf8+3 3 utf8rest
			]] [as-binary pos]
		]
		16 [ ; UTF-16BE
			pos: data
			while [not tail? pos] [
				hi: first pos
				case [
					none? lo: pick pos 2 [break/return pos]
					55296 > w: hi * 256 + lo [pos: skip pos 2]  ; #{D800}
					57343 < w [pos: skip pos 2]  ; #{DFFF}
					56319 < w [break/return pos]  ; #{DBFF}
					none? hi: pick pos 3 [break/return pos]
					none? lo: pick pos 4 [break/return pos]
					56320 > w: hi * 256 + lo [break/return pos]  ; #{DC00}
					57343 >= w [pos: skip pos 4]  ; #{DFFF}
				]
				none
			] ; none = valid, break/return pos = invalid
		]
		-16 [ ; UTF-16LE
			pos: data
			while [not tail? pos] [
				lo: first pos
				case [
					none? hi: pick pos 2 [break/return pos]
					55296 > w: hi * 256 + lo [pos: skip pos 2]  ; #{D800}
					57343 < w [pos: skip pos 2]  ; #{DFFF}
					56319 < w [break/return pos]  ; #{DBFF}
					none? lo: pick pos 3 [break/return pos]
					none? hi: pick pos 4 [break/return pos]
					56320 > w: hi * 256 + lo [break/return pos]  ; #{DC00}
					57343 >= w [pos: skip pos 4]  ; #{DFFF}
				]
				none
			] ; none = valid, break/return pos = invalid
		]
		32 [ ; UTF-32BE
			pos: data
			while [not tail? pos] [
				if any [
					4 > length? pos
					negative? c: to-integer pos
					1114111 < c  ; to-integer #{10FFFF}
				] [break/return pos]
			]
		]
		-32 [ ; UTF-32LE
			pos: data
			while [not tail? pos] [
				if any [
					4 > length? pos

     negative? c: also to-integer reverse/part pos 4 reverse/part pos 
     4
					1114111 < c  ; to-integer #{10FFFF}
				] [break/return pos]
			]
		]
	] [
		throw-error 'script 'invalid-arg num
	]
]

; Note: Native in R3, which doesn't support or screen the /utf option 
yet.

; See http://en.wikipedia.org/wiki/Unicodefor charset/value explanations.
; Aliases copied from R3 mezz-file
ls: :list-dir
pwd: :what-dir
rm: :delete
mkdir: :make-dir

cd: func [
	"Change directory (shell shortcut function)."
	[catch]

 'path [file! word! path! unset! string! paren!] "Accepts %file, :variables 
 and just words (as dirs)"
][

 ; Workaround for R3 change in lit-word! parameters with paren! arguments
	if paren? get/any 'path [set/any 'path do path] 
	switch/default type?/word get/any 'path [
		unset! [print what-dir]
		file! [change-dir path]
		string! [change-dir to-rebol-file path]
		word! path! [change-dir to-file path]

 ] [throw-error 'script 'expect-arg reduce ['cd 'path type? get/any 
 'path]]
]

more: func [
	"Print file (shell shortcut function)."
	[catch]

 'file [file! word! path! string! paren!] "Accepts %file, :variables 
 and just words (as file names)"
][

 ; Workaround for R3 change in lit-word! parameters with paren! arguments
	if paren? :file [set/any 'file do :file] 
	print read switch/default type?/word get/any 'file [
		file! [file]
		string! [to-rebol-file file]
		word! path! [to-file file]

 ] [throw-error 'script 'expect-arg reduce ['more 'file type? get/any 
 'file]]
]
So there we are, by request. Any comments?
Any FUNCO references were left over from R2/Forward, from which this 
source was copied. It was changed to FUNC in R2.
Henrik
31-Jan-2010
[15735x2]
LS won't work the same on R2 as in R3, AFAIR?
sorry, that woulc be CD and it seems it might work.
Graham
31-Jan-2010
[15737]
would be nice if we can the sdk to 2.7.7 ...
Will
31-Jan-2010
[15738x2]
what about a mv function where the target isn't relative to the origin? 
would be nice
if it's of use and Dock agree, this function has just been added 
to latest cheyenne svn:
relative-path: func [src dst /local i][
		src: remove parse src "/"
		dst: remove parse get-modes dst 'full-path "/"
		if src/1 <> dst/1 [return none]					;-- requires same root

		i: 1 + length? src 
		repeat c i - 1 [if src/:c <> dst/:c [i: c break]]	
		dst: to-file at dst i
		src: at src i
		if not tail? src [loop length? src [insert dst %../]]
		dst
	]
Henrik
31-Jan-2010
[15740]
I think we already have something like this. It's called TO-RELATIVE-FILE.