find
. I just showed how to do it with parse
to get the actual position of the first invalid char.load-utf8-buffer
.l: layout [ p1: panel "p1" 220.220.220 [ p2: panel "p2" 180.180.180 p3: panel "p3" 180.180.180 ] on-create [help p1/pane/1/text help p1/parent] ] view l
p1/pane/1/text is a string! of value: "p2"
p1/parent is a none! of value: none
parent
property is only set when the faces are shown on screen, on-create
is called just before that.l: layout [title "Why no parent at 'on-create' time" p1: panel "p1" 220.220.220 [ p2: panel "p2" 180.180.180 p3: panel "p3" 180.180.180 ] on-create [help p1/pane/1/text help p1/parent] do [ self/actors: make object! [ on-resize: function [face [object!] event [event!]][ print ["In on-resize: help p1"] either p1/parent [ help p1/parent/text ][ print ["p1/parent is none"] ] ] ] ] ] view/flags l [resize]
In on-resize: help p1
p1/parent is none
p1/pane/1/text is a string! of value: "p2"
p1/parent is a none! of value: none
In on-resize: help p1
p1/parent/text is a string! of value: "Why no parent at 'on-create' time"
on-create
is really meant to be called before the system GUI resources are allocated, and parents setting needs to happen after that. What is really missing is a on-appear
handler which would be called just after the face is fully created and displayed for the first time.base
face and building a splitter style on that?reset: function [][ if zero? first ref: [0][ref/1: length? words-of system/words] foreach w at words-of system/words ref/1 [unset w] system/view/debug?: system/reactivity/debug?: off clear-reactions system/view/auto-sync?: on ]
word-1: "Troia" word-2: "Grecia" max-distance: 5 sep: charset " ,." parse s [ any [ to word-1 mark-1: word-1 sep ;(print index? mark-1) [copy text to word-2 word-2 mark-2: ( ;(print [tab index? mark-2]) n: 0 parse text [space (n: n + 1) | skip] if n < max-distance [ print ["Close words found at offset" index? mark-1 mold copy/part mark-1 mark-2] ] ) | to end] ] ]
word-1: "giornata" word-2: "sole" max-distance: 5 sep: charset " ,." ; this is the text where to find if it contain "giornata" close to "sole" s: { Oggi è una bella giornata di gran sole, e me la spasso fuori! } parse s [ any [ to word-1 mark-1: word-1 sep ;(print index? mark-1) [copy text to word-2 word-2 mark-2: ( ;(print [tab index? mark-2]) n: 0 parse text [space (n: n + 1) | skip] if n < max-distance [ print ["Close words found at offset" index? mark-1 mold copy/part mark-1 mark-2] ] ) | to end] ] ]
n: n + 1 print n
, you can see, it will never get there. It will fail sooner ...sep: charset " ,.^/"
... and continue playing ....;i dont' want only 2 words, but how many words i want to find ;word-1: "giornata" ;word-2: "sole" words-to-find: ["today" "beautiful" "hot"] ; a series of near each other words to find max-distance: 8 sep: charset " !,.^/" ; this is the text where to find into ; in this text the matches should be: ; today is a great beautiful day, with hot ; today, what beautiful hot s: { Really ... today, i can say that today is a great beautiful day, with hot weather, and i go out to do something. Very hot, yes. Hot, this today. I like a beautiful day, as today. Really ... today, what beautiful hot day! out to do something. Very hot, yes. Hot, this today. I like a beautiful day, as today. } parse s [ any [ to word-1 mark-1: word-1 sep ;(print index? mark-1) [copy text to word-2 word-2 mark-2: ( ;(print [tab index? mark-2]) n: 0 parse text [space (n: n + 1) | skip] if n < max-distance [ print ["Close words found at offset" index? mark-1 mold copy/part mark-1 mark-2] ] ) | to end] ] ]
parse
will make sense to you soon.code
trim/all form ["A" "B" "C" "D"] code
is this a good method, is there a better way? Not sure if I did the code tag correctly... hope so!!!joinand
rejoinso they are yet to be implemented.
>> source join join: func [ "Concatenates values." value "Base value" rest "Value or block of values" ][ value: either series? :value [copy value] [form :value] repend value :rest ]
rejoin
now, though the implementation is probably subject to change.ajoin
is good function, but rejoin
can do much more:>> ajoin [%a %b] == "ab" >> rejoin [%a %b] == %ab
FORM
and usually don't need the REJOIN
s behaviour, so I use ajoin
mostly.ajoin
just an alias for compatibility.append "" ["A" "B" "C" "D"]
rejoin: func [ "Reduces and joins a block of values." block [block!] "Values to reduce and join" ][ if empty? block: reduce block [return block] append either series? first block [copy first block] [ form first block ] next block ]
copy
.append copy
. ajoin
. My other issue is that we have a number of different functions that are similar but not identical, and all very closely named. And there is nothing in the name ajoin
to tell you what's different about its behavior. round
, split
, and my for
proposal. I have separate funcs I combine to do things. For example, I have a delimit
func that works on any series type, so I can do that, then rejoin
, but I also have specialized dlm str funcs for things like building CGI or other dict-style strings with field and rec separators.object
now, which I like. What if we had string
(string these things together), which also implies the return type? One concern is confusion by overloading the word string too much. More thought required.FORM
, put extra space between values or not, using a delimiter, forming none
to empty string etc.FORM
is making it less useful, and we all write our own string functions similar to each other's.Rejoin
will be in 0.6.2, and the automated builds should have it. And, yes, the "re" in the name is for "reduce". Rebol also has remold
and reform
. The tough design work is finding better names. The old names are important for porting from Rebol.make-range: function [a [integer!] b [integer!]][ collect [i: a - 1 until [keep i: i + 1 i = b]] ] ->: make op! :make-range 2 -> 7 == [2 3 4 5 6 7]
->
for naming the infix function.excel [ start show ] foreach file files [ if %.xls = suffix? file [ excel compose [ open (join path file) goto worksheet 1 goto cell "A1" set value to "Company Name" goto worksheet 4 goto cell "A1" set value to "Destination" goto cell "B2" set value to "=A1" close workbook ] ] ] excel [quit]
alerts [on off], cut/copy/paste, cut/copy to , insert new books or sheets, paste [value formula format comment], remove sheets, save/save-as, select/set [cell row col range] |
Munge
is well-loved, and well-supported. Ashley always does outstanding work. It it strictly for manipulating tabular data. That means you have to do the work of getting it in and out of Excel, but also makes it much more general, which is great.parse
. ;^)do
down, is our paradigm.process: function [ input [string! none!] ][ if attempt [blk: compose [(load input)]][ res: parse blk [ collect [ any [ set w word! set s string! keep (rejoin ["<" w ">" s "</" w ">"]) | 'aref keep ({<a href="#"</a>}) ] ] ] either res [form res][input] ] ] view [ below text yellow 300 bold {Try "h1{foo}" or "aref"} text "Input:" input: area 300x60 text "Output:" output: area 300x180 react [face/text: process input/text] ]
for
implementation, which would be really powerful. Forgot the link to the proposal, maybe Gregg will step-in.for
proposal is here: https://github.com/red/red/wiki/REP-FOR-loop-functionfor
will be included in some form. Doesn't have to be mine. People will expect it, and it does provide features loop
and repeat
don't. You can do anything with while
, but that's not always as clear IMO. I didn't use for
often under R2, but when I needed it, I was glad to have it.for a 2 10 2 [ print a ]
init, test, step
pieces and making them explicit.a: 0 loop 5 [a: a + 2 print a]
while
.red>> time-it [a: 0 while [a < 1000][a: a + 1]] == 0:00:00.001 red>> time-it [a: 0 while [a < 10000][a: a + 1]] == 0:00:00.01 red>> time-it [a: 0 while [a < 100000][a: a + 1]] == 0:00:00.051 red>> time-it [a: 0 while [a < 1000000][a: a + 1]] == 0:00:00.488
time-it
? :-)time-it: func [block /count ct /local t baseline][ ct: any [ct 1] t: now/time/precise loop ct [do []] baseline: now/time/precise - t t: now/time/precise loop ct [do block] now/time/precise - t - baseline ]
red>> s: "ABC123" == "ABC123" red>> to binary! s == #{414243313233} red>> to string! to binary! s == "ABC123"
execution-time: func[ blok /local start_ end_ ][ start_: now/time/precise do blok end_: now/time/precise end_ - start_ ] ; fast print execution-time[a: 2 loop 10000000 [a: a + 2]] ; slow ? (looks if it is faster than above) print execution-time[a: 2 while [a <= 10000000][a: :a + 2]]
timer: func [ code [block!] "Block of code to execute" /local t r ][ t: now/time/precise set/any 'r do code t: now/time/precise - t print [ t ">>" copy/part t: trim/lines mold code 80 if 80 < length? t [".."][""] ] unless unset? :r [r] ]
series
section yet. That's my biggest group.use
in Red yet.use
, but we do have map!
, and difference
doesn't work on time!
. Consider it a draft.time-marks: object [ data: #() _key: func [key][(any [key #__DEFAULT])] _get: func [key][data/(_key key)] _set: func [key][data/(_key key): now/time/precise] _clr: func [key][data/(_key key): none] set 'get-time-mark func [/key k] [_get k] set 'set-time-mark func [/key k] [_set k] set 'clear-time-mark func [/key k] [_clr k] set 'time-since-mark func [/key k] [ if none? _get k [ print ["##ERROR time-since-mark called for unknown key:" _key k] return none ] now/time/precise - _get k ] ] ;print time-since-mark ;set-time-mark ;print time-since-mark ;wait 1 ;set-time-mark/key 'a ;wait 2 ;print [time-since-mark time-since-mark/key 'a]
`xarr: [ 5 7 8 1 8 7 5] del_at_index: function [ mylist [series!] i [integer!]] [ x: take at mylist i return mylist ] del_at_index xarr 4
remove at xarr 4
repeat
instead of for
or while
(of course there are times I need to use while
as there is a nuance) repeat i 5 [print i i: i + 2]
i: 1 loop 5 [print i i: i + 2]
do-down: func [face [face!] event [event!]][ print ["down at" face/type event/offset] ] do-up: func [face [face!] event [event!]][ print ["up at" face/type event/offset] ] view [ panel 100x100 blue on-down [do-down face event] on-up [do-up face event] area 100x100 on-down [do-down face event] on-up [do-up face event] do [ self/actors: make object! [ on-down: func [face [face!] event [event!]] [do-down face event] on-up: func [face [face!] event [event!]] [do-up face event] ] ] ]
down at panel 49x34 down at window 49x34 up at area 37x32 up at window 37x32
do-down: func [face [face!] event [event!]][ print ["down at" face/type event/offset] 'done ]
do-down: func [face [face!] event [event!]][ print ["down at" face/type event/offset] ; <- face and event/face not always the same print ["down at" event/face/type event/offset] ]
red --cli
to get the output redirected to the shell. By default, Red is using its own GUI console, not the system shell. --cli
forces it to use the system shell.red.exe
. See a workaround there: https://github.com/red/red/issues/543 Once we'll rewrite the toolchain in Red (after 1.0), this issue will be gone, as well as the Rebol dependency.pick series index length
if there's something built-in I'm totally missing it. Worst case was going to create a function that just did a repeating "pick" of index+1 and return a new series as the sub set 'b4 22 probe b4 ; == 22
repeat i 3 [set reduce[rejoin['b i]] i] ; thought this might work print [b1 b2 b3] ; *** Script Error: invalid argument: "b1"
to word! rejoin ['b i]
repeat i 3 [to word! rejoin ['b i] i] print [b1 b2 b3] ;*** Script Error: b1 has no value
--cli
"input
function won't return, then the print msg
will not run.multiply_big "4520345347346508738273465" "2304634563457837852066527845"
digit: charset "0123456789" load-bigints: function [s [string!]][ parse s [any [p: 10 500 digit e: insert e {"} insert p {"} | skip]] s ] multiply_big: func [a [string!] b [string!]][rejoin [a b]] my-console: function [/local res][ forever [ code: ask "custom>> " if code = "q" [exit] set/any 'res try/all [do load/all load-bigints code] case [ error? :res [print form :res] not unset? :res [print ["==" :res]] ] ] ] my-console
lisp red>> my-console custom>> custom>> multiply_big 123456789123456789 789456789456789456789456 == 123456789123456789789456789456789456789456
load/all
the user input, I call load-bigints
which will wrap big ints into double quotes, so they can be processed as strings. ;-)input
function expect UTF-8 encoded string../websocketd --port=8080 --devconsole ./red echo.r
print: make native! [[
"Outputs a value followed by a newline"
value [any-type!]
]
#get-definition NAT_PRINT
]
flush-file
/ fflush
from so going to experiment. Also need a way to constrain the stream to STDOUT, and not null/all.
`Red [] digit: charset "0123456789" longnum: [8 100 digit] myfunc: ["long_join" | "long_rev_join" | "long_flip_join"] load-bigints: function [s [string!]][ parse s [myfunc space insert {"} longnum insert {"} space insert {"} longnum insert {"}] s ] long_join: function [s1 [string!] s2 [string!]] [ trim/all form reduce [s1 s2] ] long_rev_join: function [s1 [string!] s2 [string!]] [ trim/all form reduce [( reverse s1) (reverse s2)] ] long_flip_join: function [s1 [string!] s2 [string!]] [ trim/all form reduce [s2 s1] ] calculator: function [/local res][ forever [ code: ask "calculator>> " if code = "q" [exit] if code <> "" [ set/any 'res try/all [do load/all (load-bigints code)] case [ error? :res [print form :res] not unset? :res [print ["==" :res]] ] ] ] ] calculator
key-event: func [face event] [ if event/type = 'key [ if event/key = #"^M" [unview] ] event ] insert-event-func :key-event view [ text "Click ok or press enter" button "ok" [unview] ] remove-event-func :key-event print "After ok clicked or enter pressed"
on-key
is a face-local event, it will only work when the face has focus.;; FYI, maybe this is a bug or, cos <> cosine ?? red>> cosine 90 == 0.0 red>> cos 90 *** Script Error: cos does not allow integer! for its angle argument *** Where: cos red>> cos 90.0 == -0.44807361612917 red>>
cos
takes radians, cosine
takes degrees (by default).reverse
modifies the series, so you may want to copy.reverse
?f1/text
to f2/text
, the **owner** of the string text
changed from f1
to f2
. When you reverse the text
later, the ownership system will notify f2
instead f1
, so no update in f1./text
and be able to auto-update, the current ownership system allows only one owner per series. There's a ticket about that already (posted by Rebolek). We'll see in next releases how to improve that.rule: [any ["every"|"any"|"an"|"a" skip "is" "a|an" skip] to end] print parse "every man is a human" rule ; must give true print parse "every man ist a human" rule ; must give false, because of "ist" (but the result is true) ; The rule must be wrong because i get 2 times true
rule: [any [[every|any|an|a] skip [is] [a|an] skip] end] print parse-trace [every man is a human] rule ; must give true print parse-trace [every man ist a human] rule ; must give false because of "ist"
rule: [ ["every" | "any" | "an" | "a"] skip "is" ["a" | "an"] skip ] print parse-trace split "every man is a human" " " rule print parse-trace split "every man ist a human" " " rule
|
is a word, not a delimiter:red>> first [every|any|an|a] == every|any|an|a red>> type? first [every|any|an|a] == word!
|
indicates that an alternative rule is following. Red dialects are using Red syntax, so a word remains a word in all possible dialects.to "is"
.split
and not by Parse. All the rest of Parse in Rebol2 should work the same in Red.dehex rejoin ["%" (to string! 41)]
I'm sure there's a better way but being a noob myself this is what I thought of. YAY rejoin !make-chr: function [x [integer!]] [ dehex rejoin ["%" (to string! 41)] ;; dehex append "%" (to string! 41) ;; would work too ] make-chr 41
#"^(41)"
doesn't work for you? Works for me in latest red;;Correction to previous post make-chr: function [x [integer!]] [ dehex rejoin ["%" (to string! x)] ;; dehex append "%" (to string! x) ;; would work too ] make-chr 49 == "I"
form
the result.make char!
for converting an integer! to char! (until we get proper to
support):red>> make char! 41 == #")"
char!value is a Unicode Code Point so has a value in the range 0 - 10FFFFFh.
""
, this is a datatype: string!
:red>> type? string! == datatype! red>> type? "A" == string!
append
to it.curl -u username:token https://api.github.com/user
. How can I specify https header infos for read
?write
:response: write/info url [GET [header1: value1 header2: value2 ...]]
res: write/info https://api.github.com [ GET ]crashes the red console
res: write/info https://api.github.com [ GET [ ] ]produces a response. I'm halfway there, hopefully ;)
user: "your username" token: "your private access token" authinfo: rejoin [ "Basic " enbase rejoin [ user ":" token ]] res: write/info https://api.github.com/user [ GET [ Authorization: authinfo ] ]
res: write/info https://api.github.com/user compose/deep [ GET [ Authorization: (authinfo) ] ]
random/seed form now/time
in the beginning of your script.seed
always generates same numbers in same order. now/precise
will be more useful but it is not yet implemented.form
ing the seed value.random/seed now/time loop 10 [print random 100]
form
it doesn't raise an error but doesn't change the seed value hence generates same numbers.random/secure
is not supported yet. For sources of randomness, you can google about that. Current time is the most used one, others can be: capturing random mouse movements or keys pressed, reading /dev/random on Unix machines for higher-quality randomness (relying on various hardware sources), querying a true random generator online, etc...random/secure
*is not* implemented yet.area
widget.all
, I don't get what you are trying to do.do
by #include
in order for the compiler to be able to process it. You can use a either system/state/interpreted? [do %... ][ #include ... ]
pattern to make it work for both the compiler and interpreter. The work for having a simpler [solution](https://github.com/red/red/issues/1601) is not yet finished.view [area bold "boldtext"] ; this works view [area wrap "this is a very long text which does not fit into the area of this widget bla.. bla... bla..."] ; seems to do nothing
face/rate: none
will stop the timer. For the radio button, are you asking how to do it from VID or from regular Red code?*** Access Error: invalid UTF-8 encoding: #{D7323020} *** Where: read
*** Syntax Error: invalid integer! at "1. * m * m" *** Where: do
decimal!
type annotation needed to become float!
. I also thought that perhaps Red was confused by mixing integer!
and float!
, so I appended a decimal to all the integer!
literals in the function. But none of my efforts seem to address the error.red>> do load %prime-factors.r
m
to float!
. So in Rebol it was 1.
--is that not the case in Red? It needs to be 1.0
?<script language="RED"> [ Red [] print now/time ] </script>
do %test.txt == </script>
<script language="RED"> Red [] print now/time </script>
red>> do %file.txt 11:54:28 == </script>
<!DOCTYPE html> <html lang="en"><head> <script language="RED"> Red [] print now/time </script> <html>
Here is some text before the script. [ REBOL [ Title: "Embedded Example" Date: 8-Nov-1997 ] print "done" ] Here is some text after the script.
PS C:\Users\peter\Red> ./red-061.exe -c -t Windows e:\Red\red\environment\console\gui-console.red
.using_dot_convention
(but mostly configs and volatile files in this case)program files
, just like the compiled languages secure
in Rebol? It's one of the ways to do sandboxing theresecure
? It is more relevant to executing arbitrary rebol code. AFAIK compiling to js hasn't been done yet.. but I've read about experimental emscripten builds..parse
which if used properly..secure
is a native in rebol fyilowercase
or uppercase
) is missing its string argument. Is there a new way to accomplish this in Red?do random/only [ lowercase uppercase ] word
red>> word: "AbcD" == "AbcD" red>> do reduce [random/only [ lowercase uppercase ] word] == "ABCD" red>> do reduce [random/only [ lowercase uppercase ] word] == "abcd"
?
, source
and reflect
word
in red) is clickable like a hyper link to get to the sourceboard: #( size: 9x9 cells: [1x1 [a] 2x1 [b] 1x2 [c] 2x2 [d]] ; ... )
foreach pos copy/part random extract board/cells 2 to integer! board/size/x * board/size/y * 10% [ ; place mine ]
num-cells: board/size/x * board/size/y mine-count: to integer! num-cells * 10% cell-positions: extract board/cells 2 random-mine-cells: copy/part random cell-positions mine-count foreach pos random-mine-cells [ ; place mine ]
help
. Play and have fun experimenting.function!|action!
crashes" ?do
on the file if you're running in the interpreter.parse
, got my data extracted. Cheersload
i.e.load/as {{ "e" : "e" }} 'json
load
, it isn't implemented yet. There are options to deploy in rebol, [like this guy got to recently](https://gitter.im/red/red/welcome?at=57bc19fcb64a3a016f5c1fcf) but if you were able to do it in red, much better..block: copy [] files: read %./ foreach file files [ append block 'image append block 100x100 append block file ] view block
view [ image 100x100 %DirtbikeChampionship.jpg image 100x100 %DominoDraw.jpg image 100x100 %DuckHunt.jpg ]
block: copy [] files: read %./ foreach file files [ if %.jpg = suffix? file [ append block 'image append block 100x100 append block file ] ] view block
view
gets it, what does it contain in the case where it fails? Examining the data sometimes make things obvious.view layout [radio "test" right true]
results in a Script Error.align
in front of right
or text
in front of "my_text"
. However both result in a Script Error. What is different with data
?data
is required where align
and text
are not. I've had a very tough time finding what I need in the documentation, and have just had to rely on the good folk here and lots of trial and error to get my GUI mostly functional. The community here is patient and very helpful.property value
syntax. If you look at the Keywords and Datatypes sections in the doc, that should clear things up. Some keywords are independent, while others take args (e.g. draw, data), and some datatypes can be automatically applied to a face based on their type.para
facet, which you can apply like so:red>> view layout [radio "test" para [align: 'right] data on]
logic!
values, which is why true
or on
isn't automatically applied to the data
facet.VIEW
and want to ask about a pointer to any documentation. When looking at various examples I collected the following possible element properties for the GUI element TEXT
.center / right / left size bold / italic / underline font size <xx> background color <xxx.yyy.zzz> font-color hidden
help text
does not work here.backcolor white ; not compatible to RED text "Normal" text "Bold" bold text "Italic" italic text "Underline" underline text "Bold italic underline" bold italic underline text "Big" font-size 32 text "Serif style text" font-name font-serif ; not compatible to RED text "Spaced text" font [space: 5x0] ; not compatible to RED
Red [ Title: "Simple GUI livecoding demo" Author: "Nenad Rakocevic" File: %livecode.red Needs: 'View Usage: { Type VID code in the right area, you will see the resulting GUI components rendered live on the left side and fully functional (events/actors/reactors working live). } ] view [ title "Red Livecoding" output: panel 400x600 source: area 500x600 wrap font-name "Fixedsys" on-key-up [ attempt [output/pane: layout/only load source/text] ] ]
red[] trigger: ["<title>" "</title>"] trigger-start: trigger/1 page: read http://www.rebol.com/ parse page [thru trigger-start copy text to "</title>"] ; -- works parse page [thru trigger/1 copy text to "</title>"] ; -- fails ; *** Script Error: PARSE - invalid rule or usage of rule: trigger/1 print text
parse page compose [thru (:trigger/1) copy text to "</title>"]
PS E:\Red\red> ./gui-console tests/hello.red
red>> dash: charset {-—} == make bitset! #{0000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000``` But when Red tries to evaluate that from a start up script, it chokes. Also, that looks like a bizarro bitset. The error:
`C:\Users\redacted\PortableApps\Red\red-061.exe start.red
¿word: [some letter] ¿spaces: [some whitespace] ¿words: [some ¿word] ¿phrase: [some [ ¿words | ¿spaces] ] ¿sentence: [some ¿phrase opt endmark] red>> s: "This is a silly Sentence?" == "This is a silly Sentence?" red>> parse s [ ¿sentence] == true red>> s: "This is a sillier **$*$*$23 sentence!" == "This is a sillier **$*$*$23 sentence!" red>> parse s [ ¿sentence] == false
Parse
mixed all kinds of naming, which only added to the poor explanations offered. Too many struggle to explain what they claim to know. Their struggling calls into question always how much do they know, in truth.¡
-t Android
and it should work (I haven’ tried it in a while but it worked last time I checked it)Ctrl+L
clears the Red GUI console, just FYI.system/console
can be modded, or if we need to do it at the lower levels.collect [repeat i 10 [keep/only collect [repeat j 10 [keep random true]]]]
array
function:array: function [ "Makes and initializes a block of of values (NONE by default)" size [integer! block!] "Size or block of sizes for each dimension" /initial "Specify an initial value for elements" value "For each item: called if a func, deep copied if a series" ][ if block? size [ if tail? more-sizes: next size [more-sizes: none] size: first size if not integer? size [ cause-error 'script 'expect-arg reduce ['array 'size type? get/any 'size] ] ] result: make block! size case [ block? more-sizes [ loop size [append/only result array/initial more-sizes :value] ] series? :value [ loop size [append/only result copy/deep value] ] any-function? :value [ loop size [append/only result value] ] 'else [ append/dup result value size ] ] result ] a: array/initial [10 10] does [random true]
parse
parse
.collect [ parse [a b c d e] [ any ['c | 'e | set w word! (keep w)] ] ] [a b d]
collect
for parse
in red? Simpler syntax? I'd thought there was a technical reason..red-26sep16-5ec74dc.exe -c -t Android-x86 environment/console/console.red
collect/keep
in Parse is faster, more flexible (keep
can be applied to matched input by rules) and it supports recursion.u0_a264@ASUS_T00F:/ $ ./Removable/MicroSD/console CANNOT LINK EXECUTABLE: could not load library "libcurl.so.4" needed by "./Removable/MicroSD/console"; caused by library "libcurl.so.4" not found 1|u0_a264@ASUS_T00F:/ $
view [ size 800x600 canvas: base 780x580 draw drawblock rate 30 on-time [ do iterate do refresh do sync-grids show canvas ] ]
probe
to see if it updates properlyscratchgrid is a block! of value: [[false .. ]]
scratchgrid:
on the outside (oh wait, you have! hmm..)draw
command (that one does not seem to be modified), so your display will not change. What you need to do is re-use the block of Draw commands (by clearing it, and filling it again), and not create new ones each time.image!
ya?#"^A"
. I wonder if we should support ^ escaping with lowercase letters.red-26sep16-5ec74dc
on-key
actor to do it though. e.g.cmd-do: does [print "hello"] handle-key: func [face event][ if event/ctrl? [ switch event/key [ #"A" [cmd-do] ] ] ] view [ button "DO" [cmd-do] on-key [handle-key face event] ]
cmd-do: does [print "hello"] view [ button "DO" [cmd-do] on-key [if all [event/ctrl? #"A" = event/key][cmd-do]] ]
do-face
yet, to trigger its default actor.help do-actor
.fill-pen circle 5
) into the draw block, the canvas
face! will be refreshed immediately (Realtime updating mode). But the draw block is not completely constructed, it will case the following draw error:*** Script Error: invalid Draw dialect input at: [<color> circle <coord> 5] *** Where: ???
Deferred updating
mode, I updated the here:show
manually after all faces coords are changed. Else, refresh is done for each XX/size
or XX/offset
changes and its too heavy to be responsive. You can test it by changing the on-drag-start
last value from no
to yes
.useto create "private" words in a context (object). It is explained in this Rebol mailing list [thread](http://www.rebol.org/ml-display-thread.r?m=rmlRJCC).
useis not yet implemented in the current alpha release of Red.
use
mezzanine if you want to play with that). I haven't seen anyone pursue it and doc their experiences though. I did the same thing when I found Rebol. I implemented a few things, ended up using a naming convention after that, but often don't even do that. I would hazard a guess that most long time Redbol users are the same, based on code I've seen.function
uses optional strings to self-document in a way that's accessible at runtime. Maybe something like that is the most elegant solution here? I assume I could accomplish something similar by using a mezzanine function to create my objects rather than invoking make object!
directly. That wouldn't stop people from altering internal values directly from the console, of course, but it could perhaps allow a higher level interface of some sort to maintain control over access. Is this totally the wrong way to be thinking about it? I appreciate your time here. It is tremendously valuable to have so much access to people with so much experience.parse
comes in). In that light, don't think about sharing code and making the code last. Think about structuring and sharing data so *it* can last and is amenable to processing and understanding.spec-of
have been helpful for me. function
uses optional strings to self-document in a way that's accessible at runtime. Maybe something like that is the most elegant solution here?parse
is usefulweather_module/temperature
directly, I might define a function called request
that (in tandem with parse
, presumably) can return the appropriate value to request temperature from weather_component
but also reject request private_variable from weather_component
?>> 24-dec-2016 - now == 82 >> 24-dec-2016/0:00 - now == 82
difference
seems to get you half-way there:difference 24-dec-2016 now == 1952:06:01
difference
, hadn't even thought it would do that in-minutes: func [d1 [date!] d2 [date!] /local d t] [d: d2 - d1 d1/date: d2/date t: difference d2 d1 d * 1440 + t/hour * 60 + t/minute]
(24-dec-2016 - now)/minutes
... but since the subtraction returns an integer the refinement I tried can not even work (besides being invalid syntax, right?)>> time-diff: difference 24-dec-2016 now == 1951:42:11 >> time-diff/2 == 42
date-diff
would be easy to write, and let you control your result. The rebol behavior makes some things easy, and others a bit more work. Another one of those darn subjective design decisions. :^)date-diff
. I suppose rel-date! would be like timespan in some other langs.DATEDIFF
in SQL.select timediff("2016-12-24 10:00", Now())
difference
, it seemsDate-diff
will take some thought, as would a supporting relative date data model. I've seen it as [months days time] and [days time]. >> 2016-12-24/10:00 - 2016-10-01/11:00 == 84.976
.976
is random)84
as rebol does Red [] ;----------------------------------------------------------------------- ; Fetch date and time from internet ; (hack until date functions are implemented) ;----------------------------------------------------------------------- datetime: context [ mid: func [s start len][copy/part at s start len] ; as in Basic format2: func[num[integer!]] [ num: form num if tail? next num [insert num "0"] return num ] page: read http://time.is/ ; maybe this have to be adjusted for other countries! ; investigate the source of the page in a browser parse page [ thru {<div id="twd">} copy time to {</div>} thru {title="Click for calendar">} copy date to { (} ] hour: mid time 1 2 minute: mid time 4 2 second: mid time 7 2 months: [ "january" "february" "march" "april" "may" "june" "july" "august" "september" "october" "november" "december" ] date: split date " " dayname: date/1 day: date/2 2 ;day: format2 to integer! date/2 2 ; 2 digits month: date/3 year: date/4 month: index? find months date/3 ;month: format2 to integer! index? find months date/3 2 ; 2 digits ] ; usage: print [datetime/hour datetime/minute datetime/second] print [datetime/dayname datetime/day datetime/month datetime/year]
page: read http://time.is/?lang=en
Red [] ;----------------------------------------------------------------------- ; Fetch date and time from internet ; (hack until date functions are implemented) ;----------------------------------------------------------------------- datetime: context [ mid: func [s start len][copy/part at s start len] ; as in Basic format2: func [ num[integer!] ] [ num: form num if tail? next num [insert num "0"] return num ] page: read http://time.is/?lang=en ; maybe this have to be adjusted for other countries! ; investigate the source of the page in a browser parse page [ thru <div id="twd"> copy time to </div> thru {title="Click for calendar">} copy date to </div> ] hour: mid time 1 2 minute: mid time 4 2 second: mid time 7 2 months: [ "january" "february" "march" "april" "may" "june" "july" "august" "september" "october" "november" "december" ] date: split date " " dayname: head remove back tail date/1 day: head remove back tail date/3 month: date/2 year: head remove back tail date/4 month: index? find months date/2 ] ; usage: print [datetime/hour datetime/minute datetime/second] print [datetime/dayname datetime/day datetime/month datetime/year]
datetime: context [ page: read http://time.is/?lang=en months: [ "january" "february" "march" "april" "may" "june" "july" "august" "september" "october" "november" "december" ] hour: minute: second: dayname: day: month: year: none parse page [ thru <div id="twd"> copy time to </div> thru {title="Click for calendar">} copy dayname to #"," 2 skip copy month to #" " skip copy day to #"," 2 skip copy year to #"," ] set [hour minute second] split time #":" month: index? find months month ] ; usage: print [datetime/hour datetime/minute datetime/second] print [datetime/dayname datetime/day datetime/month datetime/year]
page
is read once.datetime/second
, it does not change./hour
etc. are refinements.datetime: function [ /hour /minute /second /dayname /month /day /year ] [ export: none foreach word [hour minute second dayname month day year] [ if get word [export: word break] ] page: read http://time.is/?lang=en months: [ "january" "february" "march" "april" "may" "june" "july" "august" "september" "october" "november" "december" ] hour: minute: second: dayname: day: month: year: none parse page [ thru <div id="twd"> copy time to </div> thru {title="Click for calendar">} copy dayname to #"," 2 skip copy month to #" " skip copy day to #"," 2 skip copy year to #"," ] set [hour minute second] split time #":" month: index? find months month get word ] ; usage: print [datetime/hour datetime/minute datetime/second] print [datetime/dayname datetime/day datetime/month datetime/year]
export
checks which refinement you want, otherwise the code would be more complicatedtrue
. So export
stores name of first refinement that is true
.export
and returns it.export
was just first word that came to my mind :)if get word [break]
map!
or object!
type fields get cloned (rather than just passed as reference)? I've tried using copy/deep, but the prototype and subsequent objects still both end up referencing the same thing.copy/deep
should do exactly this.types
which ensures only certain types of (non-scalar) fields are copied but the argument to that is [datatype!]
whereas I would have thought it should be [typeset!]
given the plural *types*. I will make that a wish.clone
func, and others may as well.clone: function [ "Deep make an object" object [object!] /with spec [block!] "Extra spec to apply" ][ cloners!: union series! make typeset! [object! map! bitset!] new: make object any [spec clear []] foreach word words-of new [ val: get in new word if find cloners! type? :val [ new/:word: either object? val [ clone val ][ copy/deep val ] ] ] new ]
object!
, map!
, and bitset!
datatypes that pass through prototyping as references in this way?copy
function is there to allow you to avoid mutation when you need it. See a longer explanation here: http://www.rebol.com/article/0206.htmlmake
to construct them. That may or may not be a good thing. issue!
seems quite exotic too, doesnt it?issue!
I first thought for a second "how cool, i can directly create github-issues in the language"issue!
type.n°
for that, as abbreviation for numero
(== number
), don't know for other EU countries.No.
can be used here, but the octothorp is the most common symbol.make
, Red does copy string!
and other series!
by default, though, doesn't it? (Not to mention integer!
and float!
, but perhaps that's a different question)make
is precisely to create a new instance of a given datatype. ;-)make
doesn't clone object!
or map!
fields, as well. I'm sure there's a good reason for treating block!
and map!
differently in this regard; my reason for asking is just to try to understand Red's design.copy
. It has a /deep
refinement, so you can control whether you want it to copy nested non-scalars. Make
with objects works similarly, except there's no /deep
option and we just have to write a clone
func to do it.make
does clone referenced series (block!
is a series) in an object, because this behavior covers the best the common use-cases. Objects or maps are heavy datatypes, in the common cases, you want to keep a reference to the same ones, not clone them (though, you can clone them manually using copy
when you really need it). Trees of objects or maps that you need to clone deeply is not a case I remember seeing often in Rebol (except in code from OOP guys, trying to bend the language to work in a purely OOP way), usually you would rather model such tree using blocks.red>> res: read/info http://red-lang.org == [200 #( Cache-Control: "private, max-age=0" Date: "Wed, 05 Oct 2016 23:20:41 GMT" Transfer-Encoding: "chunked" Content-Type: "text/html; char...
/info
isn't documented yet, so may change in the future, but it very nicely returns you 3 values: [result-code [integer!] headers [map!] content [string! binary!]]object!
and map!
by reference but copy series!
because, most of the time, nested objects and instance-specific maps are out of step with Red's approach to prototyping. Deep structure is usually better accomplished through blocks." If that's accurate, it makes sense, and it helps me see the differences from mainstream OOP a bit more clearly. Thanks!/info
, did I look in the wrong place?info?
parameter that must be map to the /info
refinment of the read handler.read
and HTTP might be elsewhere.url!
[datatype](https://github.com/red/red/blob/master/runtime/datatypes/url.reds#L168).\ Roman numerals Create romans ( ones) char I c, char V c, ( tens) char X c, char L c, ( hundreds) char C c, char D c, ( thousands) char M c, Variable column# ( current_offset) : ones 0 column# ! ; : tens 2 column# ! ; : hundreds 4 column# ! ; : thousands 6 column# ! ; : column ( -- address-of-column ) romans column# @ + ; : .symbol ( offset -- ) column + c@ emit ; : oner 0 .symbol ; : fiver 1 .symbol ; : tener 2 .symbol ; : oners ( #-of-oners -- ) ?dup IF 0 DO oner LOOP THEN ; : almost ( quotient-of-5/ -- ) oner IF tener ELSE fiver THEN ; : digit ( digit -- ) 5 /mod over 4 = IF almost drop ELSE IF fiver THEN oners THEN ; : roman ( number -- ) 1000 /mod thousands digit 100 /mod hundreds digit 10 /mod tens digit ones digit ;
case
...help read
in the console. form
?form
doesn't allow me to strip the spaces between different values nor does it allow me to prepend zeros.format
function in the future (lots of design ideas in the works). For now, if you specific needs, we can provide examples of little helpers that give you more control than form
.sprintf
to format strings in Red/System if it's a c-string!.sprintf
. Thanks @qtxie c-string!
, won't I? How should I do this?#define BUF_SIZE 1024 buf: allocate BUF_SIZE sprintf [buf "number %d" 123]
person
object, should it *contain* field? If so, is there also a global list of fields that has a separate copy of that field's data? Or is it better to think in terms of relationships between objects? Not the is-a/has-a
inheritance/composition choice but as data relations. Object containership defines implicit, fixed relationships. But cows are not a property (in OO terms) of a person object. Except in this case: http://i.ebayimg.com/images/i/401128929397-0-1/s-l1000.jpgpatches
and turtles
, each with localized behaviors and knowledge. The observer
is the all-seeing eye.[ [Bob buys 2 cows [bessie and flossie] from Carol] [Alice moves to house #5] [Dan buys field #37N...] ; (It's a UTM coordinate system, right? ;^) ]
[ Bob buys 2 cows [bessie and flossie] from Carol . Alice moves to house #5 . Dan buys field #37N... . ]
parse
, but for humans.[ Bob buys 2 cows [bessie and flossie] from Carol Alice moves to house #5 Dan buys field #37N... ]
2 cows
is not needed, but I thought of the sub-block more like a parenthetical comment.word! ahead 'and
for infix rulesworld [ cows [ bessie [] flossie [] ] fields [ flanders [] flossie [] ] ]
bessie and flossie
(without a sub block), means two cows, rather than a cow and a field?world
block, just add people
and houses
and you have the basics. Then we have to define relationships between those things. What might that look like?world
example.construct
into objects. Red solves a lot of the pain in Rebol that came from using set-words as keys in blocks, and we have maps too. It's a very fluid mix for me.block!
, for named data use object!
. Or map!
. That is the real question. Or hash!
instead of block!
? Damned, so many datatypes ;)over
event, you can check event/flag.face
and event
in your function, or foo
and bar
. It’s just first and second argument.load/as 64#{...} 'png
should work. We need to improve the image codec automatic detection, so it will work as in Rebol.rate
in VID. See the eve clock demo.base 200x200 transparent rate 1 nowYou specify
rate 1
- that means 1 fps. on-time
actor that is run every second.red --help
? Or is that what you are looking for?any [ ["-c" | "--compile"] (type: 'exe) | ["-r" | "--release"] (opts/dev-mode?: no) | ["-d" | "--debug" | "--debug-stabs"] (opts/debug?: yes) | ["-o" | "--output"] set output skip | ["-t" | "--target"] set target skip (target?: yes) | ["-v" | "--verbose"] set verbose skip ;-- 1-3: Red, >3: Red/System | ["-h" | "--help"] (mode: 'help) | ["-V" | "--version"] (mode: 'version) | ["-u" | "--update-libRedRT"] (opts/libRedRT-update?: yes) | "--red-only" (opts/red-only?: yes) | "--dev" (opts/dev-mode?: yes) | "--no-runtime" (opts/runtime?: no) ;@@ overridable by config! | "--cli" (gui?: no) | "--catch" ;-- just pass-thru | ["-dlib" | "--dynamic-lib"] (type: 'dll) ;| ["-slib" | "--static-lib"] (type 'lib) ]
Program data\red
and red
git source) :(-=== Red Compiler 0.6.1 ===- Compiling C:\Users\XXX\Documents\GitHub\red\red\tests\hello.red ... Compiling compression library... Script: "Red/System PE/COFF format emitter" (none) *** Linker Error: locked or unreachable file: .\..\crush.dll
tests/quick-test.r
and this line in particular to char! ((shift code 6) and #"^(1F)" or #"^(C0) »)
. It is like mathematics, at some point it is just impossible to avoid parentheses to change priority rules in evaluation. The good point in Redbol is to try to avoid it when not necessary as a literal language. Sorry! You posted the same message or I receive an old message...and
, I'd thought it was more uniform. I'm a redbol newbie too :wink: parse
greedy, I changed my code to not work against itcollect/keep
combo, or just copy
or set
, depends on your needs.parse [1 2 a 3] [any [integer! | copy w word! (?? w)]] list: [] parse [1 2 a 3 b 4] [any [integer! | set w word! (append list w)]] parse [1 2 a 3 b 4] [collect any [integer! | keep word!]]
collect into
z: copy [] print mold parse [a b c] [any [collect into z [keep word!]]] print mold z ; => [c b a]
into
it prepends, not appends :)/into
has insert semantics, there was a conversation about it..parse/collect
, it's the only case where parse returns a block! instead of logic! @dockimbel you set the rules
probe
, thanks)split
:smile: in rebol3 and redparse
red *** Driver Internal Error: Script Error : Out of range or past end *** Where: parse-options *** Near: [if cmd: select [ "clear" do-clear ] first]
red --cli --== Red 0.6.1 ==-- Type HELP for starting information. red>> x: 5 == 5 red>> b: context [ [ x: x [ ] *** Script Error: x has no value *** Where: x
parse/collect
(or parse/into
) may be a good idea, I was just playing devil's advocate ;) it's not that unusual that function returns different typesbind
technique, but I'm not sure if it is ported to Redred>> x: 5 == 5 red>> b: context [x: system/words/x] == make object! [ x: 5 ]
x
value is fetched from global context and not local one.declare
is a static allocation, not a dynamic one (use allocate
and free
for that).compose
is the right option.Color - v3/x: 0.1479379273840342 y 0.2071130983376479 z 0.2958758547680684 Color - v4/x: 0.7041241452319316 y 0.7041241452319316 z 0.7041241452319316 ADD-A x 0.7041241452319316 y 0.7041241452319316 z 0.7041241452319316 ADD-B x 0.7041241452319316 y 0.7041241452319316 z 0.7041241452319316
a: [ b 1 ] ; and a: [ b: 1 ]
a/1
and a/b
, the second is a set, what is the first?collect [foreach thing a [keep type? thing]]
a: [ b 1 ]
:[word! integer!]
a: [ b: 1 ]
:[set-word! integer!]
collect
line pseudo code? I understand nothing of that line :)[b 1]
? its not a set, right? an object neitherreduce a
, they would work differenta/b
return 1
for a: [b 1]
, for a: [b: 1]
I would understand itselect
red>> a: reduce [ b 1 ] *** Script Error: b has no value *** Where: reduce red>> a: reduce [ b: 1 ] == [1]
>> a: [ b: 1 ] == [b: 1] >> a/b ** Script Error: Invalid path value: b ** Near: a/b >> select a to set-word! 'b == 1
a: [b 1]
I can still access a/b
, so what is in that block? It's not a set, right?a
local variable is statically create for the function : its adress is the same at each call. So testu
and testv
point to the same address after calling the function: they are the same.a).
vec3-Mfloat: func [ vec [vector3!] f [float!] new-vec [vector3!] ][ new-vec/x: vec/x * f new-vec/y: vec/y * f new-vec/z: vec/z * f ]
vec3-Mfloat direction testf testu vec3-Mfloat origin testf testv
red>> forall x/z [print first x/z] *** Script Error: forall does not allow path! for its 'word argument *** Where: forall
red>> o: object [a: 1 b: 2] == make object! [ a: 1 b: 2 ] red>> foreach w words-of o [print [w get w]] a 1 b 2
o: object [a: [1 2 3]]
forall
limitation, see the help: *'word [word!] => Word referring to series to iterate over.* - it does not accept path!
red>> to get-word! "foo" *** Script Error: TO cannot convert get-word! from: foo *** Where: to red>> to set-word! "foo" == foo: red>> to word! "foo" == foo
load append copy ":" 'a
(until it's fixed).to
have been dismissed by Doc because the implementation of to
is not finalized.to
can convert to lit-word!
and can't to get-word!
red>> afun: func [x] [ func [y] [x]] == func [x][func [y] [x]] red>> a: afun 1 == func [y][x] red>> a 3 *** Script Error: x is not in the specified context *** Where: a
to
is only partially implemented for now, we need to rework and complete it. Closures are not yet available in Red.to
is an action in each datatype so there is a logical reason why it might work for one but not another.allocateto reserve memory for the new structure and then assign the address of that memory to the structure. You can then return the pointer from the function. One issue with that approach is knowing when to release the memory allocated to the structure.
list: declare struct![ item1 [sphere!] item2 [sphere!] item3 [sphere!] ]
list/1 or list/x
Red/System [] sphere!: alias struct! [ radius [integer!] ] list: declare struct![ item1 [sphere!] item2 [sphere!] item3 [sphere!] ] list/item1: declare sphere! list/item2: declare sphere! list/item3: declare sphere! list/item1/radius: 1 list/item2/radius: 2 list/item3/radius: 3 print [as integer! list/item1/radius " " list/item2/radius " " list/item3/radius lf] sphere-len: 4 item: declare sphere! list-as-array: as byte-ptr! list/item1 i: 1 until [ item: as sphere! list-as-array print [i " " item/radius lf] list-as-array: list-as-array + sphere-len i: i + 1 i > 3 ]
spheres: declare struct![ item1 [sphere!] item2 [sphere!] item3 [sphere!] ] list: as sphere! spheres
list/1
or list/x
.spheres: as sphere! allocate 3 * size sphere!
Red/System [] sphere!: alias struct! [ radius [integer!] ] spheres: declare struct![ item1 [sphere!] item2 [sphere!] item3 [sphere!] ] s1: declare sphere! s1/radius: 45 spheres/item1: s1 list: as sphere! spheres print [list/1/radius]
item1in the above structure is offset from the start of the structure:
address of spheres 00003060 address of spheres/item1 0000307C
listto the address of
`spheres/item1 to get the code to work.list/1:
*** Compilation Error: invalid struct member 1 *** in file: %/Users/peter/VMShare/Code/Red-System/test.reds *** at line: 25 *** near: [list/1 lf]
spheres
is a set of 3 pointers of 4 bytes each, so 12 bytes. So spheres/item1
is the address of s1
struct in memory: its a pointer.sphere!
structs, initializing the radius
with values from a literal array of integers:sphere!: alias struct! [ radius [integer!] ] spheres: as sphere! allocate 3 * size? sphere! list: [45 30 60] s: spheres i: 0 while [i < 3][ s/radius: list/value print ["Sphere " i " radius: " s/radius lf] list: list + 1 s: s + 1 i: i + 1 ]
red>> afun: func [x] [c: context compose [x: (x) f: func[y][x]] :c/f] == func [x][c: context compose [x: (x) f: func [y] [x]] :c/f] red>> a: afun 1 == func [y][x] red>> a 3 == 1
compose
trick for using the same argument name today, but it makes me think this could evolve into a generalized closure
function generator#include %runtime/random.reds _random/init _random/srand 123 ;-- set the seed probe _random/rand ;-- get a random 32-bit integer
#system
directive or routine
), then the include and init are not required, they are already done for you by the Red runtime library.function
.function
all local values are initialized on each call (usually to none
).counter
function, that will increase some local variable by one each time it’s called?func [] [counter: 0 func [] [ counter: counter + 1 ]]
counter
is globalfunc does not gather local words
func
because it is simply shorter, and all variables will leak into global contextfunc
is the lowest level constructor for functions, it requires you to declare local words yourself. function
is a higher-level constructor (it has a different behavior in Rebol), which gather the local words for you using an heuristic (gathering set-words from the function's body), which can sometimes have unwanted effects (so to be used carefully). function
is just a wrapper over func
./extern
red>> bla *** Script Error: bla has no value *** Where: catch red>> f: function [][bla: none set 'bla 1] == func [/local bla][bla: none set 'bla 1] red>> f == 1 red>> bla *** Script Error: bla has no value *** Where: catch
func
to function
(and actually seems better this way because it doesn't leak into the global namespace), presumably because it creates a new context object each time afun is called? I don't know if this is a good way of doing something like this. To be honest, I don't really know what I am doing. Just experimenting :smile: context
always creates new context and old one is not destroyed. But with func
version, c
leaks and holds last context.closure!
type or a [closure]
attribut to functions would probably allow a more efficient internal implementation.view [b: base on-key [print event/key] do [self/selected: b]]
none
. How come?tabbable?
property, to distinguish, if the item can actually get focus, or something like that. Some systems allow even the focus nesting, so that you have to press ESC to get out of that ... might be related to also how you wish arrow keys to works, etc./selected
property or by clicking/tabbing to another focus-enabled face on screen. Tabbing support is not ready yet.replace
changes elements inside blockinterpreter
mode?replace
sourceinsert pos value
function!
, will it be evaluated?red>> f: func [x y] [append x y] == func [x y][append x y] red>> f [] does [print "yo yo"] yo yo == [unset]
error!
is just another datatypered>> f: func [x :y] [append x :y] == func [x :y][append x :y] red>> f [] does [print "yo yo"] == [print "yo yo"]
'a
in arguments list to prevent evaluation, is it different from :a
or are they the same?'a, a lit-word!, evaluates to a word.
:a, a get-word, evaluates to the contents of the value bound to
a.
red>> a: 1 == 1 red>> do first ['a] == a red>> do first [:a] == 1
red>> a == 1 red>> :a == 1
red>> f: func [] [print "executed"] == func [][print "executed"] red>> f executed red>> :f == func [][print "executed"]
red>> f1: func ['a] [probe a] == func ['a][probe a] red>> a: 5 == 5 red>> f1 a a == a red>> f2: func [:a] [probe a] == func [:a][probe a] red>> f2 a a == a
>> f1: func ['a] [probe a] >> a: 5 == 5 >> f1 a a == a >> f2: func [:a] [probe a] >> f2 a 5 == 5
red>> f: func [:fun [function!]] [fun] == func [:fun [function!]][fun] red>> f1: func [] [print "running"] == func [][print "running"] red>> f f1 *** Script Error: f does not allow word! for its :fun argument *** Where: f
>> f: func [:fun [function!]] [fun] >> f1: func [] [print "running"] >> f f1 running
words-of my-object
words-of
name is a bit misleadingvalues-of
.[RedBall sphere radius 10 position 0 0 5] [RedBall sphere position 0 0 5 radius 10]
rule: [ word! 'sphere any [set ver 'radius (print ver) | set ver 'position (print ver)] any [set int integer! (print ["Integer" int]) | float! (print ["float" ver])] any [set ver 'radius (print ver) | set ver 'position (print ver)] ]
if radius [more rules]
'sphere
, but then, what would you do about duplicates?radius: pos: none rule: [ word! 'sphere 2 [ if (not radius) 'radius set radius integer! (?? radius) | if (not pos) 'position pos: 3 integer! (print ["position:" copy/part pos 3]) ] ]
radius: ['radius set ver number! (print [name "radius" ver]) ] position: ['position set v1 number! set v2 number! set v3 number! (print [name "position" v1 v2 v3 ])] rule: [ set name word! 'sphere any [radius | position ] ] parse [RedBall sphere radius 10 position 0 0 5] rule parse [RedBall sphere position 0 0 15 radius 20] rule>
radius: ['radius set ver number! ] position: ['position set v1 number! set v2 number! set v3 number! ] rule: [ set name word! 'sphere any [radius | position ] to end (print [name "sphere of radius" ver "at position" v1 v2 v3]) ] parse [RedBall sphere radius 10 position 0 0 5] rule parse [RedBall sphere position 0 0 15 radius 20] rule
RedBall sphere of radius 10 at position 0 0 5 RedBall sphere of radius 20 at position 0 0 15
[Suppose we have a block and it has two lines of text, each having a different number of words]
red>> blk == [Suppose we have a block and it has two lines of text each having a different number of words ] red>> find-new-line: func [block] [ [ forall block [if new-line? block [return block]] [ none [ ] == func [block][forall block [if new-line? block [return block]] none] red>> pos: find-new-line blk == [ it has two lines of text each having a different number of words ] red>> pt-1: copy/part blk pos == [Suppose we have a block and] red>> pt-2: copy pos == [ it has two lines of text each having a different number of words ]
split
to handle.parse
is leveraged for all kinds of processing you might not initially consider it for.do/next
(basically). Generalizing this is much harder, and where the Eve/spreadsheet/dataflow model comes in.-o
command-line option?parse "first second third" [thru "first " copy second to " third"] print second second: parse "first second third" [collect ["first " keep to " third"]] print second
view/no-wait layout [ space 0x-2 panel [ space 0x-2 p1: panel aqua [ p1a: panel white [ space 0x-2 t1: text "hello" button "hi" [] ] return p2: panel red [ pi2: panel blue [ space 10x-2 text "here is" return button "world" [] ] ] ] ] ] center-face pi2 p2 do-events
Origin
view/no-wait layout [ space 0x0 panel [ space 0x0 origin 0x0 p1: panel aqua [ origin 0x0 p1a: panel white [ origin 0x0 space 0x0 t1: text "hello" button "hi" [] ] return p2: panel red [ origin 0x0 pi2: panel blue [ origin 0x0 space 0x0 text "here is" return button "world" [] ] ] ] ] ] center-face pi2 p2 do-events
tight
. So extending per style VID dialect (in fetch-options
).layout
).view/tight
is only for top level container..test: func [ block [series!] ][ foreach item block [ print item * 2 ; do something with each item ] ] block: [2.3 4.6 7.8 3.1 8.7 12.3 10.2] test block
convert: routine[ ob [block!] ob-len[integer!] /local len i s ][ ob ; ???? ] Sblock: [10.0 0.0 0.0 -1.0 2.0 1.0 0.2 0.2 0.0 10.0 0.0 0.0 -1.0 1.0 1.0 0.2 0.2 0.0] convert Sblock length? Sblock
red-
prefix (so as red-block!
) and then use R/S functions defined in %red/runtime/datatypes/block.reds
to work with that block.Routine
handles that automatically, but I had the same thought Bolek.convert: routine [ ob [block!] ob-len [integer!] return: [integer!] /local len i size ][ size: block/rs-length? ob return size ] Sblock: [10.0 0.0 0.0 -1.0 2.0 1.0 0.2 0.2 0.0 10.0 0.0 0.0 -1.0 1.0 1.0 0.2 0.2 0.0] print convert Sblock length? Sblock
convert: routine[ ob [block!] ob-len[integer!] /local len i s value tail fl ][ value: block/rs-head ob tail: block/rs-tail ob while [value < tail][ fl: as red-float! value probe fl/value value: value + 1 ] ]
convert: routine[ ob [block!] ob-len[integer!] /local len i s value tail fl head ][ s: GET_BUFFER (ob) head: s/offset value: head tail: s/tail while [value < tail][ fl: as red-float! value probe fl/value value: value + 1 ] ]
call
, how does one specify the working directory? change-dir
doesn't seem to affect it.change-dir
, Which OS are you using?change-dir:
instead of change-dir
, haha!not empty?
but that is forbidden.test1: make bitset! {test} test2: make bitset! length? test1 not test2 = test1
block: copy [] number-of-buttons: 10 fontsize: 50 buttonsize: 100x70 repeat i number-of-buttons [ s: to string! i append block [button buttonsize font-size fontsize] append block s append block [[print "clicked"]] ; need to know which one is clicked ] probe block view layout block ; post-processing with layout
face
object available. That should be enough IMO. But if it’s not, set something in extra
.view layout [button extra 'my-button [probe face/extra]]
block: copy [] number-of-buttons: 10 fontsize: 50 buttonsize: 100x70 repeat i number-of-buttons [ append block compose [ button buttonsize font-size fontsize extra (i) (form i) [print ["clicked" face/extra]] ] ] probe block view layout block ; post-processing with layout
extra
is part of face!
definition (try red>> ? face!
) that can be used for storing user data.block: copy [] append block [size 800x600] repeat i 21 [ t: rejoin["t" i] append block compose [ image 50x50 text (t) ] ] probe block view block
panel
maybe :block: copy [] append block [size 800x600 below] repeat j 3 [ append block reduce ['panel sub: copy [origin 0x0 below]] repeat i 7 [ t: rejoin["t" i] append sub compose [ image 50x50 text (t) return ] ] ] probe block view block
block: copy [] append block [size 800x600 below] repeat j 3 [ append block reduce ['panel sub: copy [origin 0x0 below]] repeat i 7 [ t: rejoin["t" j "," i] append sub compose [ image 50x50 extra (as-pair j i) [print ["clicked" face/extra]] text (t) return ] ] ] ;probe block view block
irx
@fergus4 and there is https://gitter.im/red which will send you to the listing of all red rooms.irx
@geekyi, I'm using gitter bridged into matrix and then the matrix client. Mostly riot android, sometimes riot.im/develop web-client.irx
It's great for reading (except edited posts are hard to read this way). It's not so great to post.options
-r, --no-runtime : Do not include runtime during Red/System source compilation.
hello.red
in my similar question [here](http://stackoverflow.com/questions/24360991/how-do-i-run-an-android-app-ive-written-in-red), and then follow the answers there, especially the top 2, to get it working on Android.hello.red
. I haven't done it in a long time, and Red has been worked on a lot since then, so there's a small chance that the Android part might not work anymore. Someone else might know, or you could just try it. It won't take long.bytes
, also used for binary data and file blobs) and one singular universal character set/string (str
)bytes
and the string
type is unicode, utf-8string
is universal and count by the character (and other diacritics etc.) while bytes
can represent UTF8, UTF16, file data or other "byte-like" thingsstring
uses code points or "characters" (which transcends binary data) while bytes
represents binary data. I use bytes
for texts sometimes and read/write files other times...string
uses code points or "characters" (which transcends binary data) while bytes
represents binary data. I use bytes
for texts sometimes and read/write files other times...string
being a text type with virtual encodingsbytes
to strings
and then back to bytes
length?
works on binary!
and string!
. I think then you might need a custom UTF-16 typeread
ing that causes the spike?view [ button "start" [ repeat i 159 [ p/data: (i / 159.0) p/data: to percent! p/data read %bookmarks.txt ; size is 4,66MB ] t/text: "Ready" ] t: text font-size 20 " " p: progress data 0.0 ]
Acer Store Europe http://go.acer.com/?id=14428 Acer Store US http://us-store.acer.com/ Amazon http://www.amazon.com/?force-full-site=1 Artificial Intelligence - Chapter 2 Notes - Computer Science Now http://www.comsci.us/ai/notes/chap02.html Back2BASIC - B2B Code Show http://back2basic.phatcode.net/?Issue_%235:B2B_Code_Show Back2BASIC - B2B Code Show: Polyplotter http://back2basic.phatcode.net/?Issue_%237:B2B_Code_Show%3A_Polyplotter BBC http://www.bbc.co.uk Beyond The Cosmos Quantum Mechanics - YouTube
read/lines
crashes it for meread/lines
, there's a huge 771mb spike like your graphread/lines/part/seek %file.txt chunk offset
might help/lines
red-20nov16-88de5e0
read/lines/as %bookmarks.txt 'latin-1 *** Internal Error: reserved for future use (or not yet implemented) *** Where: read
view [ button "start" [ repeat i 159 [ p/data: (i / 159.0) w: read/lines %testing.red ; change to an existing (small) file! ] t/text: "Ready" ] t: text font-size 20 " " p: progress data 0.0 ]
view [ button "start" [ repeat i 2259 [ p/data: (i / 2259.0) w: read/lines %testing.red ; change to an existing (small) file! ] p/data: 1.0 t/text: "Ready" ] t: text font-size 20 " " p: progress data 0.0 ]
start
button. It can be improved as below:view [ button "start" [ repeat i 159 [ p/data: (i / 159.0) wait 0.1 loop 5 [do-events/no-wait] ;-- let the View engine to process some events ] t/text: "Ready" ] t: text font-size 20 " " p: progress data 0.0 ]
view [ button "start" [ repeat i 2259 [ p/data: (i / 2259.0) w: read/lines %testing.red ; change to an existing (small) file! ] wait 0.1 loop 5 [do-events/no-wait] ;-- let the View engine to process some events t/text: "Ready" ] t: text font-size 20 " " p: progress data 0.0 ]
wait
in event code? I haven’t experimented with it yet, it was big no-no in Rebol, AFAIR.on-time
event.rate
, so also 0x0 sized faces, why not.x: base on-time [...]; anim here button "start" [x/rate: 10] button "stop" [x/rate: none]
i: 1 view [ at 0x0 x: base hidden on-time [ either i <= 15 [ w: read/lines %testing.red ; change to an existing (small) file! prin i print { } ; show it is working i: i + 1 p/data: (i / 15.0) ][ t/text: "Ready" ] ]; anim here button "start" [x/rate: 10] button "stop" [x/rate: none] t: text font-size 20 " " p: progress data 0.0 ]
wait 0.1
to simulate read ...
in your code, you don't need to use wait
. Also you should put do-event ...
inside your repeat
loop.scriptname-as-file: to file! system/options/args scriptname-as-string: to string! system/options/args probe scriptname-as-file probe scriptname-as-string
system/options/args
is of type string!
, so to string!
is not needed in your example. Moreover, to file!
can be replaced by as file!
.to-unix-path
is how I would name itto-red-file
. Furthermore, Red uses /
as separator for path elements, just like Unix, so to-red-file
is correct and OS-independent. The converse is called to-local-file
, which generates the OS-dependent form.to-integer #{B79CE5D3} == 3080512979
red>> to-integer #{B79CE5D3} == -1214454317
red>> to integer! to binary! parse #{B79CE5D3ABCD} [collect [4 [keep skip]] to end] == -1214454317
parse #{B79CE5D3ABCD} [copy number 4 bits to end]
collect
collects to block by default, but you can provide you own word to change behavior:red>> number: #{} == #{} red>> parse #{B79CE5D3ABCD} [collect into number [4 [keep skip]] to end] == true red>> number == #{B79CE5D3}
red>> parse #{B79CE5D3ABCD} [copy number 4 skip to end] == true red>> number == #{B79CE5D3}
mid: func [s start len][copy/part at s start len] ; like basic's midstring print to integer! mid #{B79CE5D3ABCD} 1 4 ; mid string start length
parse contents [thru #{030623E593} copy number 4 skip to end]
stylize
branch. Once @dockimbel accepts my stylize
PR, I will merge the changes back to master.λ red --cli --== Red 0.6.1 ==-- Type HELP for starting information. red>> about Red 0.6.1 - 28-Nov-2016/16:46:05-8:00 red>> expand-directives [print #either config/OS = 'Windows ["Windows"]["Unix"]] *** Preprocessor Error in #either *** Script Error: path config/OS is not valid for none! type *** Where: ??? λ $LASTEXITCODE 0
red>> expand-directives [print #either system/platform = 'Windows ["Windows"]["Unix"]] == [print "Windows"]
red>> about Red 0.6.1 - 22-Nov-2016/14:35:39 red>> expand-directives [print #either config/OS = 'Windows ["Windows"]["Unix"]] == [print "Windows"] red>> about Red 0.6.1 - 29-Nov-2016/11:59:47 red>> expand-directives [print #either config/OS = 'Windows ["Windows"]["Unix"]] *** Preprocessor Error in #either *** Script Error: path config/OS is not valid for none! type *** Where: ??? (halted)
s: "abc" if s = "def" [print "hoopla"]
strcmp()
or the safer strncmp()
).Plots
](https://github.com/JuliaLang/METADATA.jl/tree/metadata-v2/Plots) package, the structure is: Plots: [ versions: [ 0.0.1: [ requires: [dependencies list of packages] sha1 ] ... ] url : git://github.com/tbreloff/Plots.jl.git ]
stylize
pull request soon, so i can merge the improvements into master[(panel-background)]
[ok]
to do something.origin
optimal?ok:
and panel-background:
within the react facet?Red [ ] ok: [ button 100x33 "Ok"] field-demo: { text bold font-size 10 55x20 [(panel-background)] center "Name" field 80x20 "Enter Name" origin 0x50 Button 100x33 "Ok" origin 0x100 text font-size 10 bold "Keep me" radio "Public" radio "Private" } system/view/silent?: yes panel-background: maroon view [ title "Text entry" backdrop panel-background across source: area #13181E 410x300 no-border field-demo font [ name: "Consolas" size: 9 color: hex-to-rgb #9EBACB ] panel 400x300 panel-background react [ attempt/safer [face/pane: layout/tight/only load source/text] ] ]
[ok]
isn't used anywhere that I see, so I'm not sure what you tried with it. Also not sure how origin
can be optimal or not.[ok]
won't display when added to field-demo
Red[] Result: "Test" field1.Process: [ alert join "You typed: " Result: field1/text ] field1.Initialize: [do [field1/text: Result]] field1.Declare: compose/deep [ field1: field [(field1.Process)] (field1.Initialize) ] block: compose [ (field1.Declare) field field ] view layout (block)
[ok]
in field-demo:
I expect the code [ button 100x33 "Ok"]
to run and a new button with these facets to be displayed in panel
due to the react
function.field1.Declare: compose/deep [ field1: field [(field1.Process)] (field1.Initialize) ]
[(field1.Process)]
works with brackets and parenthesis, (field1.Initialize)
works fine with parenthesis only. I am trying to figure out the consistency of "code composition".panel-background: "#2C3339"
works withpanel-background:black
.ok
and making field-demo
a block instead of a string you load, does it work how you expect?Origin
is not for positioning individual items. Use at
for that. And you shouldn't need to set a precise offset for everything. Use across
and below
, space
and let VID align things for you as much as possible..
, it probably doesn't work like you think. You may want /
insteadbelow
, now it comes back :)view [below text "A" field text "B" field]
my-field/text
or my-list/data
) as contexts will be lost between each GUI rebuilt. You will need to always reduce
or compose
the code that acces these objects.[ok]
will not work as expected inside a string in your live-coding example. *Why* it doesn't work is the reason we suggest building simpler things first, and getting more familiar with when/where/how things are evaluated.compose/deep
before load
and use (ok)
Red [] ok: [ Button 100x33 "Ok"] field-demo: { text maroon yellow bold font-size 10 55x20 center "Name" field 80x20 origin 0x50 (ok) } system/view/silent?: yes panel-background: black view [ title "my text entry" backdrop black across source: area #13181E 410x300 no-border field-demo font [ name: "Consolas" size: 9 color: hex-to-rgb #9EBACB ] panel 400x300 panel-background react [ attempt/safer [face/pane: layout/tight/only compose/deep load source/text] ] ]
field1: field [(field1.Process)] (field1.Initialize)
on-click
field field-data on-enter [field-data: face/text]
on-enter [field-data: face/text]
how can I avoid repeat that code for each field?field-data
role within field field-data on-enter [field-data: face/text]
?field-data
is text which will be displayed in text field by default, and after you've entered something in that text field and clicked enter, this text will be saved in field-data
, though I may be wrong since I haven't test itfield
in VID DSL expects a word! as face/text
from reading face/text
description "Input text, read/write value."?face/text
description?style
for that:view [ style my-field: field red on-enter [probe face/text] my-field my-field my-field ]
random
.test_random: function [iterations][ count: 0 loop iterations [ if random 1.0 < .20 [count: count + 1] ] print to percent! (to float! count / to float! iterations) ]
iterations
I get what looks like a normal distribution centered on 50%. What am I doing wrong?red>> random 1.0 < .2 == false red>> random 1.0 < .2 == false red>> random 1.0 < .2 == true
<
and then randomif (random 1.0) < .20 [count: count + 1]
red>> random logic! *** Script Error: random does not allow datatype! for its value argument *** Where: random
Datatype! => A (Datatype!)
show
. For now updating the block causes text-list to remove the changed line from text-list facet.lines: 10 i: 0 block: [] repeat i lines [ append block append copy "line" i ] text-list-selected: 2 view [ below field on-enter [ poke block text-list-selected face/data probe block show tl ] tl: text-list data block on-create [ face/selected: text-list-selected ] on-change [ text-list-selected: face/selected print text-list-selected ] button "Quit" on-click [quit] ]
random
can become that dialect =)random
on a block! would require a refinement or something, to distinguish it from returning a randomized block.generate
function which operates only on datatype!
s would be useful as an inverse to parse
generate: func [ /random /limits /others] [...]
test
functionGenerate
. Good name @geekyi.image
, I removed generation of code and blocks allocation, now it just assigns to image directly, I turned off auto-sync0.5
and press two arrows button you will seex y
parse
audio
word, so probably yes :) : hz pi * 2 * t * sin ; 440 hz audio
fry
?bind
+ reduce
combination:red>> f1: func [x y block /local z] [bind block 'z] == func [x y block /local z][bind block 'z] red>> f1 1 2 [x y h] == [x y h] red>> reduce f1 1 2 [x y h] *** Script Error: y is not in the specified context *** Where: reduce
y
is not in the context?func
finishes-=== Red Compiler 0.6.1 ===- Compiling Z:\home\maxvel\rebol\gui\test.red ... Compiling libRedRT... ...compilation time : 1877 ms Compiling to native code... ...compilation time : 52844 ms ...linking time : 898 ms ...output file size : 792576 bytes ...output file : Z:\home\maxvel\rebol\libRedRT.dll *** Syntax Error: Missing matching ] *** line: 348 *** at: {[ stack: copy [] words: [ ; }