• Home
  • Script library
  • AltME Archive
  • Mailing list
  • Articles Index
  • Site search
 

World: r4wp

[#Red] Red language group

DocKimbel
11-Apr-2013
[6971x2]
If the AV software from virustotal doesn't give you the same error, 
you might have an older AV version.
You can post here the link to the virustotal report.
Endo
11-Apr-2013
[6973x3]
Oh sorry, when I say AV I meant AVira :) Avira Free Antivirus: http://www.avira.com/free-av
Ok I've uploaded to virustotal.com, Detection ratio:	 1 / 46, only 
avira-antivir says "TR/Crypt.XPACK.Gen" virus found.
Here is the link:

https://www.virustotal.com/en/file/2db471babe53dedbd6adf0c5c112976a6692ad000aea83dfa93890f6d1e1b43b/analysis/1365683598/
DocKimbel
11-Apr-2013
[6976]
So you just compiled tests/hello.red or did you use a custom script?
Endo
11-Apr-2013
[6977]
my script is:
Red [ ]
print "hello"
DocKimbel
11-Apr-2013
[6978]
Ok, thanks, will try to reproduce the false alarm and will contact 
AVira for reporting it.
Gregg
12-Apr-2013
[6979x2]
Since it's early days in Red, I'm toying with a lot of ideas and 
revisiting old REBOL funcs as I port them. JS has an interesting 
spin on MAP. I thought I'd see how hard it would be to do in Red.
; JS-like MAP. The order of args to the function is a bit odd, but 
is set

; up that way because we always want at least the value (if your 
func takes

; only one arg), the next most useful arg is the index, as you may 
display

; progress, and the series is there to give you complete control 
and match

; how JS does it. Now, should the series value be passed as the head 
of the
; series, or the current index, using AT?
map-js: func [

 "Evaluates a function for each value(s) in a series and returns the 
 results."
	series [series!]

 fn [function!] "Function to perform on each value; called with value, 
 index, and series args"
	/only "Insert block types as single values"
	/skip "Treat the series as fixed size records"
		size [integer!]
][
	collect [

  repeat i length? series [   ; use FORSKIP if we want to support /SKIP.
			keep/only fn series/:i :i :series ; :size ?
		]
	]
]
;res: map-js [1 2 3 a b c #d #e #f] :form
;res: map-js [1 2 3 a b c #d #e #f] func [v i] [reduce [i v]]
;res: map-js [1 2 3 a b c #d #e #f] func [v i s] [reduce [i v s]]
;res: map-js "Hello World!" func [v i s] [pick s i]
DocKimbel
12-Apr-2013
[6981x2]
Nice and short implementation! :)
An important note about such code: passing a function! as argument 
is not supported by the compiler yet, so this function could only 
work in the interpreter currently (from console or from a DO block).
Gregg
12-Apr-2013
[6983]
Good to know. Thanks. I'm trying to stay just a few steps behind 
you in what I try. :-)
DocKimbel
13-Apr-2013
[6984x17]
For Red/System fans, here's some new toy: exceptions! Here's a simple 
example for starting:
foo: func [[catch]][
	print "2"
	throw 10
	print "KO"
]

print "1"
foo
print "3"
print ["^/thrown value: " system/thrown lf]
will output:

123
thrown value: 10
A deeper nested example:

foo2: does [
	print "3"
	throw 100
	print "KO"
]

bar: func [[catch]][
	print "2"
	foo2
	print "KO"
]

print "1"
bar
print ["^/thrown value: " system/thrown lf]
will output:

123
thrown value: 100
The implementation is done and I will push it in a few minutes. It 
required about 25 additional LOC to implement all such simple exception 
system (right, 25!). ;-)
So, how does it work? When you need to interrupt the flow of code 
in a function in Red/System, currently you can just use EXIT/RETURN 
to make an early exit. But, sometimes, you need to go up through 
several nested calls, that's where the new THROW function comes handy. 
It will interrupt the execution and go up the call tree to find the 
first function that has the CATCH attribut set. It will then just 
resume execution after the last function call (from which the exception 
has been generated).


If no CATCH attribut is found, it will go up to global code and resume 
from there.
THROW requires an integer! value. Such value represent the exception 
ID and is user-defined. After the resume from a caught exception, 
you can use SYSTEM/THROWN to read the passed exception ID and act 
accordingly (usually using a SWITCH dispatcher).
Important thing to note: system/thrown needs to be manually reset, 
as the last thrown value will stay there if no exception occured. 
Such reset could be done before each call to a function that could 
generate an exception or after processing the thrown value.
I could have added a much more sophisticated system with a true CATCH 
function, but this would have made the implementation way more complex 
and would have taken a lot more time. As I need it only for Red's 
interpreter, I think this way should be enough and will be usable 
by other Red/System programmers to enhance their own code.
Thinking about it, it might be possible to allow an extended catch 
attribut with a integer value to specify the barrier value for catching 
exceptions (and avoid manual re-throwning), something like:

foo: func [[catch 100]][...]


would catch all thrown exceptions with a value <= 100 and let others 
pass up to caller.
What do you think about all this?
BTW, this exception system relies on stack frames unwinding, so it 
won't work for callbacks (CATCH attribut won't be accepted in callback 
functions anyway).
I've considered using a continuation approach for constant-time exception 
throwing (would also work from callbacks), but I didn't find a simple 
enough syntax for defining/using it without having to rely on CPS 
(Continuation-Passing Style) for every functions...

See http://en.wikipedia.org/wiki/Continuation-passing_style
Another note: messing up with the stack (using push/pop) in a user-function 
is fine as long as you returned the stack clean before calling a 
function that could generate an exception. Failure to do so will 
result in a crash. It might be possible to make stack-unwinding for 
exception resistant to such cases, I will investigate that.
Exception handling code pushed. Have fun! ;)
(only IA-32 for now, will add ARM support in the next days)
Gregg
13-Apr-2013
[7001x2]
That sounds great Doc. I collected your comments into a file in %Red/.
Hmm, shouldn't bar print KO in the second example, from your description?
DocKimbel
13-Apr-2013
[7003]
Nope, see first example. This might be a bit non/counter-intuitive, 
I will see if I can improve that.
Gregg
13-Apr-2013
[7004]
Ah, I get it now. Yes, that wasn't obvious at first.
DocKimbel
13-Apr-2013
[7005]
I won't be online tomorrow most of the day, will look into that and 
will upgrade the documentation tomorrow night.
Gregg
13-Apr-2013
[7006x2]
So you don't check system/thrown in the func with [catch], correct?
But in the func that *called* the func with [catch].
DocKimbel
13-Apr-2013
[7008x2]
Right.
I might adjust that tomorrow if possible to make it more intuitive.
PeterWood
13-Apr-2013
[7010]
Absolutely fabulous Nenad!!!
Arnold
14-Apr-2013
[7011]
Good progress. Nice of you to sum it up Gregg, makes the comments 
a whole lot more readable. Filename is a bit awkward though: "esceptions"
Gregg
14-Apr-2013
[7012x2]
Fixed. Thanks Arnold.
I had a Spanish accent last night.
DocKimbel
15-Apr-2013
[7014]
Gregg, I've reconsidered the behavior of the [catch] function attribut, 
if I change it, some use cases become even less intuitive. For example, 
the single function use case (my first example above) performs quite 
intuitively. I think the  vague non-intuitive feeling at the beginning 
comes from our habits with CATCH native in Rebol, after using Red/System's 
way a bit, that feeling just faded away. Anyway, if you have suggestions 
for improvements, it's the right time.
Kaj
15-Apr-2013
[7015]
Doc, any idea how I can convert a string! passed into a routine! 
to UTF-8, or access a cached UTF-8 value?
PeterWood
15-Apr-2013
[7016]
Kaj, can you use string/mold inside the routine to create a c-string! 
?
PeterWood
16-Apr-2013
[7017]
The answer is not you can't as mold doesnt output a UTF-8 string.
DocKimbel
16-Apr-2013
[7018x3]
Kaj: cached UTF-8 string is available using str/cache if str is a 
red-string! value.
Only small strings (< 64 bytes) are cached.
We haven't yet implemented UTF-8 encoding functions in the standard 
library. It will be done during the I/O implementation (unless you 
have a strong need for it, then I'll have a look at it).