""
with this:>> b: ["one" "two" "three"] == ["one" "two" "three"] >> foreach i b [if find i "two" [take/part i length? i]] == none >> b == ["one" "" "three"]
>> b: ["one" "two" "three"] == ["one" "two" "three"] >> take b == "one" >> b == ["two" "three"]
""
?why
, but I don;t know how to take positionallytake/only
to exist?remove-each
. It's not about /only
, but about accessing the series, and how tricky that can be when you start removing items as you traverse forward.>> b: ["one" "two" "three"] == ["one" "two" "three"] >> forall b [if find b/1 "two" [remove b]] == ["three"] >> b == ["one" "three"] >> >> >> b: ["one" "two" "two" "three"] == ["one" "two" "two" "three"] >> forall b [if find b/1 "two" [remove b]] == none >> b == ["one" "two" "three"]
""
left in the blocks ? (See comment on gist)remove-each
is viable. It returns unset.take
will remove values from the series. If you remove all values from a series, you are left with an empty series.take/part i length? i
, which leaves me with ""
left in the series>> b: ["one" "two" "three"] == ["one" "two" "three"] >> forall b [if find b/1 "two" [remove b]] == ["three"] >> b == ["one" "three"]
remove-each
as suggestedremove-each
but it doesn't return a block of valuesremove/part b some-length
take/part i length? i
doesn't remove more than one "two"
also, it removes i
values where i is the length of the series, so in case of two
it removes three chars.>> x: ["one" "two" "three" "two"] == ["one" "two" "three" "two"] >> foreach i x [if find i "two" [take/part i length? i]] == "two" >> x == ["one" "" "three" ""]
>> x: ["one" "two" "three" "two"] == ["one" "two" "three" "two"] >> remove-each i x [i = "two"] >> x == ["one" "three"]
get-cards: func [from-hand to-hand kind][ foreach i from-hand [ if find i kind [ append to-hand take/part i length? i ] ] ]
>> x: ["one" "two" "three" "two"] == ["one" "two" "three" "two"] >> z: [] == [] >> foreach c collect [remove-each i x [all [i = "two" keep i]]][append z c] == ["two" "two"] >> z == ["two" "two"]
collect/into [code here] z
from-hand
, and to-hand
.b: ["one" "two" "three" "two"] collect [while [found: find b "two"] [keep take found]] ;== ["two" "two"] b ;== ["one" "three"]
b: ["hearts-one" "clubs-two" "hearts-three" "spades-two"] collect [forall b [if find b/1 "two" [keep take b b: back b]]] ;== ["clubs-two" "spades-two"] b ;== ["hearts-one" "hearts-three"]
remove-each-and-count: function [ "Like remove-each, but returns both modified series and count of removed items." 'word [word! block!] "Word or block of words to set each time" data [series!] "The series to traverse (modified)" body [block!] "Block to evaluate (return TRUE to remove)" ][ orig-ct: length? data remove-each :word data body reduce [data orig-ct - length? data] ] remove-each-and-count v [1 2 3 4 5] [odd? v] remove-each-and-count v [1 2 3 4 5 6 7 8 9 10] [odd? v]
; Is . better than _ as a placeholder for the current value? It maps ; to the concept of %. as a current directory, but _ looks like an ; empty space where something goes. filter: partition: function [ "Returns two blocks: items that pass the test, and those that don't" series [series!] test [any-function! block!] "Test (predicate) to perform on each value; must take one arg if a function; block implied arg is named ." /only "Return a single block of values that pass the test" ][ result: copy/deep [[][]] ; Convert block test to anonymous func if block? :test [ ;probe test: func either arg [compose [(arg)]][[.]] test test: func [.] test ] foreach value series [ ; `make logic!` is used, so zero test results become false. append/only pick result make logic! test :value :value ] either only [result/1][result] ] ;red>> filter [1 2 3 4 5 6 7] :even? ;== [[2 4 6] [1 3 5 7]] ;red>> filter [1 2 3 4 5 6 7] :odd? ;== [[1 3 5 7] [2 4 6] ;red>> filter/only [1 2 3 4 5 6 7] :odd? ;== [1 3 5 7] ;red>> filter [/only /dup 3] :refinement? ;== [[/only /dup] [3] ;>> filter [1 2 3 4 5 6 7] [odd? _] ;== [[1 3 5 7] [2 4 6]] ;>> filter [[1 2] [3 4] [6 6]] [odd? ./1] ;== [[[1 2] [3 4]] [[6 6]]]
take/only/with
exclude
?difference
?red/sandbox
test: func [a b][ c: a + b print c ] debug [test 1 2]
:word
and watch
command but I get the "Unknown command!" response like belw, at any time so far.debug> :a Unknown command! debug> watch :a Unknown command! debug> :word Unknown command!
chand phand fhand thand etc.
not as good. ;^)clear-show
wasn't clear to me on a first read.show-and-clear
. After I had a few multi word function names, I decided to have all parameters as one word, thus.... the chand, etchttp
-branch? I would like to try migrate my app to new Red version and http with timeout support is what I needview/options [] [menu: ["commands" ["bash" [call "bash"] "nano" [call "nano"]]]]
call
is a little whimsical at times, might require some helpformat
is coming soon, but a simple replace is your best option there for now.menu
docs for VID/View?call
is a little whimsical at times, might require some help(console-2021-12-31-2876:1940): Gtk-CRITICAL **: 18:30:38.759: gtk_menu_shell_insert: assertion 'GTK_IS_MENU_ITEM (child)' failed
view/options [] [menu: ["commands" ["bash" bash "nano" nano]] actors: object [on-menu: func [face event][call/show form event/picked]]]
call
returns the pid, but nothing is shown)call/console
works - bash is shown in the terminal, which blocks Red ofccall/show
is not implemented in GTK? (it was a contribution work, not really polished)loop 10 [i: copy [] loop 150 [append i to-char 15 + random 200] print i wait 1 ]
has a different behaviour on R2 than on Red. on R2 each line is written then the wait is done, on Red, all the line are written by the end of 10seccall
>> ? call USAGE: CALL cmd DESCRIPTION: Executes a shell command to run another process. CALL is a native! value. ARGUMENTS: cmd [string! file!] "A shell command or an executable file." REFINEMENTS: /wait => Runs command and waits for exit. /show => Force the display of system's shell window (Windows only). /console => Runs command with I/O redirected to console (CLI console only at present). /shell => Forces command to be run from shell. <-------
red
console>> system/console/prompt: "♥♥♥" == "♥♥♥" ♥♥♥oops *** Script Error: oops has no value *** Where: catch
view [button "print 2 things" [print 1 print 2]]
rm -f
, you're not going to hurt anything. >> view [button "print 2 things" [call/shell/console "echo 1" call/shell/console "echo 2"]] 1 2
Call
*can* be a little tricky, because there are a number of options and OS behaviors based on whether you're in GUI or CLI consoles, or a compiled app. Lots of moving parts, should it wait for a result, etc., so start simple and post your examples when you get stuck.button "button name" [call "something"] return
Seems the same. Return
is a layout command, kind of like a CR for the GUI, but directionally aware (across vs below).view [ button "print 2 things" [ call/shell/console "echo 1" ; command 1 call/shell/console "echo 2" ; command 2 ] ]
commands: [who ps df] view [ button "Run three commands" [ foreach c commands [ call/console form c ] ] ]
call/wait
for ensuring that all commands are correctly executed.commands: ["/usr/bin/xterm -e top -a" "another command" "etc"]
[]
? a blockcommands:
? a set-wordset 'commands ...
when evaluated> commands: [who ps df] > > view [ > button "Run three commands" [ > foreach c commands [ > call/console form c > ] > ] > ]
>> ? view USAGE: VIEW spec DESCRIPTION: Displays a window view from a layout block or from a window face. VIEW is a function! value.
view
is a function of one argumentview
) and 1 block c
in the above example stands for the item that is being touched at the time. delete
function only deletes a single file or an empty folder. How to delete a folder that is not empty?delete
every file firstglob
](https://gitlab.com/hiiamboris/red-mezz-warehouse/-/blob/master/glob.red), reverse
the result and then delete
every item using foreach
/deep
on delete
instead.foreach file reverse glob [delete file]
delete-dir
function from Rebol:delete-dir: function [ {Deletes a directory including all files and subdirectories.} path [file!] ][ try [ if all [ dir? path ;@@ does not actually checks, if it is a real dir exists? path block? files: read path ] [ foreach file files [delete-dir path/:file] ] delete path ] ]
USAGE:
OPEN port
DESCRIPTION:
Opens a port; makes a new port from a specification if necessary.
OPEN is an action! value.
ARGUMENTS:
port [port! file! url! block!]
file://
>> >> write-clipboard ["one" "two" "three"] == true >> c: read-clipboard == [%one %two %three] >> type? c/1 == file! >>
alt+space->E->P
for the CLI console. If we don't have a ticket for that, we can see what @qtxie thinks.write-clipboard
, pasting into the CLI console doesn't work at all. Definitely worth a ticket if we don't have one already.form
it first. If it's a block, to try and be helpful, the platform code treats it as a block of files, for CF_HDROP/DROPFILES compatibility. We need to doc it beyond having this comment in the code. write-clipboard
, pasting into the CLI console doesn't work at all. Definitely worth a ticket if we don't have one already.write-clipboard
files then CLI console doesn't paste anything though. But that's expected, because it's OS who does the paste, not the CLI console.write-clipboard
is used with a block, which lines up with what @semarie says and what the code looks like. What happens is that the CF_HDROP format is probably not supported, i.e. converted to plain text, when the OS tries to paste into the CLI console.write-clipboard [a b c]
? We have https://github.com/red/red/issues/4331 for that case already.file!
values, it's just text or an image, and if we want to move data between Red apps, we just load
it if it's text.write-clipboard
itself, but this should be fixed by nowsystem/words
object, all words exists even if they do not exists. They are created when you check for their existence. >> in system/words 'gggg == gggg >> in make object! [aaaa: 1] 'gggg == none
system/words
without creating it?>> unset? 'gggg == false >> value? 'gggg == false >> gggg: true == true >> value? 'gggg == true
value?
is the solutionif unset? get/any 'gghd [print off]
unset?
might be hazardous, but I can't recall why because it works. maybe it goes away some day?value?
IMO is more hazardous as it's easy to misuse:>> value? in object [] 'x == true >> value? 'nonexisting/path == true
word-exists?: func [word [word!] /in obj [object!]][ either all [in not same? obj system/words] [ not none? system/words/in obj word ][ value? word ] ]
word-exists?: :value?
:^)book-check: func [hand] [ foreach book books [ counter: 0 record: [] repeat card-numb probe length? hand [ if (first hand/:card-numb) = book [ counter: counter + 1 append/only record hand/:card-numb ]] if counter = 4 [hand: exclude hand record] ;not being set globally ] ] obh: [["a" 0] ["a" 1] ["q" 0] ["a" 2] ["a" 3]] book-check obh probe obh
[["q" 0]]
, but this isn't being set globally to obh. books
data?>> f: func ['word][ ? word ? :word set :word random 100 ] num: 0 f num WORD is a word! value: num NUM is an integer! value: 0 == 13 >> num == 13
["a" "2" "3" "4" "5" "6" "7" "8" "9" "10" "j" "q" "k"]
book-check: function ['hand] [ data: get/any :hand foreach book books [ counter: 0 record: clear [] repeat card-numb probe length? data [ if (first data/:card-numb) = book [ counter: counter + 1 append/only record data/:card-numb ]] if counter = 4 [data: exclude data record] ;not being set globally ] set :hand data ]
get
is good as well./any => If word has no value, return UNSET rather than causing an error.
length? :hand
not work?*** Script Error: length? does not allow word! for its series argument
books: ["a" "2" "3" "4" "5" "6" "7" "8" "9" "10" "j" "q" "k"] book-check: function [hand] [ foreach book books [ counter: 0 record: [] repeat card-numb probe length? hand [ if (first hand/:card-numb) = book [ counter: counter + 1 append/only record hand/:card-numb ]] if counter = 4 [hand: exclude hand record] ;not being set globally ] hand ] obh: [["a" 0] ["a" 1] ["q" 0] ["a" 2] ["a" 3]] obh: book-check obh probe obh
obh: book-check obh
is changing.return
is not explicitly used.books: ["a" "2" "3" "4" "5" "6" "7" "8" "9" "10" "j" "q" "k"] book-check: function [hand] [ foreach book books [ counter: 0 record: copy [] repeat card-numb probe length? hand [ if (first hand/:card-numb) = book [ counter: counter + 1 append/only record hand/:card-numb ]] if counter = 4 [result: exclude hand record insert clear hand result] ; a little bit cryptic :-) ] ] obh: [["a" 0] ["a" 1] ["q" 0] ["a" 2] ["a" 3]] book-check obh probe obh
exclude
creates a new series.book-check: function [hand] [ foreach book books [ counter: 0 record: copy [] repeat card-numb probe length? hand [ if (first hand/:card-numb) = book [ counter: counter + 1 append/only record hand/:card-numb ]] if counter = 4 [return exclude hand record] ] ] obh: [["a" 0] ["a" 1] ["q" 0] ["a" 2] ["a" 3]] obh: book-check obh probe obh
hand
to 'hand
in the func spec. We call this lit-arg
syntax, and it's an advanced feature. With great power... :^) record: []
use record: copy []
instead!>> f: func[v][blk: [] append blk v] f 1 == [1] >> source f f: func [v][blk: [1] append blk v] >> f "persistent in the function source!" == [1 "persistent in the function source!"] >> source f f: func [v][blk: [1 "persistent in the function source!"] append blk v]
copy
, it's fundamental to the design, and the fact that Red is a data language first and foremost. Same with not having keywords. We *could* change these rules, but then Red would be a very different language, and lose many of its benefits compared to others. In many cases it's just getting used to how things work, until they seem natural.record: []
not actually do anything after the first time?*.red
doesn't seem like it's working as designed? record: []
not actually do anything after the first time?do
. ;^) It's just two values, a set-word and a block. When Red *evaluates* them, it sees the set-word and says "Whatever comes next, I'll set this word to refer to that, kind of like a variable." Then it sees the block and says "This is a block. It's empty, so I don't need to allocate slots for values it 'contains', and I'm done." With the block evaluation done, record
can be set to refer to it.test: [1 2 3 4]
>> foreach t test [ [ probe record: [] append record "a"] [] ["a"] ["a" "a"] ["a" "a" "a"] == ["a" "a" "a" "a"] >>
>> foreach t test [ [ probe record: ["b"] append record "a"] ["b"] ["b" "a"] ["b" "a" "a"] ["b" "a" "a" "a"] == ["b" "a" "a" "a" "a"]
>> test: [1 2 3 4] == [1 2 3 4] >> foreach t test [ [ append record "a"] *** Script Error: record has no value *** Where: either *** Near : record "a" *** Stack:
copy
. If you want to do something more advanced, you can assign another word to an existing block or string, but both those words are simply pointers to the same memory structure.integer!
or decimal!
datatypes. All datatypes have their own set of rules. For instance, if you add an integer! to a date!, should that add to the year, month, or day? In Redbol languages, it adds to the day.record
example). When you use a set-word, it doesn't do that, and in the special global context, adds an entry for that word. Normal contexts (objects) can't be extended right now, their words are set when they are created.'record
. This is called a lit-word. When evaluated, they return themselves rather than what that word refers to. That's where get
can be used, as sometimes words are used indirectly. Sounds advanced, again, but isn't in most cases. scalar
category, which subsumes number
and that contains [integer float percent]
. We call these categories typesets
. Blocks, strings, and more fall under series
. Even at the bottom though, integers for example, are values with a common internal structure (and overhead). Some types can contain their entire content in that structure, while others need to store it elsewhere. e.g. an int is small and fits, but series vary in size and may be huge.fexprs
vs sexprs
, others might talk about thunks
, but we can keep it simple. In most langs, code is evaluated when compiled, or interpreted. And that code is fixed. If you want added flexibility, you have to build it yourself. For example, let's say you have a switch
statement in your code:while [not empty? str: ask "What say you? "][ print switch str [ "Hello" ["Howdy"] "Bye" ["Later"] ] ]
chat-map: [ "Hello" ["Howdy"] "Bye" ["Later"] "What?!" ["Yeah, that's right"] ] while [not empty? str: ask "What say you? "][ print switch str chat-map ]
data-ranges
is data, and that other funcs operate at the data structure level, returning a rich structure rather than having separate functions for every possible value variation. I just noticed that this is so old it needs a fix, as it predates the change when /
used to return an integer, but now returns a float.The Benefits of Code as Data
or something along those lines.>>> a = [1, 2, 3] >>> a = [4, 5, 6] >>> a [1, 2, 3, 4, 5, 6]
>> r: [1 2 3] == [1 2 3] >> r: [4 5 6] == [4 5 6] >> r == [4 5 6]
>>> a = [1, 2, 3] >>> a = [4, 5, 6]
=
append, or does that mean that the first one also appends, but to an invisible array I never see?r: copy []
, but only in the context of loops, is a little annoying. >> r: [1] == [1] >> r: [] == [] >> r == []
r: a: [1] ; R and A both refer to this block r: b: [] ; R now refers to this one, as does B r a b same? a b same? r a same? r b append b 2 r append c: copy b 3 ; C refers to a NEW block, which is a copy of B. r same? b c
>> r: [] == [] >> loop 3 [r: [] append r 3] == [3 3 3]
>> r: [] == [] >> append r 3 == [3] >> r: [] == [] >> append r 3 == [3] >> r: [] == [] >> append r 3 == [3] >> r == [3]
r
inside the loop
call is the same one for every append
call. You haven't changed it to a new reference. In the second example, you set r
to refer to a new and different block every time you do r: []
.r: []
behaves differently inside a loop, because loop's instructions are inside a "block"?r
no longer refers to them. You can still access them though.foreach val code [print mold val] code/2 ; etc.
bind
and contexts yet. ;^)?? loop loop: make native! [[ "Evaluates body a number of times" count [integer! float!] body [block!] ]]
>> do [r: [] append r 3] == [3] >> do [r: [] append r 3] == [3] >> do [r: [] append r 3]
f: func [][r: probe [] repeat i 5 [ append r i probe r ]] f f
code
example.code: [ do [r: [] append r 3] do [r: [] append r 3] do [r: [] append r 3] ] do code print mold code
loop 3 blk: [r: [] append r 3 print mold blk] loop 3 blk: [r: [] append blk/2 3 print mold blk]
r
isn't needed at all.loop 3 blk: [[] append blk/1 3 print mold blk]
blk
to refer to it, but that's incidental to how it works. It shows that setting a word to refer to something does not affect the thing it refers to.why you have to copy
wiki page.When evaluated, it binds the word to the result of next expression. It doesn't do anything more than that. So a: "" does not "reset" or "reinitialize" the "variable" a. That is an incorrect interpretation, it just makes the word a refer to the literal string "" which follows it.
f: func [][r: [] repeat i 5 [ append r i probe r ]] f f
, r: []
doesn't actually make r refer to an empty series f: func [][r: 89 r:[] repeat i 5 [ append r i probe r ]] f f
does the same thing in the end. So I guess series are just never destroyed no matter what. >> f: func [][r:[] repeat i 5 [ append r i probe r] r: 89] == func [][r: [] repeat i 5 [append r i probe r] r: 89] >> f [1] [1 2] [1 2 3] [1 2 3 4] [1 2 3 4 5] == 89 >> f [1 2 3 4 5 1] [1 2 3 4 5 1 2] [1 2 3 4 5 1 2 3] [1 2 3 4 5 1 2 3 4] [1 2 3 4 5 1 2 3 4 5] == 89
>> f: func [][r:[] repeat i 5 [ append r i probe r] r: 89] == func [][r: [] repeat i 5 [append r i probe r] r: 89] >> print mold body-of :f [r: [] repeat i 5 [append r i probe r] r: 89] >> f [1] [1 2] [1 2 3] [1 2 3 4] [1 2 3 4 5] == 89 >> f [1 2 3 4 5 1] [1 2 3 4 5 1 2] [1 2 3 4 5 1 2 3] [1 2 3 4 5 1 2 3 4] [1 2 3 4 5 1 2 3 4 5] == 89 >> print mold body-of :f [r: [1 2 3 4 5 1 2 3 4 5] repeat i 5 [append r i probe r] r: 89] >> f: func [][r: copy [] repeat i 5 [ append r i probe r ]] f f [1] [1 2] [1 2 3] [1 2 3 4] [1 2 3 4 5] [1] [1 2] [1 2 3] [1 2 3 4] [1 2 3 4 5] == [1 2 3 4 5] >> print mold body-of :f [r: copy [] repeat i 5 [append r i probe r]]
probe
between most statements to see what is happening, it passes values through>> f: func [][probe r: "a" probe r:[] repeat i 5 [ append probe r i] probe r: 89] == func [][probe r: "a" probe r: [] repeat i 5 [append probe r i] probe r: 89] >> f "a" [] [] [1] [1 2] [1 2 3] [1 2 3 4] 89 == 89 >> f "a" [1 2 3 4 5] [1 2 3 4 5] [1 2 3 4 5 1] [1 2 3 4 5 1 2] [1 2 3 4 5 1 2 3] [1 2 3 4 5 1 2 3 4] 89 == 89
>> f: func [][probe r: [] repeat i 5 [append r (i * -1)] probe r:[] repeat i 5 [ append r i]] == func [][probe r: [] repeat i 5 [append r (i * -1)] probe r: [] repeat i 5 [append r i]] >> f [] [] == [1 2 3 4 5] >> f [-1 -2 -3 -4 -5] [1 2 3 4 5] == [1 2 3 4 5 1 2 3 4 5] >> f [-1 -2 -3 -4 -5 -1 -2 -3 -4 -5] [1 2 3 4 5 1 2 3 4 5] == [1 2 3 4 5 1 2 3 4 5 1 2 3 4 5]
>>> none = [] == false
none
and false/off/no
. We have empty?
to ask about emptiness. source
.[]
to compare to an empty block, but that's not as meaningful.append
or insert
. Which leads me to the following - one of the most important aspect of Redbol languages, is a concept of series. There is still Rebol Core documentation, which I would suggest you reading this chapter - http://www.rebol.com/docs/core23/rebolcore-6.html>> code: [print [1 2 3]] == [print [1 2 3]] >> code/1 == print >> first code == print >> code/2/3 == 3 >> at code 2 == [[1 2 3]] >> sort copy code == [[1 2 3] print] >> insert code "before" == [print [1 2 3]] >> append code "behind" == ["before" print [1 2 3] "behind"] >> remove back tail code == [] >> code == ["before" print [1 2 3]] >> remove head code == [print [1 2 3]] >> do code 1 2 3
;-- empty block in a function >> test: func [value][c: [] append c value] == func [value][c: [] append c value] >> test 1 == [1] >> c == [1] >> test 2 == [1 2] >> c == [1 2] ;-- empty block in a console >> d: [] == [] >> append d 1 == [1] >> d: [] == [] >> append d 2 == [2] >> d == [2]
>> c: context [b: [] f: func[v][append b v]] == make object! [ b: [] f: func [v][append b v] ] >> c/f 1 == [1] >> c/f 2 == [1 2] >> c == make object! [ b: [1 2] f: func [v][append b v] ]
>> f: func[v][ print ["The Value is:" v] ] == func [v][print ["The Value is:" v]] >> f 1 The Value is: 1
["The Value is:" v]
and copy of string "The Value is:"
every time, when you call the function.record: clear []
instead of record: copy []
. Using the clear
has the advantage, that you re-use already created series (no allocation), but you still start with empty record. You just have to be careful not to return the value from the function, because next run of the function always clears it.search-metadata.json
you list them with an *alias* e.g. "[profile]/mal.xml":{"alias":"a"}
. Now entering a term
in the URL bar will perform MAL search for term
. I think Opera must have smth like this too (in fact the idea likely originated from Opera back in it's better days, though idk if it survived the switch to Chromium).request
, and book-check doesn't seem to work despite working on its own when I tested it. until
. See what results are getting back to it, and maybe add a counter to break after N repetitions so it stops and lets you see if it always freezes after the same number of iterations, or different counts. Then remove randomness. Seed it with a known value and you should see consistent behavior. Look for a seed that makes it freeze, and then analyze the state of things to see where it goes wrong.search (choice: request) human_hand ]
until
blocks. "In first until", "In second until".until [ ;probe human_hand trace search (choice: request) human_hand ]
do/trace choice etc
or probe choice
to see what it returnsuntil
evaluates a body until it is truthy.until
, and what your expressions return when you use them there.print human_hand
in the until loops, and it's not empty probe choice
this is the output around when the freezing starts, Computer's choice: 10 Computer's choice: 4 Go Fish Remaining Books: a 2 3 4 5 6 7 8 9 10 j q k Your hand: q♥ j♥ 5♠ 5♦ j♠ 3♦ 2♦ k♣ 8♥ 3♠ q♣ k♦ "10" "10" "10" "10" "10" "10" "10" "10" "10" "10" "10" "10" "10" "10" "10" "10" "10" "10" "10" "10" "10" "10" "10" "10" .....................
Computer's choice: 9 Computer's choice: 6 Go Fish Remaining Books: a 2 3 4 5 6 7 8 9 10 j q k Your hand: 5♦ k♦ k♣ q♥ 7♠ 7♥ k♠ 8♦ 5♥ 3♠ 2♣ 8♥ "9" "9" "9" ...
because an included file isn't in the repo.
what do you mean by that? #include %pc.red
From https://rosettacode.org/wiki/Playing_cards#Red ... commentsuntil [ probe human_hand search (choice: request) human_hand ]
context
is often usedtext
has no meaning, but you can use the word in the contexts of VID
and draw
, each of which do different things. Here they are just symbols, but the idea holds that the same word can have a different meaning in different contexts.>> text *** Script Error: text has no value *** Where: set *** Near : text *** Stack: >> view [text "Hello!" base 300x100 white draw [text 20x40 "Different meaning here."]]
VID
or draw
is tailored to each context.text
meaning different things in different "contexts" create uniquely Red effects?text-face
and draw-text
to disambiguate them, with the naming explosion that goes along with that approach. Instead, you build a vocabulary and write expressions, much like we write sentences in natural language, to say what you mean as clearly as possible. This is where [rock rock rock rock]
says *why*, but isn't as helpful on the intent side. VID
or draw
in Python. Doesn't have to generate output, just recognize the input such that work could be done with it. A small subset will do, as they are large dialects.eval
c: context compose/deep [ draw: function [] [ view [ image 200x200 ( draw 100x100 [translate 50x50 rotate 45 line-width 10 pen gold box -40x-40 40x40] ) draw [pen off draw: fill-pen cyan circle 100x100 70] rate 5 on-time [draw/2: random cyan] ] ] ] c/draw
>> storage: [] == [] >> l1: function [] [a: 0 b: 0 c: 0] == func [][a: 0 b: 0 c: 0] >> l2: function [] [a: 1 b: 1 c: 1] == func [][a: 1 b: 1 c: 1] >> l3: function [] [a: 2 b: 2 c: 2] == func [][a: 2 b: 2 c: 2] >> append storage [bind 'a context l3 bind 'b context l2 bind 'c context l1] == [bind 'a context l3 bind 'b context l2 bind 'c context l3] >> reduce storage *** Script Error: context does not allow integer! for its spec argument *** Where: context *** Near : 2 *** Stack: context
a:2: 4
==: >>: none
now you can copy & paste examples*** Script Error: context does not allow integer! for its spec argument *** Where: context *** Near : 2 *** Stack: context
context l3
first evaluates l3 and returns an integer context 'l3
?*** Script Error: context does not allow word! for its spec argument *** Where: context *** Near : 'l3 bind 'b context 'l2 bind 'c context *** Stack: context
? context?
>> storage: clear [] >> append storage [bind 'a context context? 'l3 bind 'b context context? 'l2 bind 'c context context? 'l1] >> reduce storage *** Script Error: context does not allow object! for its spec argument *** Where: context *** Near : 'l3 bind 'b context context? 'l2 bind 'c *** Stack: context
The word context is a shorter form of make object!.
Well, what about when the object is already made?context
?>> storage: clear [] >> append storage [bind 'a context? 'l3 bind 'b context? 'l2 bind 'c context? 'l1] >> reduce storage == [a b c]
>> reduce make block! storage == [a b c] >> storage == [bind 'a context? 'l3 bind 'b context? 'l2 bind 'c context? 'l1]
L3
was an object, not a function. Not sure what you're trying to do, but I'm working on other things ATM.a
, b
and c
using bind such that the result is [2 1 0]
rural-park
in append rocks bind 'rock rural-park: context [rock: "mineral"]
, I want to use a context I made elsewhere, specifically a function's context. context? 'l3
returnbind
. It's one of the most advanced aspects of Red. bind
. :^)func
and function
, and how to control what's local and what's external to a function. This will lead you to set
vs set-word syntax, and you're on your way./extern
? https://www.red-by-example.org/#function uses the term global scope
, but Red does not have not have such a thing. Should global scope
be replaced with top-level context
?system context
is a good way to think of it. Kind of in between the two.system
. :^)>> context? 'l3 == make object! [ datatype!: datatype! unset!: unset! none!: none! logic!: logic! block!:...
print [mold spec-of :l3 mold body-of :l3]
print [mold spec-of :l3 mold body-of :l3]
is less so. Not sure what to make of it though. >> print [mold spec-of :l3 mold body-of :l3] [/local a b c] [a: 2 b: 2 c: 2]
>> f1: context function [] [a: 0 b: 0 c: 0] *** Script Error: context does not allow function! for its spec argument
>> f1: function [] [a: 0 b: 0 c: 0] == func [/local a b c][a: 0 b: 0 c: 0] >> object? f1 == false
Binding is quite a simple concept, I'm still puzzled why people fail to grasp it.
bind
for the same reason you're struggling with a lot of things right now. We're all different.>> f: function [] [a: 1] >> function? :f == true
>> storage: [] >> l1: function [] [a: 0 b: 0 c: 0] >> l2: function [] [a: 1 b: 1 c: 1] >> l3: function [] [a: 2 b: 2 c: 2] >> append storage [bind 'a :l3 bind 'b :l2 bind 'c :l1] >> reduce storage == [a b c] >> reduce reduce storage *** Script Error: context for b is not available
X
, it only makes sense you'd be able to Y
system
context is special in some ways. Red aims to be consistent, but not to the exclusion of things making sense in other ways. And sometimes consistency in one way contradicts consistency in another. reduce storage
?>> storage: [] >> o1: context [a: 0 b: 0 c: 0] >> o2: context [a: 1 b: 1 c: 1] >> o3: context [a: 2 b: 2 c: 2] >> append storage [bind 'a :o3 bind 'b :o2 bind 'c :o1] >> reduce reduce storage == [2 1 0]
[a b c]
it seemscontext?
and then get error that context is not available
, there's some contradiction, don't you think?context?
gives you a value (object!
or a function!
) that refers to internal context!
value. object!
's context are allocated on the heap and are present during whole lifetime of a script (or until next GC sweep). function!
's contexts come and go to/from call stack together with function calls.So functions's context and object's context, are somehow different.
looks like I was right storage3: [] sf: function [] [a: [1] append a 2] append storage3 [bind 'a :sf] reduce storage3
a
in sf
is within sf
's context, yet every time sf
is called, a
changes value. Nonetheless, a
's value cannot be accessed through storage3. Maaaaaaybe, a
in sf
points to somewhere else, where its value is stored, but only during a function call. So sf
kind of opens communications during a function call, and after, communications are closed. Inside the function! value, the spec and body blocks are still there, and they are still data.
function's contexts are mapped on call stack during function call, and disappear once function is evaluated
help
myself from *trying* to help
you, so...play...in the console...with *small, easy* bits of code. *Learn* how collect
works. It's pretty cool, and very useful. You won't learn if you don't try.context
and bind
even exist. You're trying to dive deep and you can't even swim. context?
not returning a logic value? I would so much prefer context-of
instead. Well, but then we've got index?
and other functions too ...append storage reduce [bind 'a :o1]
self
too, but it might have a different meaning. We can't extend objects, while R3 can, etc.help collect
doesn't really explain how keep
works. Right now, all I know is that if you already have a block with keep
inside of it, collect
will "keep" those. Not too useful. keep
is only in collect
's context. Can help be used for things not in the global context
?>> ?? collect collect: func [ {Collect in a new block all the values passed to KEEP function from the body block} body [block!] "Block to evaluate" /into {Insert into a buffer instead (returns position after insert)} collected [series!] "The buffer series (modified)" /local keep rule pos ][ keep: func [v /only] [either only [append/only collected v] [append collected v] v] unless collected [collected: make block! 16] parse body rule: [ any [pos: ['keep | 'collected] (pos/1: bind pos/1 'keep) | any-string! | binary! | into rule | skip] ] do body either into [collected] [head collected] ]
keep
has no all
refinement. The example in red/red though, uses keep/all
.helpin
collect's context like so:
collect [help keep]. However, the help this gets you is a bit disappointing. At least it points you to the
/onlyrefinement
keephas, a secret which
collectkeeps very well (pun intended).
keep/only
. Maybe I remembered wrong. collect [help keep]
is a clever trick. I guess that help string should be added to the internal keep
function.collect
.collect
help collect
do
, until
, foreach
, ...#modifies
and #evaluates
or something like that so it would be easier to see what you can expect.>> ? collect ... ARGUMENTS: body [block!] "Block to EVALUATE." ...
pure-function
that wraps function
and makes a copy of non-scalar arguments. I.e. myfunc: pure-function [a b ] [ ...]
l3: function [] [a: 2 b: 2 c: 2] set 'blk body-of :l3 blk/c: 99 >> :l3 == func [/local a b c][a: 2 b: 2 c: 99] >> l3 == 99 >> clear spec-of :l3 == [] >> :l3 == func [][a: 2 b: 2 c: 99] clear blk change blk [dir] ;-- now what does l3 do?
l3
as a name, because it looks like 13
. The other thing I'll note is that advanced coding patterns may trip up the compiler, so if you want to compile your apps (remember encap
is your friend here), keep it simple.>> f: function [] [a: 2 b: 2 c: 2] == func [/local a b c][a: 2 b: 2 c: 2] >> clear spec-of :f == [] >> f == 2
function
evaluates to a func
with the \local
refinement. f
still works after clearing its spec though. f
doesn't rebind f's body to a new function context, so a
, b
, c
are still bound to the original context of f
. You can check with keys-of :f ;== [local a b c]
. Therefore, even after clearing the spec, f
doesn't set a
in the global context: >> f == 2 >> a *** Script Error: a has no value
>> a: 9 == 9 >> f: function [] [a: 2] == func [/local a][a: 2] >> clear spec-of :f == [] >> ?? f f: func [][a: 2] >> f == 2 >> a == 9 >> f2: func [] [a: 2] == func [][a: 2] >> f2 == 2 >> a == 2
f
's spec is cleared, it's the same as f2
, yet its effect on a
in the global context isn't the same.>> keys-of :f == [local a b c] >> keys-of :f2 == []
key
and spec
is kind of oddl3
's spec actually didn't need to be cleared. >> con: context [a: 5] == make object! [ a: 5 ] >> keys-of con == [a] >> a *** Script Error: a has no value
>> spec-of con *** Internal Error: reserved for future use (or not yet implemented)
>> reflect con 'body == [ a: 5 ] >> reflect con 'spec *** Internal Error: reserved for future use (or not yet implemented)
f2
example function
seems to be "represented" by func
's with /local
, judging by the output of writing a function
in the repl>> f: function [] [a: 2 b: 2 c: 2] == func [/local a b c][a: 2 b: 2 c: 2]
f
is still different than a func
with a /local
refinement, shouldn't that say something different? function
collects /local for you>> keys-of :f2 == [local a]
>> f2: func [/local a][a: 1] == func [/local a][a: 1] >> a: 9 == 9 >> f2 == 1 >> a == 9 >> clear spec-of :f2 == [] >> f2: do load mold/only :f2 == func [][a: 1] >> a == 9 >> f2 == 1 >> a == 1
load mold/only
necessary?>> mold/only :f2 == "func [][a: 1]" >> load mold/only :f2 == [func [] [a: 1]] >> do load mold/only :f2 == func [][a: 1] >> a == 9 >> do :f2 == func [][a: 1]
f2
, so you got to "remake" f2 in a two step process?letters: charset [#"a" - #"z" #"A" - #"Z"]
mold/load
is buggy/unfinished in Red...>> str: mold/all :f2 == "func [/local a][a: 1]" >> blk: load/all str == [func [/local a] [a: 1]] >> type? first blk == word! ;<--- it is not function loaded.. so you must first reduce/do the blk
>> str: mold/all :f2 == "#[function! [[/local a][a: 1]]]" >> blk: load/all str == [make function! [[/local a][a: 1]]] >> type? first blk == function! ;<--- you already have the function in the blk
cyrillic-letters: charset [#"^(0410)" - #"^(042F)" #"^(0430)" - #"^(044F)"] parse "Чаи" [some cyrillic-letters] ;<== true
clear spec-of :f2
I consider as a security issue, while others think that it is a _feature_.secure
dialect at least in the state like it was in Rebol2. But here is not right place for such a talk (and I don't want to have it). I just think, that have modifiable access to function internals is a path to problems instead of something useful.union
, or lesser used data types, can always be looked up later, so are less important. clear
, so when they inevitably do, it WILL trip them up and that WILL frustrate them. Avoiding that situation in the first place would a be a good thing I think. copy
wiki page.clear
(or copy
) is necessary. Being relegated to some buried wiki page is not optimal. mold
works differently in Red. And people will question if it wouldn't be easier to just use R2 or R3. >> f: function [hand] [hand: exclude hand [2]] == func [hand][hand: exclude hand [2]] >> f a == [1 3] >> a == [1 2 3] >> f: function [hand] [append hand 9] == func [hand][append hand 9] >> f a == [1 2 3 9] >> a == [1 2 3 9]
>> a: [0] == [0] >> f: function [series] [series/1: series/1 + 1] == func [series][series/1: series/1 + 1] >> f a == 1 >> a == [1]
>> a: [1 2 3] == [1 2 3] >> f: function [hand] [:hand: exclude hand [2]] *** Syntax Error: (line 1) invalid word at :hand: exclude hand [2]] *** Where: set *** Near : :delimiter-lex *** Stack: load
hand
?>> f: function [hand] [head clear insert hand exclude hand [2]] == func [hand][head clear insert hand exclude hand [2]] >> a: [1 2 3] == [1 2 3] >> f a == [1 3] >> a == [1 3]
hand
is applicable, that is.head clear
do?Help
!hand
itself isn't positioned at it's head? Then above f
gives wrong result, a better solution would be:>> a: next [0 1 2 3 4] ;== [1 2 3 4] >> f: function [hand] [clear insert hand exclude hand [2] hand] () >> f a ;== [1 3 4] >> a ;== [1 3 4] >> head a; == [0 1 3 4]
Help
! And *play*. In the console, define a block, and see how each series action it supports work. Use help action!
for a list of all actions (not just series related). Take functions out of the equation entirely. Learn how words work. How does each form behave, why does get-word!
even exist?help
in the Red console. do
ithelp
. For everyone's long term benefit, we will help new people started, but very quickly encourage them to become more self-sufficient. If you get into the habit of asking for answers every time, rather than trying to *find* them yourself, you'll get less and less answers over time. Help us to help you, by making the best use of our time.ask -> try -> think
pattern looks like a parenting issue to me. If you immediately give your child all the answers and do not encourage it to play or give time to come with own answers, eventually this way of learning prevails over the others and becomes a life habit. One that is not particularly useful anymore, but gets repeated automatically. A huge share of our behavior is defined this way unless we consciously reprogram ourselves.head clear insert hand exclude hand record
code golf line into your script is neither walking nor running, its just rushing. In the context of your script head
is totally superfluous, because you're not using the position it returns anywhere.>> a: [1 2 3] >> f: function [hand] [clear insert hand exclude hand [2]] >> f a == [] >> a == [1 3]
a
clear
is so this doesn't happen>> f a == [1 2 3] >> a == [1 3 1 2 3]
exclude hand [2]
is [1 3]
, which you insert to the hand, so you get [1 3 1 2 3]
, but insert returns result at tail, so you clear the [1 2 3]
part and see empty block.. but at tail... and a
is [1 3]
>> f: function [hand] [probe head probe clear probe insert probe hand probe exclude hand [2]] >> f a: [1 2 3] [1 2 3] [1 3] [1 2 3] [] [1 3] == [1 3]
>> trace/all/deep [f a] a => [1 2 3] hand => [1 2 3] hand => [1 2 3] exclude hand [2] => [1 3] insert hand [1 3] => [1 2 3] clear [] => [] head [] => [1 3] f a => [1 3] == [1 3]
clear []
trace
, right, not merged yet?f
from here, so got extra output. >> a: [1 2] insert a 0 == [1 2] >> a == [0 1 2] >> a: [1 2] append a 0 == [1 2 0] >> a == [1 2 0]
b: ["one" "two" "three"] view [drop-down 250 data b]
Red [
title: "Multiple View test"
needs: 'view
]
Vit_Min: [A B C D E K Iron Magnesium]
Vit_Min_Units: [gram mg]
view [
Button 60x18 "Quit" [quit] return
p: panel white [ size 300x300
Text "Stuff Test" return
drop-down 120 data Vit_Min
drop-down 100 data Vit_Min_Units
]
]
do https://gist.githubusercontent.com/gurzgri/f09b8b78e96cd1d876d38ae7a64b8c96/raw/bd02e1c20562cd96315527ec49cd57f6f93ee790/gofish.red
Red [ title: "Drop-down test" needs: 'view ] Vit_Min: ["A" "B" "C" "D" "E" "K" "Iron" "Magnesium"] view [ Button 60x18 "Quit" [quit] return V_M: drop-down 120 data Vit_Min button 60x30 green "Add" [V_M_List/data: pick V_M/data V_M/selected] return V_M_List: text-list 140x140 data ["hi" "there"] ]
[ V_M_List/data: pick V_M/data V_M/selected]
[?? V_M_List/data V_M_List/data: pick V_M/data V_M/selected ?? V_M_List/data]
probe
or ??
your V_M/data
and V_M/selected
. Then help pick
in the console. You'll find out what's going on. view [drop-down data ["aa" "bb"] select 1 rate 2 on-time [probe face/selected]]
/BuildRoot/Library/Caches/com.apple.xbs/Sources/AppleFSCompression/AppleFSCompression-96.200.3/Common/ChunkCompression.cpp:49: Error: unsupported compressor 8 /BuildRoot/Library/Caches/com.apple.xbs/Sources/AppleFSCompression/AppleFSCompression-96.200.3/Libraries/CompressData/CompressData.c:353: Error: Unknown compression scheme encountered for file '/System/Library/LinguisticData/Latn/Dict2.dat' 1x2 1x2 1x2
collect
ing. I really like how reverse
is used. game/:player/hand
just make things so much more accessible than having each and every "thing" in it's own word (i.e. "variable"), help in tidying things up and allow for way easier debugging. In my script, I can easily probe game
where ever I want and see the whole application state. collect
isn't idiomatic per se, it's just that I love it so much. Many things you can collect
you can gain by remove-each
their complement:remove-each card copy hand [not same? rank rank-of card]
collect [foreach card hand [same? rank rank-of card]]
collect
, you can e.g. wrap it on a high level around other code blocks and in there keep
whatever you need. Think of creating logs that way for example. help datatype!
). So if you find yourself using strings, and then to
for converting to email, url, file, etc. that's *un*idiomatic. Leverage datatypes. Sell 100 shares of "Acme" at $47.97 per share
# recursive fibonacci function in Python def fib(n): if n < 3: return 1 return fib(n-1) + fib(n-2)
\ the Forth version : fib dup 3 < if drop 1 else 1- dup recurse swap 1- recurse + then ;
/fib { dup 3 lt { pop 1 } { 1 sub dup fib exch 1 sub fib add } ifelse } def
split
. I am 99% certain VID2 won't come out in the next 2-3 years.>> b: [[none 0]] >> a: [1 0 3 4] >> reduce [a/-1 a/2] == [none 0] >> b/1 == [none 0] >> b/1 = reduce [a/-1 a/2] == false
b: [[#[none] 0]]
>> help # *** Syntax Error: (line 1) invalid issue at # *** Where: set *** Near : :delimiter-lex *** Stack: load
(reduce b/1) = reduce [a/-1 a/2]
petri: head clear.....
isn't necessary. Insert "returns" a modified series after the inserted material, but that doesn't actually change where a series' word points to. none
as a 0, which doesn't break any rulesselect
seemed like the best option a: 4 switch a [ first find [0 2 3 4] a [print a] 10 [print "10"]]
case
maybetry
is very convenient. to-integer 10 / 3
the idiomatic way to do it?obj: object [ test: none ] foo: func[] [ obj: copy/deep obj obj/test: true ; it's modify original probe obj ] foo
new-obj: make obj []
>> a: b: context [c: 1] == make object! [ c: 1 ] >> a: make a [c: 2] == make object! [ c: 2 ] >> a == make object! [ c: 2 ] >> b == make object! [ c: 1 ]
obj: object [ test: none say: func[] [print ["hello:" test]] ] foo: func[] [ obj: make obj [] ; it's new instance of obj or original obj? obj/test: true obj/say return obj ] foo
new-obj: make obj [] ; where obj is already created object with methods and fields
new-
to name it's good?>> obj1: make object! [a: 1] == make object! [ a: 1 ] >> obj2: make obj1 [b: 2] == make object! [ a: 1 b: 2 ]
make object [..] object [..]
obj: make object! [a: 1] obj: make obj []
obj: make object! [a: 1] obj: "now `obj` points to a string!"
copy\copy/deep
to prevent use old links in new objects?copy/deep
should copy blocks, maybe objects or maps tooobj: object [ test: copy/deep #(a: none) say: func[] [print ["hello:" test]] ] foo: function[] [ nobj: make obj [] nobj/test/a: true nobj/say return nobj ] foo obj/test ; is true, but I am expecting none
info?
to get type, date and size of a file. What can I use in red?print [query f: %some-file size? f ]
obj: object [ test: #(a: none) say: func[] [print ["hello:" test]] ] bar: 123 foo: function[] [ nobj: copy obj ; creating new object nobj/test/a: true nobj/say return nobj ] foo obj/test
dir?
to know if it is a directory or file. copy
action which does not require a specification block, so does just a simple cloning of the object. Existing functions will be re-bound to the new object."test: #(a none)
and not `test: #(a: none)’ in your object definition. Original object remains unmodified.test: #(a none)
. Should be: test: #(a: none)
nobj: copy/deep obj?
C:\Users\i>dir c:\Windows\System32\OpenSSH\ Volume in drive C is Windows Volume Serial Number is 260A-94B5 Directory of c:\Windows\System32\OpenSSH 2021-05-13 22:06 <DIR> . 2021-05-13 22:06 <DIR> .. 2021-05-13 20:39 307 712 scp.exe 2021-05-13 20:39 374 272 sftp.exe 2021-05-13 20:39 481 280 ssh-add.exe 2021-05-13 20:39 382 976 ssh-agent.exe 2021-05-13 20:39 662 016 ssh-keygen.exe 2021-05-13 20:39 557 568 ssh-keyscan.exe 2021-05-13 20:39 946 176 ssh.exe 7 File(s) 3 712 000 bytes 2 Dir(s) 115 633 356 800 bytes free
>> read %/c/Windows/System32/OpenSSH/ *** Access Error: cannot open: %/c/Windows/System32/OpenSSH/ *** Where: read *** Near : %/c/Windows/System32/OpenSSH/ *** Stack:
%/c/Windows/Sytstem32/
. Are there some permissions I do not have right?a: object [a: none] a/a: a b: copy/deep a same? b/a b ;== false same? b/a a ;== true
>> o1: object spec: [m: make map! [a: 1]] >> o2: object spec >> o1/m =? o2/m == false
cmd
as admin maybe?>> extend obj [b: 2] *** Internal Error: reserved for future use (or not yet implemented) *** Where: extend *** Near : [b: 2] *** Stack:
make
@pekr copy/deep
part I do consider a (known) bugcall/output/error "dir c:/Windows/System" o: "" e: "" print o
I find the strange2021-11-02 09:23 1ÿ212ÿ544 OpenCL.dll 2019-12-07 10:09 60ÿ416 openfiles.exe 2021-07-08 23:35 922ÿ112 opengl32.dll 2021-05-05 02:33 107ÿ368 OpenWith.exe 2019-12-07 10:09 44ÿ032 OposHost.exe 2020-04-20 21:55 732ÿ0 ... 019-12-07 10:09 32ÿ768 winml.dll 2020-10-14 04:20 149ÿ272 winmm.dll
opengl32
and openWith
:2021-07-08 23:35 1 062 400 opengl32.dll 2021-05-13 22:06 <DIR> OpenSSH 2021-05-05 02:32 123 984 OpenWith.exe
>> call/output/error "dir c:/Windows/System32" o: "" e: "" print o >> call/output/error "dir c:\Windows\System32" o: "" e: "" print o Volume in drive C is OS (dump of all the files, no dots)
o
output and there's no OpenSSH in the listing! (and no dots)regedit
(someone reported)cmd
from Red (happens implicitly with dir
command), W10 for some reason runs %systemroot%\syswow64\cmd.exe
which runs in some sort of compatibility mode or something. When I call dir %systemroot%\system32
from that cmd.exe
it actually displays me contents of syswow64
(and it's 30% smaller).%systemroot%\syswow64\cmd.exe
can that be called from the normall call?>> call/output "c:\windows\system32\cmd.exe /c dir c:\Windows\System32" o1: "" >> call/output "c:\windows\syswow64\cmd.exe /c dir c:\Windows\System32" o2: "" >> length? o1 == 147328 >> length? o2 == 147328
call/output "c:\windows\syswow64\cmd.exe /c dir c:\Windows\System32" o2: "" *** Access Error: invalid UTF-8 encoding: #{FF313531} *** Where: call *** Stack:
about
in the console)?dir
gives output in OEM codepage, so can't be loaded like this.cmd
does some weird conversion..o2: #{}
as the target, but then need a code page decoder. Either @rebolek or @Oldes have those.list-dir
and propose a new version, or we can put it in red/community.list-dir/col () 3
find o2 to-binary "OpenSSH"
system32
, only to wow64c:/windows/syswow64
. andcall/output "c:\windows\syswow64\cmd.exe /c dir c:\Windows\System32" o2: ""
does not seem to output OpenSSH (at least I cannot find it)read
too.sysnative
? And your slashes are backwards. ;^)call/shell/output/error "where curl" out: "" err: "" print [out err]
call/shell/output/error {where /R "%windir%" osk.exe } out: "" err: "" print [copy/part out 1560 err]
number: object [ type: copy/deep #( selected?: none name: none ) ] new-number: copy number new-number/type/selected?: true print ["number:" number/type/selected?] print ["new-number" new-number/type/selected?]
obj1: object [ test: none say: func[] [print ["hello:" test]] ] foo: function[] [ nobj: make obj1 [test: true]; creating new object nobj/say return nobj ] f: foo print ["old =" obj1/test] ;--unchanged print ["new =" f/test] ;--changed
test: #(a: none)
orginal value is changed.ssh
and other 32 bit programs in https://github.com/red/red/wiki/%5BDOC%5D-Reference-Call#3264-bit-issuesobjs: object [ obj1: object [ foo: function[] [ print "foo1" ] ] obj2: object [ foo: function[] [ print "foo2" ] ] ] list: words-of objs foreach el list [ print objs/(el)/foo ]
foo1 obj1 foo2 obj2
foo1 foo2
objs: object [ obj1: object [ foo: function[] [ return "foo1" ] ] obj2: object [ foo: function[] [ return "foo2" ] ] ] list: words-of objs foreach el list [ print objs/(el)/foo ]
obj1 obj2
>> objs/obj1/foo == "foo1"
Sysnative
isn't found on my system. Not just hidden from view, but the example calls don't work. Does it work for others? Win10 here.els: ["foo" "bar" "baz"] ui: collect [ foreach i els [keep compose [ text i ] ] ] view [panel ui]
?? ui
(i)
is evaluate to proper text value every time?compose
Returns a copy of a block, evaluating only parens
form-each: func [b] [collect [forall b [keep form b/1]]] config: [ age: [1 2 3 4] index: [7 8 9] ] ui: collect [ foreach [key value] config [keep compose/deep [ group-box (to-string key) [ (to set-word! rejoin ['config- key]) drop-list data form-each config/(key) ; [] ] ] ] ] view [panel ui]
>> ?? ui ui: [ group-box "age" [config-age: drop-list data form-each config/(key)] group-box "index" [config-index: drop-list data form-each config/(key)] ]
select
instead of pathsselect
syntax here>> select config-age 'data == ["7" "8" "9"] >> select config-index 'data == ["7" "8" "9"]
?? ui
output?form-each config/(key)
did not evaluated to block? form-each config/(key)
don't helpprobe
probe
is your friend>> probe config/age [1 2 3 4] == [1 2 3 4] >> >> probe config/index [7 8 9] == [7 8 9]
probe
into all steps between correct data and wrong data probe
probe
?form-each: func [b] [collect [forall b [keep form b/1]]] config: [ age: [1 2 3 4] index: [7 8 9] ] ui: collect [ foreach [key value] config [keep compose/deep [ group-box (to-string key) [ (to set-word! rejoin ['config- key]) drop-list data copy form-each config/(key) (probe reduce to-word rejoin ['config- key]) ; I should here get state of /data ] ] ] ] view [panel ui]
>> a: 1 - b: 2 + c: 3 ;) some unknown values == -4 >> (probe a) + (probe b) + probe c ;) displays all values -4 5 3 == 4
config: [ age: [1 2 3 4] index: [7 8 9] ] ui: collect [ foreach [key value] config [keep compose/deep [ group-box (to-string key) [ (probe to set-word! rejoin ['config- key]) drop-list data [] ; probe here ] ] ] ] view [panel ui]
>> a: 1 - b: 2 == -1
>> length? "a" - 1 *** Script Error: - does not allow string! for its value1 argument *** Where: - *** Near : 1 *** Stack:
(length? "a") - 1
1 - b: 2
, -
wants to fetch it's value on the right, but meets b:
, and b:
like function call f x y z
opens a new expression (b: 2
in this case)>> a: 1 - (b: 2) + (c: 3) == 2 >> a: 1 - (b: 2 + (c: 3)) == -4
a: 1 - 2 + 3
a: 1 - b: 2 + c: 3
view [ text 600x30 bold red font-size 20 "My text" font[name: "Consolas" color: 100.100.100.255] ]
form-each: func [b] [collect [forall b [keep form b/1]]] config: [ age: [1 2 3 4] index: [7 8 9] ] ui: collect [ foreach [key value] config [keep compose/deep [ group-box (to-string key) [ ( to set-word! rejoin ['config- key]) drop-list data append [] (probe form-each config/(key)) ] ] ] ] view [panel ui]
Script Error: VID - invalid syntax at: ["3" "4"]
base
@moppy_gitlabtext
is GDI-based and GDI is 24-bits of depthview [ base 600x30 255.0.0.255 text bold font-size 20 "My text" font-color 100.100.100.255 font[name: "Consolas"] ]
text
?form-each: func [b] [collect [forall b [keep form b/1]]] config: [ age: [1 2 3 4] index: [7 8 9] ] ui: collect [ foreach [key value] config [keep compose/deep [ group-box (to-string key) [ ( to set-word! rejoin ['config- key]) drop-list data append [] [(probe form-each config/(key))] ] ] ] ] view [panel ui]
view [ base 600x30 255.0.0.255 bold font-size 20 "My text" font-color 100.100.100.255 font[name: "Consolas"] ]
ui
block, and make sure the view
call works with that. Then add the collect
part, and just basic text
faces. Include something like a counter for the text, so you can see if each one is different. Now add compose
and be sure to use probe
as @hiiamboris suggested. Also, when generating UIs like this, it's *vital* that you probe or save the resulting block for analysis. e.g. probe ui
should be one of the first things you do, even before you hit a problem. :^)>>./red-15feb22-3e79be5ab Compiling compression library... *** Driver Internal Error: Script Error : Invalid path value: Needs *** Where: run-console *** Near: [all [ view? any [Windows? macOS? Linux?] not gui? append source/2/Needs 'View ] files: [%auto-complete.red %engine.red %help.red] foreach ]
full-sql: { t1.id, t1.section_name, t1.fz FROM xml_files t1 WHERE t1.exists_status IS NULL -- тест, NULL } select-columns-raw-part: first split full-sql "FROM" ; replace select-columns-raw-part "SELECT" "" ; get-list-of-columns-from-select: function[] [ raw-list: split select-columns-raw-part "," foreach el raw-list [ column-name: none column-name: second split el "." trim column-name ; remove spaced. if comment all works! print column-name ] ] get-list-of-columns-from-select
trim
all works. *** Runtime Error 16: invalid virtual address *** at: 08066AB6h
тест
letters are key to thisprint trim first split {x^/+й} "+"
this reproduces it for meprint copy column-name
? trim
:)trim/with
it removes all newline characters, not only from head & tail.>> trim/with/tail "one^/two" newline == "onetwo"
str: "hello" t: type? str print t switch t [ string! [print "it is string"] integer! [print "it is integer"] ]
none
>> t: type? str == string!
type?/word
#[string!]
syntax is very limited and buggy.#[unset!]
will cause troubles.>> rejoin ["yyyy-mm-dd: " 2015-02-28] == "yyyy-mm-dd: 28-Feb-2015"
Format
modulecontext
, right? card_type: context ['b 'c 'd] == make object! []
card_type: context [b: c: d: none]
construct [b: c: d:]
works too>> card_type: context [1 probe "a" none x: 1] "a" == make object! [x: 1]
foo: object [ bar: object: [a:1] ] foo/bar/a: 123 ; do not work
>> foo: object [bar: object [a: 1]] foo/bar/a: 2 ? foo/bar/a FOO/BAR/A is an integer! value: 2
foo: object [ bar: object [a:1] ] foo/bar/a: 123 >> probe foo make object! [ bar: make object! [ ] ] == make object! [ bar: make object! [ ] ]
parse "aaaa bb" [(tag: "ss") "aaaa bb"]
parse "aaaa bb" [(tag: "ss") if (tag = "bb") [break|none] "aaaa bb"]
parse [x] [if (cond) break | do you need none?]
'x
to match the actual inputbreak
likely not doing what you think it's doing(return ..)
from within Parse put an end-condition with if (second-table-already)
- ushakovs_gitlab
- 18:07Is it possible to learn about dialect's words by console help?
- hiiamboris
- 18:09
lol Helpin.Red actually documents R3 rules, not Red rules (we have no then
and never had)18:09> Is it possible to learn about dialect's words by console help?
no, just read that page, or I can give a link to the reference 18:09https://w.red-lang.org/en/parse18:10it's not an easy reading though ;)
- ushakovs_gitlab
- 18:10[](https://files.gitter.im/5780ef02c2f0db084a2231b0/qkTo/image.png)18:10Also lol:
- hiiamboris
- 18:11oh maybe it was there in the first release?
- ushakovs_gitlab
- 18:11Who knows.
- gltewalt:matrix.org
- 18:11then is in the parse blog
- hiiamboris
- 18:12I have veery old builds18:12yeah
then
was there
- gltewalt:matrix.org
- 18:12too slow <-----
- hiiamboris
- 18:13it was so years ago and I'm starting to misremembering things :D
- zentrog:matrix.org
- 01:00It was removed because it was too confusing, and didn't provide much benefit [removal of Parse THEN keyword](https://github.com/red/red/issues/3843)
- bubnenkoff
- 13:18Ia there any micro-linux distribs that support Red? Did anybody tried to run it on some ultra light weight (5-10MB)?
- rebolek
- 16:51as Red supports Musl, it should run on such micro-distros. I tried it on Debian-slim, Alpine, OpenWRT and few others.
- ushakovs_gitlab
- 16:59Is there any libs to work with JSON or other structured format?
- hiiamboris
- 17:00no libs, just
? "json"
17:04XML was merged recently, but I wouldn't recommend XML to anyone :D
keep in mind though, Red is first a data format, then a language, so why not use Red or Redbin directly, unless you need interop with other software?
- ne1uno
- 17:04
Needs: ['json]
yet?
- hiiamboris
- 17:06it should be available in prebuilt console in any case
- Moppy_gitlab
- 17:18
popup
appears to be buggy. After closing one(with the x button), clicking anywhere in previously opened "main" window reopens the popup, and the "main" window can't be closed with the x button. 17:18
to-field: function [] [
view [field] [modal popup]
]
view [
b1: button "draw" [resize]
canvas: base 200x200 white
return
canvas-info: text "200x200"
on-down [to-field]
]
- ushakovs_gitlab
- 17:18I need interop exactly. So JSON is good enough. Thank you!
- hiiamboris
- 17:24
modal
is not used in your code @Moppy_gitlab 17:24so, it's a View bug
- Moppy_gitlab
- 17:31what do you mean
modal
is not used?
- ne1uno
- 17:34? view
- hiiamboris
- 17:36you forgot /flags
- Moppy_gitlab
- 17:36okay17:36thanks 17:38Do I have to program the x button to unview the window?
- hiiamboris
- 17:39reported https://github.com/red/red/issues/508317:39try
on-up
for now?17:40I saw very similar bug on W7, need to find it
- ne1uno
- 17:40model is a little wonky, focus might return to some random window
- Moppy_gitlab
- 17:45what does
on-up
do? Doesn't seem to be documented. https://github.com/red/docs/blob/master/en/view.adoc https://github.com/red/docs/blob/master/en/vid.adoc
- gltewalt:matrix.org
- 17:49on- <event> is an actor, so
up
is the event doc
- Moppy_gitlab
- 17:50not here either https://github.com/red/docs/blob/master/en/draw.adoc17:50okay
- gltewalt:matrix.org
- 17:51https://github.com/red/docs/blob/master/en/view.adoc#111-event-names17:51up
- Moppy_gitlab
- 17:59
to-field: function [] [
view/flags [
field
on-up [unview]
] [modal popup]
]
view [
b1: button "draw" [resize]
canvas: base 200x200 white
return
canvas-info: text "200x200"
on-down [to-field]
]
this both makes the field useless and the problem persists. I'll wait then.
- hiiamboris
- 18:03you missed the point completely :)18:04
on-up [to-field]
- Moppy_gitlab
- 18:05removing
modal
all together doesn't seem to make a difference either. I appreciate the condescension. 18:08This freezes all interaction. So yeah. Doesn't work
to-field: function [] [
view/flags [
field
] [modal popup]
]
view [
b1: button "draw" [resize]
canvas: base 200x200 white
return
canvas-info: text "200x200"
on-up [to-field]
]
18:09insert smiley face
- hiiamboris
- 18:10lol18:10View is a mess
- ne1uno
- 18:12adding 'done to the event didn't help either
- Moppy_gitlab
- 18:14would easy GUI be considered one of the main draws of Red?
18:15the syntax is nice and all 18:16but uuuugh, popups are kind of important for real programs
- hiiamboris
- 18:16agreed, hit that many times already
- ne1uno
- 18:17can still right click on the system menu, upper left icon to close
- Moppy_gitlab
- 18:20@ne1uno you can, but for me, the right click menu is disabled until I click on some other window
- pekr
- 18:29I wonder if most of those problems are related to the difficulcy of wrapping of the native gui elements?
- hiiamboris
- 18:30
to-field: function [] [
view/flags [
field
] [modal popup]
]
view [
b1: button "draw" [resize]
canvas: base 200x200 white
return
canvas-info: box 0.0.0.254 left 100x25 "200x200"
on-up [to-field]
]
this works
- Moppy_gitlab
- 18:31@pekr I assume that's why most languages opt for bindings to gui frameworks like qt
- ne1uno
- 18:33probably not every element is fully wrapped to work like a button automatically?
- hiiamboris
- 18:36it's not native controls that are a problem, it's tech debt
View was written hastily to get funding for Red, and never was like really designed
- pekr
- 18:37@Moppy_gitlab But we were there already with the R2 and R3 and found our toolkits, system wise, being not fully compatible - especially in the resort of hotkeys, system look, etc. compatibility.
- Moppy_gitlab
- 18:46okay, well I'm glad this works. For future reference, I guess everything I want to use as a button, that isn't a button, should be a box?
to-field: function [] [
view/flags [
new-size: field
on-enter [canvas/size: to-pair new-size/text]
] [modal popup]
]
view [
canvas: base 200x200 white
return
canvas-info: box 0.0.0.254 left 100x25 "200x200"
on-up [to-field]
]
- hiiamboris
- 18:48you'll know, if it works then you're correct :)
- ne1uno
- 18:48
base
works for custom buttons usually
- hiiamboris
- 18:48box/base - same thing, different defaults18:48but transparent colors also very problematic on W7
- ne1uno
- 18:48x.x.x.254 for transparent ones
- Moppy_gitlab
- 19:26Can the pixels of a base be accessed and edited directly? Say for instance, I wanted to change a single pixel to a different color. 19:26not by adding something on top of the canvas, but by directly changing the canvas itself
- hiiamboris
- 19:30use
image
instead of base
>> view/no-wait [i: image]
>> i/image
== make image! [100x100 #{
FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF...
19:30it's the same base but with image
preallocated to it19:32or add that pixel into draw
facet of the base19:32box 10x10 11x11
smth like that19:33that's "on top" but it also eats less RAM
- gltewalt
- 19:35What are you trying to do @Moppy_gitlab 19:50
view [
size 200x100
title "View can view"
button "Click Me" [
view [
text "I'm a pop-up" button "Ok" [unview]
]
]
]
19:52And alert
exists to use as a guide/template for your own pop-ups.19:52
alert: func [msg [string! block!]][
view/flags compose [
title "Message"
below center
text 200 (form reduce msg) center
button focus "OK" [unview] on-key [
switch event/key [
#"^M" #"^[" #" " #"^O" [unview]
]
]
] 'modal
]
- Moppy_gitlab
- 20:09@gltewalt in a broad sense, remake ms paint as closely as I can, like https://jspaint.app/20:13view [image %something.png] is already better in that it preserves transparency
- gltewalt
- 20:26
box
might be of use20:26It's a transparent base
- Moppy_gitlab
- 20:34the image! type lets you access pixel's value through a numbered path it seems, and every pixel is represented by 6 letters, or a tuple! value.
>> x: load %pixtest.png
== make image! [2x2 #{ED1C24FFAEC9FFFFFF000000}]
>> x/1
== 237.28.36.0
>> x/2
== 255.174.201.0
- hiiamboris
- 20:34
x/1x1
20:34x/(as-pair x y)
- Moppy_gitlab
- 20:35that's convenient
- hiiamboris
- 20:48:+1:
- Moppy_gitlab
- 21:22
repeat x-coor x/size/1 [repeat y-coor x/size/2 [
probe coor: make pair! reduce [x-coor y-coor]
append/only storage reduce [coor x/:coor]
]]
1x1
1x2
2x1
2x2
3x1
3x2
4x1
4x2
5x1
5x2
== [[1x1 255.255.255.0] [1x1 255.255.255.0] [2x2 255.255.255.0] [2x2 255.255.255.0] [3x3 none] [3x3 none] [4x...
21:25probe reduce
also gives me what I expect. 21:25so whatever is being appended to storage is different
- hiiamboris
- 21:26doesn't make sense21:26works for me
- Moppy_gitlab
- 21:27x is this by the way
x: make image! [5x2 255.255.255.0]
21:28okay, it works now 21:28after restarting the console
- gurzgri
- 22:02just a note, you can use
coor: as-pair x-coor y-coor
instead22:11and you can poke x event/offset 0.0.0.0
as an alternative to x/(event/offset): 0.0.0.0
if speed isn't your ultimate concern (it's a tad slower)
- Moppy_gitlab
- 23:09 This works, but if you move the pencil(mouse) too fast, it doesn't keep up and you end up with lots of little dots.
mouse-state: 'up
pencil: func [event] [
if mouse-state = 'down [
base-image/(event/offset): 0.0.0.0
]
]
base-image: make image! [200x200 255.255.255.0]
view [
canvas: image all-over
base-image
on-down [mouse-state: 'down]
on-up [mouse-state: 'up]
on-over [pencil event]
]
23:10instead of a continuous line
- gltewalt:matrix.org
- 23:46What does
view/no-wait
give you?
- Moppy_gitlab
- 23:49the window instantly closes 23:50pretty sure that's what's it's supposed to do
- gltewalt
- 23:50Yeah. missremembering. I think you want to play with
rate
23:51https://github.com/red/docs/blob/master/en/view.adoc#2-face-object
- Moppy_gitlab
- 23:54I've been trying. Setting it higher and higher up to
500000
doesn't seem to change anything23:55I'm not sure it's related to the mouse even. 23:55on-over
specifically 23:57it affects on-time
- Moppy_gitlab
- 00:11I don't think time events know anything about the mouse
on-time [print event/offset]
none
none
none
......
00:25This program doesn't have this issue. It doesn't use rate
. The biggest difference seems to be that it draws lines instead of edits pixels 00:25https://gist.github.com/toomasv/70acbae8dc9d2511df319498592c7eed
- gltewalt
- 00:26Yeah, uses
draw
- Moppy_gitlab
- 00:26for my purposes, that's not gonna work
- gurzgri
- 00:30no way that ’view/no-wait’ instantly closes a window, it rather opens a window but doesn‘t wait for events in an event loop.
- Moppy_gitlab
- 00:31should I record a video of it instantly closing?
- gurzgri
- 00:33The difference between toomasv‘s version and yours is that the former uses the draw block to draws lines to get lines from the old mouse pos to the current mouse pos, not just plots loose pixels at current mouse pos in an image00:34minimal sample code to demonstrate should do00:34No video required
- Moppy_gitlab
- 00:35his doesn't use
no-wait
00:36my goal here is to quickly edit an image's pixels based on mouse position
- gltewalt:matrix.org
- 00:38It doesn't close here, but im using Mint
- Moppy_gitlab
- 00:56video of instant closing https://files.catbox.moe/duosq9.mp4
- luis-rj
- 01:25@Moppy_gitlab Add do-events as last line of you program.
- Moppy_gitlab
- 01:27the problem persists
- gltewalt
- 01:32@toomasv any knowledge here?
- Moppy_gitlab
- 01:32I asked elsewhere how you'd typically do this 01:32
You need to buffer the cursor position in memory so those pixels can be affected at a asynchronous rate to the script, display refresh or CPU time.
>01:33not a Red specific answer
- gltewalt
- 01:33Makes sense, but yeah.. I'm curious about Red specific
- Moppy_gitlab
- 01:34I wouldn't know how to make a buffer in any language, but uugh, I guess Red has support for that?
- gltewalt:matrix.org
- 01:39As far as I know you'd have to make one. But others will be along to give their 2 cents01:44Maybe do the old fill bucket 🪣 part while you're stuch01:53I'm stuck too, I dont know how to smooth it out without going into that buffer idea. 01:54Maybe... look at
draw
source code and see how it draws
- Moppy_gitlab
- 01:56I have no problem with using a buffer conceptually.
- ne1uno
- 01:56pixelation from integer x,y? maybe zoom in
- Moppy_gitlab
- 01:57you mean drawing a line, and then pixelizing it? 01:59
line
is some kind of abstraction of pixels, so whatever it uses to keep track of mouse position must also be usable for editing pixels.
- toomasv
- 07:11Drawing directly into image, but dotty:
x: make image! [100x100 255.255.255.0] a: x/argb
view [
below
image x all-over on-over [if event/down? [x/(event/offset): 0.0.0.0]]
button 100 "Clear" [x/argb: a]
]
To draw with smooth continuous line I suggest using draw with spline
.
- ldci
- 07:36@Moppy_gitlab You’ll find in redCV different routines (R/S) and functions (Red) such as rcvGetPixel or rcvSetPixel that allow getting and seting individual pixel value.
- toomasv
- 09:33With continuous line:
view [
below
pic: base white 100x100 draw [] all-over
on-over [if event/down? [append face/draw event/offset]]
on-down [append face/draw reduce ['spline event/offset event/offset]]
button 100 "Clear" [clear pic/draw]
]
- hiiamboris
- 09:44after a few seconds this is gonna slow down a lot09:45you have to rasterize points before the last two
- toomasv
- 10:34Maybe then:
x: draw 100x100 []
clr: x/rgb
view [
below
im: image x draw [] all-over
on-over [if event/down? [append face/draw event/offset]]
on-down [
if not empty? face/draw [
dr: draw face/size face/draw
x/rgb: x/rgb and dr/rgb
clear face/draw
]
append face/draw reduce ['spline event/offset event/offset]
]
bt: button 100 "Clear" [clear im/draw x/rgb: clr]
]
- hiiamboris
- 10:45why not
draw x face/draw
?10:46it actually has acceptable speed now, maybe because of D2D
when I tested it on GDI back then it was *really* slowing down
- toomasv
- 10:46Yeah, of course. Silly me.
- hiiamboris
- 11:17wow I changed spline to curve and it crashes baaadly
- toomasv
- 11:31Did you use
shape
? And how do you place control points?
- hiiamboris
- 11:34
view [
below
im: box 0.0.0.254 1000x600 draw [] all-over
on-over [if event/down? [append face/draw event/offset]]
on-down [
append face/draw reduce ['line-width 3 'curve event/offset event/offset]
]
bt: button 100 "Clear" [clear im/draw]
]
this is the crashing code
need to simplify it :)
- toomasv
- 11:41This works
x: draw 100x100 []
clr: x/rgb
view [
below
im: image x draw [shape []] all-over
on-over [if event/down? [append face/draw/shape reduce [event/offset event/offset]]]
on-down [
if not empty? face/draw/shape [draw x face/draw clear face/draw/shape]
append face/draw/shape reduce ['move e: event/offset 'curv e e]
]
bt: button 100 "Clear" [clear im/draw/shape x/rgb: clr]
]
12:31But control-points are nonsensical :)
- hiiamboris
- 12:40
view [
im: box 0.0.0.254 1000x600 draw [] all-over
on-over [if event/down? [append face/draw event/offset]]
on-down [append face/draw reduce ['line-width 3 'line event/offset event/offset]]
]
this is **unbearably** slow somehow12:42almost okay on GUI console, but delayed by seconds on CLI console12:50also, it's much faster if drawing by touchpad, and only slow when using touchscreen12:54or maybe it's random, depending how it aligns with the timer
- gurzgri
- 13:11can't confirm this, same acceptable speed in cli and gui console here on a SurfacePro7 i5-1035G4 @ 1.10GHz 8 GB, latest automated Red build. no differences between mouse, touchpad or touchscreen
- hiiamboris
- 13:16interesting! need to investigate this more13:16Surface has a discrete GPU?13:22what if I add
probe
to CLI console:
view [
im: box 0.0.0.254 1000x600 draw [] all-over
on-over [if event/down? [append face/draw event/offset probe length? face/draw]]
on-down [append face/draw reduce ['line-width 3 'line event/offset event/offset]]
]
still fast?
- gurzgri
- 13:26ask me something simpler, especially ask me nothing about GPUs ;-) ... I think I stopped following them after Denise and Lisa. Should be a Intel Iris Plus Graphics G4 (Ice Lake 48 EU) without dedicated graphics eDRAM.
- hiiamboris
- 13:28I really don't get it. It usually starts slow for me like I'm drawing 100-200px away from where I see the changes, then esp. on touchpad, after like 10 seconds it starts to keep up and now it's not slow anymore, even though the number of points maybe close to 500 by now
- gurzgri
- 13:28With
probe
ing, GUI slows way down, no noticable degrading with CLI console.
- hiiamboris
- 13:28nah, GUI is expected to slow down
- gurzgri
- 13:29yeah, thought so13:30number of points doesn't matter much, I almost painted the whole canvas black :D
- hiiamboris
- 13:30lol13:3113:31here it's even visible - first 3 seconds (touchpad) delay is so huge that it creates inertia13:32then it suddenly syncs with me and keeps up after13:33but I've no idea about the reasons :laughing: 13:41battery mode doesn't affect it for me
- Moppy_gitlab
- 15:27@ldci thanks for pointing me in that direction. 15:28the point's not to make lines, the point's to edit pixels in a variety of ways 15:41does RedCV offer a way of dealing with the mouse? Because the mouse seems to be the problem point15:51This works, but doesn't solve the issue. And when going out of bounds, it causes an access violation and closes the program
on-over [if event/down? [rcvSetPixel base-image event/offset 0.0.0.0]]
- ne1uno
- 15:53check < 0?
- hiiamboris
- 15:54@Moppy_gitlab your previous bugs were fixed today
- Moppy_gitlab
- 15:55with
text
?
- hiiamboris
- 15:57yeah
- Moppy_gitlab
- 16:09This demonstrates the crux of the problem.
base-image: make image! [200x200 255.255.255.0]
view [
canvas: image all-over base-image
on-over [if event/down? [print event/offset]]
]
output
67x24
67x32
67x40
67x50
67x60
67x74
67x86
67x101
67x116
67x129
66x144
65x154
64x161
64x166
62x168
62x169
62x170
I held the mouse down the entire time, so there's no way it could have teleported from 67x24 to 67x32. I need a way to capture every single pixel the mouse goes while the button is held down.
- hiiamboris
- 16:14study the solutions above
- ne1uno
- 16:17high mouse acceleration dpi? I'm not seeing much breakup
- Moppy_gitlab
- 16:19Okay, I'll read Red/System docs so I can understand this https://github.com/red/red/blob/89896f9c1e3d9ddbe97d33392d3239b00df0afb3/modules/view/draw.red
- hiiamboris
- 16:20don't overcomplicate the task :)16:20what you're looking for is like 3 lines of code
- Moppy_gitlab
- 16:21I know this task is possible in a browser with javascript of all things. I don't know how though.
- ne1uno
- 16:25https://www.tutorialspoint.com/How-to-draw-on-the-canvas-with-JavaScript16:30that's not a good example, looks like default html5 canvas accepts drawing by default
- Moppy_gitlab
- 16:47https://developer.mozilla.org/en-US/docs/Web/API/Element/mousemove_event16:48> The frequency rate of events while the pointing device is moved is implementation-, device-, and platform-specific, but multiple consecutive mousemove events SHOULD be fired for sustained pointer-device movement, rather than a single event for each instance of mouse movement. Implementations are encouraged to determine the optimal frequency rate to balance responsiveness with performance.16:48https://w3c.github.io/uievents/#event-type-mousemove16:56maybe interpolation could work
- hiiamboris
- 16:58read the above like 5 times and still don't understand what it's saying :/
- Moppy_gitlab
- 17:00I think, if movement puts events on a queue that happen consecutively, every movement causes multiple events. So even if I just moved the mouse one pixel, it would return its
offset
5 times
- hiiamboris
- 17:03but that would pixelate the movements, make lines look like in 80s17:04I doubt that's what it's saying
- ne1uno
- 17:10you're going to have to know if the movement was continuous to interpolate. de-bouncing user intentions is probably more than you want to do.17:16https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Basic_animations there's probably a drawing on canvas section here but I didn't find it
- Moppy_gitlab
- 17:35I guess like this
a: 1x1
b: 5x7
straight-gen a b
{
desired output
[
1x1 2x2 3x3 4x4 5x5 5x6 5x7
]
}
17:37I'll make a block(for x difference), then turn each member into a pair(y difference)
- hiiamboris
- 17:40I'd recommend to rethink your approach. It was already solved idiomatically in the above examples by Toomas.17:40On the other hand if you pursue this, you'll realize why it's deeply wrong. Also a good thing.
- Moppy_gitlab
- 17:42If you're trying to feed a bird, and you feed a cat instead, you fed an animal, but not the right one.
- ne1uno
- 17:43http://en.wikipedia.org/wiki/Bresenham%27s_line_algorithm the 5th day adventofcode 2021 was about line intersection.
- hiiamboris
- 17:45aliased :)
- ne1uno
- 17:45guessing your mouse sensitivity is high too
- Moppy_gitlab
- 17:46my mouse is normal. Hardware is really not relevant.
- toomasv
- 18:18Somehow 1x1 is not there?
i: draw 10x10 [anti-alias off line 1x1 5x7]
collect [repeat r 10 [repeat c 10 [if i/(p: as-pair c r) = black [keep p]]]]
;== [2x2 2x3 3x3 3x4 4x5 4x6 5x6 5x7]
- hiiamboris
- 18:19start with 0x0
- toomasv
- 18:19Then 5x7 will not be there
- hiiamboris
- 18:22why?18:22
- toomasv
- 18:23Hmm.. tired?
collect [repeat r 10 [r: r - 1 repeat c 10 [c: c - 1 if i/(p: as-pair c r) = black [keep p]]]]
== [2x2 2x3 3x3 3x4 4x5 4x6 5x6 5x7]
- hiiamboris
- 18:23D2D follows coordinate system 3 here
- toomasv
- 18:24
collect [repeat r 10 [repeat c 10 [if i/(p: as-pair c r) = black [keep p - 1]]]]
== [1x1 1x2 2x2 2x3 3x4 3x5 4x5 4x6]
- hiiamboris
- 18:25well, your line is 5x7 - 1x1 = 4x6 pixels in size (outline)18:26
- toomasv
- 18:28Ok, so it draws to the "start" of 5x7?
- hiiamboris
- 18:2918:29red line coordinates are 1x1 to 5x7 on this pic18:29there's no "start" or "end"
- toomasv
- 18:29:+1:
- bubnenkoff
- 18:33What principle difference when I should use
object
instead of block
?
foo: [a: 1 b: 2 c: 3]
vs
foo: object [a: 1 b: 2 c: 3]
From real usage. I am using mostly blocks when I have same data structure, but now I see that at last real useful thing is support of casing object to json
- hiiamboris
- 18:36objects are heavier to create, but faster to select from
- Moppy_gitlab
- 18:39this produces some, uugh interesting results
initial: none
pencil: function [event] [
base-image/(event/offset): 0.0.0.0
]
straight-gen: function [init-pair final-pair] [
x-diff: final-pair/1 - init-pair/1
y-diff: final-pair/2 - init-pair/2
xvals: copy reduce []
repeat x absolute x-diff [
x-to-add: x
if negative? x-diff [x-to-add: x-to-add * -1]
append xvals reduce [init-pair/1 + x-to-add]
]
vals: copy reduce [init-pair]
repeat y absolute y-diff [
y-to-add: y
if negative? y-diff [y-to-add: y-to-add * -1]
case [
tail? xvals [
append vals as-pair xvals/-1 (init-pair/2 + y-to-add)
]
(init-pair/2 + y-to-add) > xvals/1 [
append vals as-pair xvals/1 (init-pair/2 + y-to-add)
]
true [
append vals as-pair xvals/1 (init-pair/2 + y-to-add)
xvals: next xvals
]
]]
vals
]
base-image: make image! [200x200 255.255.255.0]
view [
canvas: image all-over base-image
on-down [initial: event/offset]
on-over [if event/down? [
foreach pixel (straight-gen initial event/offset) [
base-image/:pixel: 0.0.0.0
]
]]
on-up [initial: none]
]
- hiiamboris
- 18:40wow
- gltewalt:matrix.org
- 18:49> but that would pixelate the movements, make lines look like in 80s
Queue up events, blow out queued events (serially).
- Moppy_gitlab
- 18:50now it's a little better
view [
canvas: image all-over base-image
on-down [initial: event/offset]
on-over [if event/down? [
foreach pixel (straight-gen initial event/offset) [
base-image/:pixel: 0.0.0.0
]
]
initial: event/offset
]
on-up [initial: none]
]
- gltewalt:matrix.org
- 18:51Like buffering for video
- Moppy_gitlab
- 18:55except for straight lines that go up and down(kinda, not really), the desired result has not been achieved. There's also a noticeable delay between mouse movement and pixel color changing. With my current information, I give up.
- ne1uno
- 18:55que unique sequential events, react on a timer to smooth line output. to what end? avoiding draw?
- Moppy_gitlab
- 18:56I'm not avoiding draw, I don't need draw. Draw is tangential to what I've trying to do.
- hiiamboris
- 18:57no it's not
- Moppy_gitlab
- 18:57ms paint is the goal
- hiiamboris
- 18:57
draw
is exactly what you should have used
- GiuseppeChillemi
- 18:57I would like have a dynamic command whose refinements are defined by a word like:
r: 'part
copy/:r [a b c] 2
But it does not work
I have tried in REBOL
>> do to-path reduce ['copy r] [a b c] 2
== [a b]
It does work but not in RED. I have to use:
do reduce reduce ['to-path reduce ['copy r] [a b c] 2]
Which is far less readable than both the above versions
Is there a way to have the first version, which is very easy to manage, write and read?
- Moppy_gitlab
- 18:57ms paint does not make line objects, it edits pixels 18:57when you use the pencil
- hiiamboris
- 18:57so study
draw
better18:57? draw
18:58like I said, your task was already solved above today :)
- Moppy_gitlab
- 18:58I don't think you understand my task
- hiiamboris
- 18:59> Is there a way to have the first version, which is very easy to manage, write and read?
@GiuseppeChillemi no, by design, variable arity is forbidden to make interpreter faster and more predictable19:00@Moppy_gitlab I do :)
- Moppy_gitlab
- 19:00In that case, you'd be able to say how draw accomplishes what I'm trying to
- hiiamboris
- 19:00
? draw
- Moppy_gitlab
- 19:01I don't know why you're getting defensive.
- hiiamboris
- Moppy_gitlab
- 19:01I'm not doing vector graphics19:01vector graphics is not my goal
- hiiamboris
- 19:02ignore that19:02read "TO AN IMAGE"
- GiuseppeChillemi
- 19:02@hiiamboris
I know, we have talked about this 2 years ago. But I have hoped refinement could be evaluated before arity i defined so the interpreter know that copy/:r
needs 2 args instead of 1.
- hiiamboris
- 19:03@GiuseppeChillemi well, I wish for that too sometimes (not too often though)
- Moppy_gitlab
- 19:03"To an Image" doesn't imply anything about raster graphics
- hiiamboris
- 19:03
image!
is a raster array in Red, aka bitmap
- GiuseppeChillemi
- hiiamboris
- 19:04just make a wrapper that works for both R2 and Red
- Moppy_gitlab
- 19:05>Raster-based image editors, such as PaintShop Pro, Corel Painter, Adobe Photoshop, Paint.NET, Microsoft Paint, and GIMP, revolve around editing pixels, unlike vector-based image editors, such as Xfig, CorelDRAW, Adobe Illustrator, or Inkscape, which revolve around editing lines and shapes (vectors).
- hiiamboris
- 19:06I know what raster is and I know what you're trying to do, and I stand by my point
draw
function is the way
- Moppy_gitlab
- 19:06even if I could finagle it, it's still an extra step going from vector to raster
- hiiamboris
- 19:06don't be so stubborn, plz?19:08either you leverage
draw
or you reimplement it by modifying individual pixels19:08there's no other way
- GiuseppeChillemi
- 19:09The most important thing I miss is to ability to run a function returned but another one or as result of a selection:
f: reduce ['f1 func [a b] [print [a * b]] 'f2 func [a b] [print [a + b]]]
select f 'f1 arg1 arg2
- Moppy_gitlab
- 19:09I'd rather reimplement it. I don't know how I'd do that now. Hence what I said earlier about giving up.
- hiiamboris
- 19:09mkay
- GiuseppeChillemi
- ne1uno
- 19:09found https://github.com/raevilman/excalidraw while looking up their https://github.com/raevilman/windows-scripts/tree/master/mouse/speed 19:09not sure if it's 19:10not sure if it's vector or raster, but likely simpler than paint.net
- gltewalt
- 19:11A hue amount of stuff, though
- hiiamboris
- 19:13
f/f1
should work19:14ah, I see what you're doing
- GiuseppeChillemi
- 19:14You are right, I have forgotten about this. It is just you can't execute when returning a function as result of another one!
- hiiamboris
- 19:14
f2: f/f1 f2 arg1 arg2
19:14cleanest way
- GiuseppeChillemi
- 19:18@hiiamboris
:point_up: [20 febbraio 2022 20:09](https://gitter.im/red/help?at=621291d36b91242320fb15c8)
I have corrected the example, it is now what I want to do.
- hiiamboris
- 19:20well, that one is not returning a function19:20but I've shown you the way without
reduce
- GiuseppeChillemi
- 19:25Why?
f: reduce ['f1 func [a b] [print [a * b]] 'f2 func [a b] [print [a + b]]]
select f 'f1
== func [a b][print [a * b]]
- hiiamboris
- 19:26I mean this:
> when returning a function as result of another one!
- GiuseppeChillemi
- 19:27Pardon, I have not understood!19:27Could you repeat the example with the source data?
- hiiamboris
- 19:29ah nevermind19:29sorry I need to make dinner fast19:45@GiuseppeChillemi I'm sayin your code does not have a function that returns a function20:03@Moppy_gitlab regarding your quest. I know nothing of mspaint source code, but I'm confident that it doesn't include a vector rasterizer. Nor does Red - it just lets OS do all that. And OS lets the driver do that. Just how low level do you wanna get with this? Red/System would be a better language for this task than Red.
- greggirwin
- 20:26@Moppy_gitlab your
straight-gen
confused me, as to your goal. I haven't followed the other links posted, but for a pencil brush, you should just be able to poke
the color value into the image's pixel at a given position.
- Moppy_gitlab
- 20:27@hiiamboris As low as necessary to get a clean solution with no magic involved as to how events work.
- hiiamboris
- 20:28what events?20:29what magic?
- Moppy_gitlab
- 20:30Toomas suggesting I used
spline
. Even if this would fix things, I don't how it does. I have no idea how spline
works and draw
as a whole.
- hiiamboris
- 20:31like I said, it gets down to the driver and DirectX code20:31do you wanna go that low? maybe also to program the GPU?
- Moppy_gitlab
- 20:31I don't want to append a draw block millions of times
- hiiamboris
- 20:31anyway, my point is, you have to balance your task's complexity with your skills20:31otherwise it will be no fun for you20:32no fun = no learning
- Moppy_gitlab
- 20:32the draw block is going to get gargantuan 20:32editing the image itself is cleaner
- hiiamboris
- 20:32don't append, just understand that
draw
function draws a stroke on a bitmap20:32I've spent whole evening trying to get this thru to you :)20:33after it's drawn - there's just pixels
- Moppy_gitlab
- 20:33
on-down [
if not empty? face/draw/shape [draw x face/draw clear face/draw/shape]
append face/draw/shape reduce ['move e: event/offset 'curv e e]
]
20:33append
is right there
- hiiamboris
- 20:33that's because Toomas didn't choose to draw *every* intermediate line, only the whole line after mouse-up event20:34doesn't stop you from doing that
- Moppy_gitlab
- 20:35I haven't seen any instance of putting a line in
draw []
that doesn't involve appending to draw 20:36the line should not be deletable20:36it should replace the color values of the pixels in those locations
- hiiamboris
- 20:37do you understand the distinction between face's
draw
facet (which is a block) and a draw
function that commit similar block to the bitmap?
- gurzgri
- hiiamboris
- 20:37:turtle: 20:37:rocket:
- gurzgri
- 20:37beat me :D
- GiuseppeChillemi
- 20:38@hiiamboris I have spent the last hour making this. It works for Rebol and Red.
run-a-cmd: func [
"Run a command by name with separate refinements and argument"
'cmd [word! function! action!] "The command name or a function"
ref [word! block! none!] "The refinements"
args [block!] "the arguments"
/local
the-command
command
exe
run?
the-ref
in-cmd
] [
run?: true
exe: copy []
either any [function? :cmd action? :cmd] [
in-cmd: :cmd
the-command: 'in-cmd
] [
the-command: :cmd
]
either none? ref [
the-command: append reduce [the-command] args
] [
if block? ref [
forall ref [
the-ref: first ref
if any [not word? the-ref not refinement? the-ref] [run?: false]
]
ref: to-path ref
]
the-command: append append/only exe to-path reduce [the-command ref] args
]
either run? = true [do the-command] [make error! "Invalid refinements!"]
]
probe run-a-cmd copy none [[a b c]]
probe run-a-cmd copy 'part [[a b c] 1]
probe run-a-cmd :copy none [[a b c]]
probe run-a-cmd :copy 'part [[a b c] 1]
probe run-a-cmd :copy [deep part] [[a b c] 1]
probe run-a-cmd :copy [deep part 22.2] [[a b c] 1]
Result:
[a b c]
[a]
[a b c]
[a]
make error! [
code: 800
type: 'user
id: 'message
arg1: "Invalid refinements!"
arg2: none
arg3: none
near: none
where: none
stack: none
]
Suggestion are welcome!
- Moppy_gitlab
- 20:39there are no functions in view though. just faces
- hiiamboris
- 20:39:clap: @GiuseppeChillemi
- gurzgri
- 20:40´system/words/draw´ or, as we say, global context
- hiiamboris
- 20:40yeah I pointed to
? draw
like 3 times already :)
- gurzgri
- 20:40I know.
- Moppy_gitlab
- hiiamboris
- 20:41yep20:42and it's all documented in https://w.red-lang.org/en/draw
- Moppy_gitlab
- 20:45so this guide is not actually about
draw
https://www.red-by-example.org/draw.html20:45the function20:45or dialect 20:46or whatever it is I should be using
- hiiamboris
- 20:57correct
- Moppy_gitlab
- 21:01
base-image: make image! [200x200 255.255.255.0]
draw base-image [line 0x0 10x10]
view [image base-image]
I did not know you could do this.
- hiiamboris
- 21:02that's why I initially insisted you study the Toomas' example
- Moppy_gitlab
- hiiamboris
- Moppy_gitlab
- 22:48[](https://files.gitter.im/5780ef02c2f0db084a2231b0/zL9l/res.png)22:48
base-image: make image! [200x200 255.255.255.0]
draw base-image [anti-alias off line 0x20 150x21]
above, result of this, below, what I'm trying to do(should go one pixel below initial point, but you know what I mean)
22:53[](https://files.gitter.im/5780ef02c2f0db084a2231b0/7Ik5/res2.png)
- ne1uno
- 23:03invent grey half pixels?23:06line-width 2
- Moppy_gitlab
- 23:11so is draw's vector -> bitmap system limited in how precise it can be?
- ne1uno
- 23:12what are the options? zoom out and you can have more pixels23:20keep lines horizontal, vertical or 45 degrees to minimize jaggies23:45https://github.com/red/red/wiki/[PROP]-Image-coordinate-systems-reboot-idea similar problem shows up in scale & rotation
- pekr
- 06:34I would like to say, that even with R2, user called Geomol created a paint program, which resembled Amiga Deluxe paint, and it worked. I just can't find any screenshots right now ....
- ne1uno
- 06:46
Rebol Geomol paint
turns up a bunch of links. R2 draw effects would need work
- pekr
- 06:52None of them are useful to the topic. Just wanted to show you a Rebol version of Amiga Deluxe Paint in under 200KB of code. Would have to dig some harddrive.
- ne1uno
- 06:54https://pastebin.com/Xpz2Nq9Y06:57>Paint REBOL version "Frank Sievertsen" Red port "Gregg Irwin"
- pekr
- 06:59That's not it. Geomol (John Niclasen) was very skilled Rebol programmer. He even created a Rebol clone called World programming language. I think, it is abandoned, as its website dissappeared, but it can be found via Github, last commits in 2016 ....06:59But - there was multiple simpler paint programs and as for Red, I think stuff from Toomas are quite inspirational ....
- ldci
- 07:01See http://www.world-lang.org
- ne1uno
- 07:01https://github.com/Geomol/World/07:11I used some amiga paint & cad and the video toaster in the early 90's at a marketing company. way ahead of anything else I had access to then.
- toomasv
- 08:43@Moppy_gitlab Something like this?
img: draw 200x50 [] clr: img/rgb
paint-line: function [img [image!] points [block!]][
img/rgb: clr forall points [
if not last? points [df: points/2 - points/1 case [
any [df/y = 0 df/x = 0 (abs-x: absolute df/x) = (abs-y: absolute df/y)] [
draw img compose [anti-alias off line (points/1) (points/2)]
]
abs-x > abs-y [
dy: pick [-1 1] df/y < 0 dx: df/x / ay: abs-y + 1 x: points/1/x y: points/1/y
loop ay [draw img compose [anti-alias off line (as-pair x y) (as-pair x: x + dx y)] y: y + dy]
]
true [
dx: pick [-1 1] df/x < 0 dy: df/y / ax: abs-x + 1 x: points/1/x y: points/1/y
loop ax [draw img compose [anti-alias off line (as-pair x y) (as-pair x y: y + dy)] x: x + dx]
]
]
]] ? img
]
get-points: function [img [image!]][collect [repeat r img/size/y [repeat c img/size/x [if img/(p: as-pair c r) = black [keep p]]]]]
show-points: function [img [image!] /cols cls][cls: any [cls 20] points: get-points img probe new-line/skip points true cls ()]
E.g.:
paint-line img [1x20 150x22 148x50 200x50 200x1 150x50]
- hiiamboris
- 09:20or just don't turn off antialias :)
- toomasv
- 09:21It's not same
- hiiamboris
- 10:1110:11:)10:19question is, why is it not symmetric? ;)
- toomasv
- 10:52Excellent tool!
But...
... what about following comparison? First is by my code above, second is anti-alias on
, third anti-alias off
, fourth just draw, all scaled by 3:10:52[](https://files.gitter.im/5780ef02c2f0db084a2231b0/uwwX/image.png)10:53Third is with line-cap round
as in yours.
- hiiamboris
- 11:00it's a mess :)11:0011:03some implementation artifacts which are likely different across platforms
- toomasv
- 11:08My code for above comparison:
bi: draw 200x50 []
paint-line bi [1x20 150x22 148x50 200x50 200x1 150x50]
gi: draw 200x50 []
draw gi [line 1x20 150x22 148x50 200x50 200x1 150x50]
hi: draw 200x50 []
draw hi [anti-alias off line-cap round line 1x20 150x22 148x50 200x50 200x1 150x50]
view [below
box 1000x200 draw [scale 3 3 image bi]
box 1000x200 draw [scale 3 3 image gi]
box 1000x200 draw [scale 3 3 image hi]
box 1000x200 draw [scale 3 3 line 1x20 150x22 148x50 200x50 200x1 150x50]
]
- hiiamboris
- 11:10
explore draw 200x50 [anti-alias off line 1x20 150x22 148x50 200x50 200x1 150x50]
on GTK:
11:11open source beats it
- toomasv
- hiiamboris
- 11:17
- toomasv
- 11:18Thanks! Not too bad.
- hiiamboris
- 11:18yeah pretty good :)11:18off by a pixel though? I think it draws from pixel's center to pixel's center11:18not from corner to corner
- toomasv
- 11:20I devised it so as to match my taste for what I would expect from it ...
- hiiamboris
- 11:20ok :)11:24draw should be like this then for fairer comparison:

- toomasv
- 11:41Ha, I like it more! :)11:43But why do you need
line-cap round
?
- hiiamboris
- 11:46just forgot to remove, it doesn't seem to do it's magic when line has >2 points
- toomasv
- 11:48Ok, thanks.11:50Maybe
line-join
?11:53Naah..
- Moppy_gitlab
- 15:52@toomasv Thank you for writing that. @ne1uno mentions this sort of thing happening in scale and rotation too. While for each one, a workaround is probably possible, at that point, you might as well "fix" anti-alias itself. I don't expect anyone to do that for something so specific and seemingly niche.
- ne1uno
- 15:58nothing is broken, there is a physical limit of how you deal with limited pixels.
- Moppy_gitlab
- 15:59what do you mean by that?
- ne1uno
- 16:00vector drawing is another workaround. you describe shapes exactly, then render
- Moppy_gitlab
- 16:01to draw a line that ends one pixel below the initial point,
anti-alias off
needs to be used, and its functionality needs to be added to by adding logic which breaks the line down into pieces. 16:02if anti-alias off
had all that built into it(in a generalized way), such things wouldn't be necessary
- hiiamboris
- 16:08> to draw a line that ends one pixel below the initial point, anti-alias off needs to be used
not true though
- Moppy_gitlab
- 16:11[](https://files.gitter.im/5780ef02c2f0db084a2231b0/SBUM/alias.png)16:12pretty much every feature was made with anti-alias being on in mind, since it's the default and all 16:14so to make a program where every feature is
anti-alias off
by default, a lot of workarounds are probably needed
- hiiamboris
- 16:18write a mail to micro$oft :)
- Moppy_gitlab
- 16:19does microsoft have something to do with this?
- hiiamboris
- 16:20who else do you think writes Direct2D?
- Moppy_gitlab
- 16:21mmm, I see. So it comes back to vector graphics. 16:26@pekr Did R2 have a built-in graphical facility?16:27R3 view's draw dialect seems to have took a similar approach to Red 16:28http://rebol.com/docs/draw.html16:29apparently R2's didn't even have anti-aliasing
- pekr
- 16:39R2 had antialiasing, since it was based upon AGG library.
- Moppy_gitlab
- 16:41Yeah, after trying it, I can see that. 16:41R3 has "new anti-aliasing" 16:47[](https://files.gitter.im/5780ef02c2f0db084a2231b0/jW3a/test3.png)16:48I mean....
- ushakovs_gitlab
- 17:05
res: [] parse "a a a a " [any [ (ch:[]) 2 ["a" skip (append ch "a") ] (append/only res ch) ] ]
length? res/1
I suppose res should be block of 2x2. But in fact it's block of 2x4.
What is wrong with my code?
- hiiamboris
- 17:07https://github.com/red/red/wiki/[DOC]-Why-you-have-to-copy-series-values
- endo64
- 22:22@GiuseppeChillemi here is my version:
run: function [cmd args /ref refs] [do probe reduce compose/deep [to path! [(cmd) (any [refs ()])] (args)]]
>> run 'copy [next "abc"]
[copy "bc"]
== "bc"
>> run/ref 'copy [next "abcabcabc" 2] [part]
[copy/part "bcabcabc" 2]
== "bc"
>> run/ref 'find ["testing" "t"] [last]
[find/last "testing" "t"]
== "ting"
- toomasv
- 07:45@hiiamboris @Moppy_gitlab Seems that GDI handles
anti-alias off
much better than D2D. Tried Jan 18, 2021 build.
- hiiamboris
- 09:56can't stop progress :/
- Moppy_gitlab
- 03:47@toomasv What is GDI? Is this what you mean? https://docs.microsoft.com/en-us/windows/win32/gdi/windows-gdi03:48I guess so if D2D is short for Direct 2D
- toomasv
- 04:23Yes. Red used GDI/GDI+ in its Draw engine earlier, but switched to [Direct2D](https://docs.microsoft.com/en-us/windows/win32/direct2d/direct2d-portal) about year ago. But I don't know the low-level details, or benefits. Have noticed some drawbacks though, some things that used to work, do not any more.
- pekr
- 05:59The main benefit is, that D2D is hw accelerated. I did some tests with the Particles demo and D2D provided a clear advantage in performance, whereas Direct / 3D stuff is known for having problems with precision ....
- Moppy_gitlab
- 17:17wouldn't allowing users to choose the backend they use be better?
- ne1uno
- 17:19you can with compiling
- hiiamboris
- 17:22also GDI backend is not maintained
- ne1uno
- 17:25I thought the old gui would use GDI. I think you need to edit in Config before you build. the and may itself still require Dx11 D2D17:26
Config: [gui-console?: yes red-help?: yes draw-engine: 'GDI+]
17:31%environment/console/GUI/old/gui-console.red17:32also not fully maintained, has a few quirks18:45you could build a gui console from before 2021 to see how GDI+ looks, modulo any bugs fixed since
- Moppy_gitlab
- 18:51why not opengl, sdl2 or vulkan?
- ne1uno
- 18:56linux console uses gtk.
- hiiamboris
- 18:56those are 3d tech
- Moppy_gitlab
- 19:25not exclusively 19:27There's also OpenVG19:29@ne1uno huh? There's no mandate that terminal emulators need to use gtk
- ne1uno
- 19:31yea, just for view I guess. I haven't used linux in awhile19:33cairo19:45there are some various gui wraps in the community repo? everyone should wrap a gui, at least once.
- hiiamboris
- 19:46:)19:48@ldci wrapped a lot of them already
- ne1uno
- 20:04https://github.com/red/code/tree/master/Library/Vulkan
- greggirwin
- 20:54The idea of having user-configurable back ends sounds great, but it adds another dimension to being cross platform. That's already hard enough. And just as platform differences lead to lowest-common-denominator limitations, so will each different graphics and audio back end. So you end up exposing things at a low level and code is now *far* less portable.20:56To ease things for the user, Red relies on what the OS provides, and minimizes all other dependencies. And the more options we support, even at the OS level, the more we have to keep up with. Rebol learned this lesson the hard way. At one time it ran on 43 OSs, but unless you have a champion for each one, who is dedicated long term, features and robustness can easily become very uneven.
- GiuseppeChillemi
- 21:43@endo64 I'll take a look at your version during the weekend.
- Moppy_gitlab
- 01:59OpenGL is intended to be cross-platform, though I guess there's caveats to that. Nuklear's approach sounds pretty appealing, and like something Red would be well suited for.
>It was designed as a simple embeddable user interface for application and does not have any dependencies, a default render backend or OS window/input handling but instead provides a highly modular, library-based approach, with simple input state for input and draw commands describing primitive shapes as output. So instead of providing a layered library that tries to abstract over a number of platform and render backends, it focuses only on the actual UI.02:00https://github.com/Immediate-Mode-UI/Nuklear
- Oldes
- 09:44Problem with these immediate UIs is, that you must draw everything on each frame. So it is not the best choice for generic tools. It is fine as a debug overlay for a game, where you draw everything anyway.11:27But when reading the [Nuklear documentation](https://immediate-mode-ui.github.io/Nuklear/doc/index.html), it is possible not to draw on each frame and instead call
do_ui
when needed.. and as it just fills buffer with draw commands, it could work even with current Red.
- Moppy_gitlab
- 22:30
t: [
p [" " <p> 'val " " </p> "^/^/"]
img [" " <img src= 'val]
alt [" " alt= 'val > "^/^/"]
]
probe t/p
probe t/img
why am I getting this output?
[" " <p> 'val " " </p> "^/^/"]
[" "
<img src= 'val]
alt [" " alt= 'val > "^/^/"
]
22:30I'd like probe t/img
to give [" "
23:54img ["^-^-"
"^/^/"]
so here, if I want to replace val
with something else, because val
is in a tag, replace
isn't going to work.
- greggirwin
- 23:57It works fine.
>> tag: <img src= val alt= val >
== <img src= val alt= val >
>> replace copy tag "val" "ABC...XYZ"
== <img src= ABC...XYZ alt= val >
>> replace/all copy tag "val" "ABC...XYZ"
== <img src= ABC...XYZ alt= ABC...XYZ >
- Moppy_gitlab
- 23:57maybe to-tag?23:57okay, I see
- greggirwin
- 00:00Play with some other types as the replacement value, to see how they work. You can also see the source for
replace
, which is more involved than you might expect.
- Moppy_gitlab
- 00:15this is more or less, what I was expected
>> g: %ex.jpg
== %ex.jpg
>> tag: <img src= val alt= val >
== <img src= val alt= val >
>> replace tag "val" g
== <img src= ex.jpg alt= val >
>> replace tag "val" load g
== <img src= ex.jpg alt= make image! [708x1000 #{
FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF...
00:16I've gotten the result I wanted out of the generator now.00:17I don't know how pages are generally dynamically generated in "web 2.0" sites, but this is a start. 00:18Red as a "data-driven" language seems well suited for web dev considering that's mostly markup.
- Oldes
- 07:55You are not making valid HTML tags!
- Moppy_gitlab
- 08:02@Oldes what do you mean?08:02seems to work 08:02page comes out fine 08:02
form
does all the work
- Oldes
- 08:04
is not what you should use in a HTML page.
08:05Yes.. after all these years.. browsers are very forgiving... but that does not means, that you should not generate valid pages... you should find [some HTML validator](https://validator.w3.org/) to see what all is wrong.
- Moppy_gitlab
- 08:08@Oldes I didn't actually use that08:08that was just to see what would happen08:09my actual output looks like this
- Oldes
- 08:10Ok then.
- Moppy_gitlab
- 08:11any information on how to use
and stuff like that with Red?08:13here maybe https://helpin.red/CGI-Processingwebforms.html08:14seems to be about Rebol though
- ne1uno
- 08:15there's a video series on youtube using parse for markdown and @Bitbegin has red-markdown on github. just for the basic proof of concept. they seem unfinished08:18probably a form vrs mold explorer on http://gist.github print does form and probe does mold?
- Moppy_gitlab
- 08:22
Red []
mid: function[
element [series!] input
] [
head insert skip copy element 2 reduce ["^/" input "^/"]
]
tag-mid: function [
element [series!] inputs
] [
out: copy/deep element
foreach input inputs [
head replace out/2 "redval" input
]
out
]
t: [
doctype [<!DOCTYPE html> "^/"]
html ["" <html> </html>]
head ["^-" <head> "^-" </head> "^/"]
title ["^-^-" <title> "^-^-" </title>]
body ["^-" <body> "^-" </body>]
p ["^-^-" <p> "^-^-" </p> "^/^/"]
img ["^-^-" <img src= redval alt= redval > "^/^/"]
styled-img ["^-^-" <img src=redval alt=redval style=redval> "^/^/"]
form ["^-^-" <form action=redval method="Post"> "^-^-" </form> "^/^/"]
input ["^-^-^-" <input type=redval id=redval name=redval value=redval> "^/"]
br [<br>]
]
page: [
t/doctype
mid t/html reduce [
mid t/head mid t/title "^-^-^-Example"
mid t/body ;this is where all of a site's actual content goes
compose/deep 'contentx
]]
form-page: function [a-page content] [
replace a-page/5 'contentx [content]
form reduce a-page
]
08:22this is what I wrote. Best part is I can immediately understand it. 08:30for writing cgi scripts, this seems to be the most up to date source https://github.com/red/red/wiki/[DOC]-Using-Red-as-CGI
- ne1uno
- 08:34maybe @rebolek html tools for form post or get
- rebolek
- 08:35Yes, I have some html tools and also a dialect for producing HTML from Red.
- Moppy_gitlab
- 09:06hmm, I'm not sure cgi is necessary. 09:06to use the
tag and a reverse proxy09:06not sure how I'd retrieve that information though09:10http?
- rebolek
- 09:14@Moppy_gitlab you need to be running HTTP server. You can run either some 3rd party webserver (Apache, lighttpd, nginx, ...) or use the IO branch and run Red webserver (but that’s experimental and unfinished yet).
- Moppy_gitlab
- 09:14I've gotten nginx to run before 09:15getting something from
and then sending it to a Red program is what I'm not sure of
- rebolek
- 10:17see the wiki page you posted, setup Red as CGI and then use
input
to read POST data and printenv
to read GET data. Or use wrappers in my HTTP tools that would make it easier.
- dsunanda
- 16:42Simple question - I hope :) - how do I successfully reLOAD a SAVEd map?
m: make map! []
put m 'key make object! [data: 1]
save %m.txt m
m: load %m.txt
select m 'key
== make ;; <=== was hoping for the object
- hiiamboris
- 16:45using Redbin
- dsunanda
- 17:40Thanks! (It's easy when you know how :)
- cosacam1
- 02:39Hi guys, yesterday I made a question in the wrong room. Here I go again: I've been working recently. I'm creating a face (so to call it) which is actually a scrollable list of checks and multiline texts. However, my red.exe has stopped working. I use REEDITOR-11 and it still compiles ok (so slowly!) but it can't interpret because red.exe is broken. I can't use the console any more for the same reason (actually the GUI console is red.exe). It opens and close inmediatly. I've been googling but all I find is same problem with cmd for many users. But cmd works fine in my laptop. Only red.exe doesn't. Any suggestions? -- Someone gave me this https://github.com/red/red/issues/5073 -- I did what stated there (use rebol to compile gui-console) here is rebol output -=== Red Compiler 0.6.4 ===-
Compiling F:\red\red\environment\console\GUI\gui-console.red ...
...compilation time : 6252 ms
Target: Windows
Compiling to native code...
...compilation time : 127928 ms
...linking time : 3389 ms
...output file size : 1226752 bytes
...output file : F:\red\red\gui-console.exe
== none --- but actually the gui-console.exe does absolutely nothing Help please
- gltewalt:matrix.org
- 04:23Your anti-virus is squashing it04:25Look in quarantined files
- hiiamboris
- 09:45You need to compile consoles using command lines in some of the last posts on that issue for them to give you output.
- Oldes
- 09:45@Moppy_gitlab with each use of
"^-"
you are loosing at least 8 bytes. You should use TAB
instead. Or #"^-"
(char instead of string).
- hiiamboris
- 09:46If it's AV, wouldn't it delete the compiled GUI console?
- Oldes
- 09:47@cosacam1 use CLI console instead and run it from command line. So in case of errors you should see the output.
- gltewalt:matrix.org
- 12:49Nope, sometimes it just copies it to quarantine, or moves it on the first attempt to run the exe.
red.exe blipping and then quitting / disappearing is classic AV.
In days of yore it happened to me all the time.
- ne1uno
- 13:00earlier version ran ok?
- gltewalt:matrix.org
- 13:06Anyway it's easy to check. Turn off AV. Compile, Run.
Eliminate that possibility.
- dsunanda
- 23:06False positives from AV is a total pain for small developers - eg: https://www.nirsoft.net/blog/2009/05/antivirus-companies-cause-big-headache.html
You probably don't need to turn it off entirely - you'll have options to whitelist folders or files.
- Moppy_gitlab
- 03:05@Oldes good to know
- bubnenkoff
- 13:05How to measure time to get function execute time?
>> a: now
== 5-Mar-2022/16:02:16+03:00
>> b: now
== 5-Mar-2022/16:02:19+03:00
>> a - b
== 0
>> b - a
== 0
- pekr
- 13:15you can use
now/precise
.... but we've got a dt
(time-it
) function for such purposes already. You can use source dt
to look into what it is doing.
- bubnenkoff
- 13:20thanks!
- greggirwin
- 17:12If you use
now
or now/precise
yourself, use difference
instead of subtract
.
But it looks like we have a regression in date math.
>> c: now
== 5-Mar-2022/10:11:10-07:00
>> d: now
== 5-Mar-2022/10:11:15-07:00
>> c - d
== -1
>> d - c
== -1
Should be 0
. There was a date ticket fixed not long ago, which may be the cause.17:13If someone can confirm, would you please open a ticket for it?
- hiiamboris
- 17:18
>> a: now
== 5-Mar-2022/20:19:35+03:00
>> b: now
== 5-Mar-2022/20:19:37+03:00
>> a - b
== 0
>> b - a
== 0
>> about
Red 0.6.4 for Windows built 22-Feb-2022/5:26:32+03:00 commit #8126da7
>>
17:19hmm
>> a/zone: -7
== -7
>> b/zone: -7
== -7
>> a
== 5-Mar-2022/20:19:35-07:00
>> b
== 5-Mar-2022/20:19:37-07:00
>> a - b
== -1
>> b - a
== -1
17:20zone 0
seems to be the turning point17:22it's also buggy in 0.6.417:23maybe it's correct, we just don't know how it works?17:24R2 gives 0 in both cases though
- greggirwin
- 17:25Interesting. Thanks for the R&D @hiiamboris. :+1:17:26If the zone is the same for both dates, there should be a zero day difference.
- hiiamboris
- 17:27so should the calculation be done in the zone of the 1st operand?17:28or should it return truncated number of 24h intervals?
- greggirwin
- 17:29That sounds reasonable, though my brain is split right now.
- hiiamboris
- 17:32\* imagines how Gregg plugs his brain to a steam generator and extracts electricity :)17:35R2 buggy as well?
>> a
== 1-Jan-2001/11:11:11-12:00
>> b
== 1-Jan-2001/11:11:11+13:00
>> a - b
== 0
>> b - a
== 0
either way this should not be zero
- greggirwin
- 17:44Given two identical dates, with one being in zone +24 or -24, we're at +/-1. The real world range is -11 to +14 but Red wraps at +/-16, 16 being the same as 0. Truncating makes sense here, since you're max zone diff is modulo'd.
I don't think R2 is buggy, because the world is round. But Maybe. Let's ask some people in Samoa and Niue if they argue about which day it is. I might need a) coffee, b) to draft a viz, c) focus. I have a meeting in an hour so have to do some other work right now.
- hiiamboris
- 17:48R2 seems to ignore TZ completely?17:49I'll make an issue for further discussion
- greggirwin
- 17:51> but
-12
and +13
are 25 hours apart
Which isn't possible in a 24-hour day, given that the date is the same. If we leave a location at the same time, flying in opposite directions, how far apart are we 12.5 hours later?
- hiiamboris
- 17:53I think you're missing critical part of timezone arithmetic here: if I'm living in
+13
zone and you are in -11
zone, then when my date is Jan 1
, your is Jan 2
17:54Though we're on the same meridian
- greggirwin
- 18:01Ah, we may be crossing our lines. <ba-doom-cha!> For this arithmetic, do we want the difference in *dates* or number of *days*. This is where I need to be able to step back and think about how the results will be used to calc other dates, etc.
- hiiamboris
- 18:06Exactly18:06https://github.com/red/red/issues/5095
- gltewalt:matrix.org
- 18:06Easier as a giant circular list
- greggirwin
- 18:09Thanks for writing that up @hiiamboris. :+1:
@gltewalt:matrix.org, making a visual tool for this will also be good, to help people understand it. We've talked in the past about a time-clock app, and I still want to do that.
- gltewalt:matrix.org
- 18:10I found it difficult back in the day, but then I've always been not so talented 18:12But timezones around the world are effectively a circular list, due to the whole globe thing.
- hiiamboris
- 18:16most controversial region: https://en.wikipedia.org/wiki/Time_in_Antarctica18:17technically you can have midnight 10 times a day if you move from zone to zone :)
- greggirwin
- 18:21And also the fun of daylight savings changes. Skip an hour or see the same one twice.
In this case, it *seems* like we can just convert to UTC and do the basic math, but that may be what happens internally now, which is bugged.
- dsunanda
- 18:33An oldie, but perennially true -- Falsehoods programmers believe about time: https://gist.github.com/timvisee/fcda9bbdff88d45cc9061606b4b923ca
(and regarding the second item on that list - never forget Sweden once had 30 February).
- gltewalt:matrix.org
- 19:15Have to pick a "good enough" outcome19:35Looks like
/precise
is rounding
- ne1uno
- 20:12convert to julian if best guess more than 23 hour difference20:26https://gist.github.com/luce80/96d48297f2307a713c918c68bf046520#file-dates-calcs-red
- cosacam1
- 04:07hi guys again. well i had no AV running by the time I posted my issue. I couldn'y use CLI instead because it didn't showed up. Anyway I reinstalled W10 and here I am running again RED.exe succesfully. And I didn't dissapeared, I'm just a very busy man in several ways, and I don't have internet access all the time (I could have it using my phone but the screen is small and Gitter shows a purple ad which covers most of my screen) and blah, blah. besides, when I try to login Gitter via Github it always sends me a 6 digits code to my gmail account. So I need to enter gmail and read the code and enter it to Gitter. Why? I don't know. Ok I'm working. Thanks everybody. One question: how can I use size-text prior to defining the face. I mean- I wanna know the size a text will have in a future (non existing yet) face so I will create the face with a size where this text fits. I'm using fixedsys font so every char has the same width. Is there something in red like systemmetrics? Thanks
04:57Here's my code:04:57Red [needs: view]
txt: "qwertyuiop asdfgh jkl zxcv bnm"
line-height: 2 * char-width: 12 ; in pixels
chars-per-line: 10
len: length? txt
lines: max 1 to-integer len / chars-per-line ; amount of lines used by txt, at least one
sz: as-pair (chars-per-line * char-width) (line-height * lines) ; size of txt in pixels
view [
text txt sz wrap font-name "Fixedsys"
]
- bubnenkoff
- 07:45My favorite question -- is there any progress with ports. I still need http timeouts...08:31My http application started to behave strangely.
The http responses are always two seconds or more.
I can't figure out what the reason is.
I created a minimal http server and checked on it.
I get:
>> print ttt.
0:00:02.04055
The server is https://gist.github.com/bubnenkoff/ca2ac7a0b3ed4522776050edfa31466c
Application:
http://localhost:5000/test
insert-query: [{}
ttt: dt [
send-request/data to-url http://localhost:5000/test 'POST object [
sql: to-json insert-query
]
]
print ttt
For http requests I am using https://github.com/rebolek/red-tools/blob/master/http-tools.red
08:42* insert-query: [ {} ]
08:55it's seems that this issue is happens only with local http server. I tested it with public, and response time is normal:
do https://raw.githubusercontent.com/rebolek/red-tools/master/http-tools.red
insert-query: [{}]
ttt: dt [
send-request/data/verbose to-url http://www.thomas-bayer.com/sqlrest/ 'POST object [
sql: to-json insert-query
]
]
print ttt
09:02I have tested it on two PC. Behavior is same. Very slow access to local http server and fast to external.
Do you have any ideas?
- toomasv
- 12:20@cosacam1 I played with the idea, but the result is probably a bit too complicated:
rt: none
get-size: function [text font letters /extern rt][
replace/all text lf ""
either rt [
rt/text: text
repend clear rt/data [as-pair 1 length? text font/1 font/2]
][
rt: rtd-layout probe compose/only [font (font) (text) /font]
rt/size: 2000x600
]
sz: size-text rt
lt: round/ceiling/to sz/x / length? text 1
while [not empty? text: skip text letters][text: insert text lf]
rt/text: head text
x: letters * lt
y: sz/y * round/ceiling/to sz/x / x 1
rt/data/1/2: length? rt/text
as-pair x y
]
txt: "qwertyuiop asdfgh jkl zxcv bnm"
sz: get-size txt ["Consolas" 9] 10
view [rich-text sz with [text: rt/text data: rt/data]]
- cosacam1
- 18:08Thanks toomasv for your help. I've been studying it. It's interesting- 1) basically create a rich-text with the desired text and font; 2) use size-text to get the actual size in the rich-text; 3) insert linefeeds at 'letters' intervals (where letters is the desired amount of characters per line) 4) assign the modified text to the rich-text; 5) then getting and returning the actual size of the text after splitted in several lines. Some doubts: a) what is the '/font' at the end of rt: rtd-layout probe compose/only [font (font) (text) /font]; b) what are the refinements '/1/2' at rt/data/1/2: length? rt/text (I did ? rich-text and ? rtd-layout at CLI but I couldn't see any explanation of data). Finally, when I run your code, not all the text is shown. Thanks anyway. Meanwhile I managed to solve my problem yesterday. Here's my code:
Red [needs: view]
txt: "qwertyuiop ASDFGH jklzxcv bnm"
line-height: char-width: 16 ; in pixels
chars-per-line: 10
len: length? txt
lines: max 1 round len / to float! chars-per-line ; ammount of lines used by txt, at least one
sz: as-pair (chars-per-line * char-width) (1.6 * line-height * lines) ; size of txt in pixels
; 1.6 :: leave some vertical space for descendant characters like fgjpqy
print [len lines sz]
view [
text txt sz yellow wrap font [name: "Consolas" size: line-height]
]
- toomasv
- 19:05@cosacam1 You got it! I did it so the text can be splitted at any number of letters, not only on word borders. (Well, actually I did that too.)
You'll get answers to your questions in rich-text [doc](https://github.com/red/docs/blob/master/en/rtd.adoc). If not, ask away and I'll try to answer, if I can :)
- cosacam1
- 21:21Thanks so much Toomasv
- toomasv
- 04:14You are welcome!
- djrondon
- 12:56Hi Folks, Is there a documentation with examples of read/as mime-types csv, json, etc.?
- ne1uno
- 13:01@djrondon, try https://github.com/red/red/wiki/Common-tasks-and-how-to-do-them-in-Red-(for-Python-programmers)
- djrondon
- 13:06thanks @ne1uno , Cool! :-;13:31
Unable to init server: Could not connect: Connection refused
(console-2022-3-10-85264:2089400): Gtk-WARNING **: 13:29:13.824: cannot open display:
- hiiamboris
- 14:01you need xserver running14:03or build console without View support
- djrondon
- 14:22so I have to compile. I thought that the option red --cli would allowed me just with the console without GUI. I don't have problems with the latest stable release, but with latest build.14:22the latest stable version, red --cli is working14:32I'm using the linux version, I think that latest build for linux is not prepared for the --cli option
- ne1uno
- 14:34stable is years old, before gtk view. would need 2 executables: view and no view
- djrondon
- 14:36I just want to use the console, because I don't have the GUI
- ne1uno
- 14:43you can get non gui rebol from http://rebol.com/download-core.html 14:50https://github.com/red/red for source, the readme shows options for building or running the console
- djrondon
- 15:14Ok. @ne1uno, I will do this.15:33thanks @ne1uno . It worked!21:17using the red console on linux, how can I give bold type as we can use in bash
\033[1mresults:\033[0m
echo -e "\033[1mresults:\033[0m"
- hiiamboris
- 21:24red char codes are hexadecimal, not octal21:24
^(1B)
21:24or ^[
21:24https://w.red-lang.org/en/datatypes/char
- djrondon
- 21:25Thanks
- djrondon
- 01:36I compiled the console from the sources, but I couldn't compile my .red file with the new console, just with the old version.
- ne1uno
- 02:08to compile, the build needs the sdk but it's no longer available. you can run red source from rebol.02:24the error message could be improved
- djrondon
- 02:25it's running ok, I just thought to generate the binaries with libRed02:25but it's ok anyway02:26I tried to run console -c -t Linux prog.red02:26console is ok and up to date
- hiiamboris
- 09:08You can use Rebol to compile, like you did to create the console itself.
- ne1uno
- 14:02 header requires
Needs: ['csv 'json]
when compiling
- hiiamboris
- 15:14it's already in the header
- ne1uno
- 15:18
Script Error: path element > header < does not apply to unset! type
15:18'csv15:20no error at compile
- hiiamboris
- 16:02you're on the old console?
- ne1uno
- 16:05just tried again w/recent latest
Red 0.6.4 for Windows built 8-Mar-2022/17:31:19-04:00 commit #b0e5493
16:06win10
- hiiamboris
- 16:12https://github.com/red/red/blob/master/environment/console/CLI/console.red#L6
- ne1uno
- 16:18why does the error go away when I add needs 'csv?
- hiiamboris
- 16:48ㄟ( ▔, ▔ )ㄏ
- bubnenkoff
- 19:10If I am compiling Red from sources will I would be able to use it fully as official builds? I an asking because I tried build
odbc
-branch, but I was not able to use result to compile my project because it did not recognized -c
option and probable some others. Or I need to do some more manipulation to get own build work as I am expecting?
- hiiamboris
- 19:19you can only compile consoles19:19and you can use the rebol compiler directly from rebol19:20the launcher (which recognizes
-c
) is not compiled, it's packaged with Rebol/SDK
- mikeyaunish
- 20:45Didn't notice this change until now.
The last version of Red (that I have) that the reaction works properly is:
Red 0.6.3 for Windows built 24-May-2018/7:28:58-06:00 commit #ba9cabe
view [
output: panel 200x200 gray
button "load layout" [
output/pane: layout/only load {
b1: button "move me" loose
f1: field react [ f1/text: to-string b1/offset ]
}
]
]
To test it, click on the "load layout" button, then move the button labelled "move me". The text field should reflect the offset position of the button.
No idea if this was meant to be a permanent feature of react
or not?
- hiiamboris
- 21:30looks like reactions get cleaned up during pane change and never recovered?21:30make an issue anyway, it's a great case to think on design
- mikeyaunish
- 00:40@hiiamboris thanks for confirming. I will make an issue.
- bubnenkoff
- 10:37> the launcher (which recognizes
-c
) is not compiled, it's packaged with Rebol/SDK
But that how red.exe works? I can compile all with them without Rebol
- hiiamboris
- 10:39red.exe is an R2 script (red.r) wrapped into an exe
- bubnenkoff
- 10:40Wow! I even can't imagine it!10:41But why Rebol is still needed? What futures it have that Red have not?
- hiiamboris
- 10:42temporary compiler that we are using is written in Rebol
- bubnenkoff
- 10:44But what need to be implement to get Red self-hosted?
- hiiamboris
- 10:45just porting it to Red is a task team does not see very useful right now (although I believe there was an attempt by @oldes but it didn't work)
- bubnenkoff
- 10:47@hiiamboris and what status of
ports
branch? I have seen some activity there. When it would be merged?
- hiiamboris
- 10:47plan I think is, when we rewrite the compiler, we make it solid, so it's a big task10:48> @hiiamboris and what status of
ports
branch? I have seen some activity there. When it would be merged?
no idea :) you know how far plans usually go.. something happens along the way and the plan is scratched
- Oldes
- 10:48I was porting it to Rebol3 actually. But I don't have time for it and no need as well.
- hiiamboris
- 10:48thanks for clarifying10:50anyway, Red changes a lot, so writing compiler in it right now would mean spending time maintaining it in a constantly changing environment
- Oldes
- 11:08Even the compiler written in Rebol is changing quite a lot, so it would be waste of time to do some real porting when there is no will to use it anyway. One would have to constantly follow all changes. Not to mention, that there is zero documentation and just a very few comments in the source.
- loziniak
- 12:14
>> change-dir probe %prj
%prj
== %/home/maciek/prj/
>> cd ..
== %/home/maciek/
>> cd probe %prj
*** Access Error: cannot open: %/home/maciek/probe/
*** Where: do
*** Near : args
*** Stack: cd change-dir cause-error
Is there a reason why cd
acts like that?
- hiiamboris
- 12:41@qtxie ?
- loziniak
- 12:59it's probably same as with
pwd
– meant only for console use?
- hiiamboris
- 13:14yep
- redredwine
- 16:42parse question - If I have a string that already contains " " , how do i set a rule to include the quote in the string? e.g <a href="blablabla"> . I think rebol allows us to use { <a href="blablabla">}. but not sure how to handle that in Red.
- hiiamboris
- 16:46have you tried the same in Red?
- bubnenkoff
- 16:11Is it possible to get selected text from
area
?
- hiiamboris
- 16:14try
view [area "a^/bc^/def^/1234" rate 1 on-time [attempt [probe copy/part face/text face/selected + 0x1]]]
- bubnenkoff
- 16:23thanks!
- toomasv
- 17:12@hiiamboris Dunno, this didn't do a thing for me on W10 :flushed:
But this did:
view [area "a^/bc^/def^/1234" rate 1 focus with [selected: 1x1]
on-time [if (length? face/text) = face/selected/2: face/selected/2 + 1 [
probe "done" face/rate: none
]]]
- hiiamboris
- 17:14have you selected any text for it to "do the thing"? ;)
- toomasv
- 17:27Ha, something is happening :baby:
- hiiamboris
- 17:33:+1:
- redredwine
- 00:26@hiiamboris i tried the {} again today, it works. Thanks. Not sure what happened the other day.
- GiuseppeChillemi
- 07:07How could I know if a datatype is part of a superset datatype? I mean: how could I know if
integer!
is part of number!
?
- rebolek
- 07:08
find number! integer!
- cloutiy
- 15:16Interesting
- GiuseppeChillemi
- 20:36I don't understand why of used in a block, I have to
get
it, otherwise I could use it directly.
- hiiamboris
- 22:12then you probably do not understand that *block is not evaluated*
- GiuseppeChillemi
- 09:20And where is written that a
datatype
is evalated before being interpreted? I have always thought of it as a terminal value.09:22@rebolek
> find number! integer!
Is there a way to query integer for its parent without searching all datatypes?
- rebolek:matrix.org
- 09:25What do you mean by "evaluated before interpreted"?
integer!
is a word!
that evaluates to integer datatype.
- GiuseppeChillemi
- 09:34
Integer!
has been for me always a datatype!
, I mean a type of its own with different characteristics than word!
because I have never read what you Rebolek and Hiiamboris are writing. It is written nowhere in Rebol Core doc. I am 20 in Rebol and i have never encountered anything about this fact.09:37And when you read here: http://www.rebol.com/docs/words/wtypeq.html that /word - Returns the datatype as a word
you think that the datatype is a "datatype" and not a word and then if you need it as a word, you must use /word
refinement in type?
- rebolek:matrix.org
- GiuseppeChillemi
- rebolek:matrix.org
- 09:42So why
integer!
should be different? It's a word, don't let the exclamation mark confuse you, is just a convention that works holding datatype value end with it.
- GiuseppeChillemi
- 09:44Yes, it was the exclamation mark that has led me to think it was not a
word!
but a datatype!
. It's because of the symbolic decoding of the brain...
- rebolek:matrix.org
- 09:52For example
mydatatypename!: :integer!
- GiuseppeChillemi
- 09:53A whole world opens.09:54Is there any extra info I should know about using datatypes? Like the magic of
find number! integer!
?
- hiiamboris
- 10:21typeset is a kind of bitset, no other magic
- endo64
- 11:01Just type
number!
in the console and you see it:
>> number!
== make typeset! [integer! float! percent!]
or better, type >> ? typeset!
- GiuseppeChillemi
- 16:55@hiiamboris so, no special accessor?
- hiiamboris
- 17:12what accessor?
- greggirwin
- 19:08> Is there any extra info I should know about using datatypes? Like the magic of
find number! integer!
?
You can think of it *kind of* like find
on a series, but more accurately, as @hiiamboris noted, like find
on a bitset.
We should into to [bitset docs](https://github.com/red/docs/blob/master/en/datatypes/bitset.adoc) on pick/poke/find
and things like enbasing.19:12> But, is there a way to let Red recognize mydatatypename!
as datatype
when using type?
My canonical example for this is aliasing issue!
as hashtag!
. You have the type name and the type query func (i.e. issue!
and issue?
), which can be quite usable in many cases, but may be a liability in the grand scheme of things.
- GiuseppeChillemi
- 21:06What could go wrong?
- greggirwin
- 22:08It's not that something would "go wrong", as this is just another flexible part of Red. What I mean by being a liability is that programming in the large using *any* trick means more coordination. But I do think that the added meaning can be useful, especially in dialects.
- hiiamboris
- 19:35Have you guys ever needed or used this function?
>> ? distribute
USAGE:
DISTRIBUTE amount weights limits
DESCRIPTION:
Distribute a numeric AMOUNT across items with given WEIGHTS.
DISTRIBUTE is a function! value.
ARGUMENTS:
amount [number!] "Any nonnegative number."
weights [block!] {Zero for items that do not receive any part of AMOUNT.}
limits [block!] {Maximum part of AMOUNT each item is able to receive; NONE if unlimited.}
>> distribute 100 [1 2 1] [2e9 2e9 2e9]
== [25 50 25]
>> distribute 100 [1 2 1] [99 99 99]
== [25 50 25]
>> distribute 100 [1 2 1] [99 40 99]
== [30 40 30]
>> distribute 100 [1 2 1] [99 40 20]
== [40 40 20]
>> distribute 100 [1 2 1] [30 40 20]
== [30 40 20]
>> distribute 100 [1 0 1] [99 40 20]
== [80 0 20]
19:37I'm just curious because I wrote it for Spaces, but it looks like something that *can* be generally useful.
- GiuseppeChillemi
- 00:20I have neverused it, but It resembles a function that I have just written to calculate the column size for listviews, after scanning the column data.
- toomasv
- 08:32I haven’t used it, but looks very interesting.
- bubnenkoff
- 08:42How to make yellow panel take full width?
view [
panel red [ ]
panel blue [ ]
return
panel yellow []
]
- hiiamboris
- 09:15'panel 210 yellow' or smth like this.
- bubnenkoff
- 09:18Only way to set absolute size?
- toomasv
- 12:36Use
parent/size
12:36With with
- hiiamboris
- 12:40Alternatively, with https://gitlab.com/hiiamboris/red-elastic-ui you can write:
view elastic [panel red [] panel blue [] return panel #fill yellow []]
and also get automatic resizing if you enable it in flags
- ne1uno
- 13:10
react [face/size/x: face/parent/size/x - 15]
add after the item. I don't really understand how this works and it might miss some resize events
- hiiamboris
- 13:28should be
- 20
?
- GiuseppeChillemi
- 16:41While experimenting with
select/skip
I have told to my self, lets see if...
>> type? select/skip [a b c none] 'c 1
== word!
>> type? get select/skip [a b c none] 'c 1
== none!
And yes, it is!
- hiiamboris
- djrondon
- 00:58Is there any jwt library for red?
- greggirwin
- 01:04I think @rebolek started one, as did I. Need to dust it off and see what state it's in.01:06[json-web-token.red](https://files.gitter.im/5780ef02c2f0db084a2231b0/wKD6/json-web-token.red)
- djrondon
- 01:42thanks @greggirwin ;-)
- rebolek
- 05:44@djrondon Yes, I have JWT library, I’m not sure if it’s online.
- planetsizecpu
- 07:13> Have you guys ever needed or used this function?
>
> >> ? distribute
> USAGE:
> DISTRIBUTE amount weights limits
>
> DESCRIPTION:
> Distribute a numeric AMOUNT across items with given WEIGHTS.
> DISTRIBUTE is a function! value.
>
> ARGUMENTS:
> amount [number!] "Any nonnegative number."
> weights [block!] {Zero for items that do not receive any part of AMOUNT.}
> limits [block!] {Maximum part of AMOUNT each item is able to receive; NONE if unlimited.}
>
> >> distribute 100 [1 2 1] [2e9 2e9 2e9]
> == [25 50 25]
> >> distribute 100 [1 2 1] [99 99 99]
> == [25 50 25]
> >> distribute 100 [1 2 1] [99 40 99]
> == [30 40 30]
> >> distribute 100 [1 2 1] [99 40 20]
> == [40 40 20]
> >> distribute 100 [1 2 1] [30 40 20]
> == [30 40 20]
> >> distribute 100 [1 0 1] [99 40 20]
> == [80 0 20]
>
@hiiamboris I never used distribute
but I know at least one use case where it fits perfect: stock piling. When you have some number of items on one store location and have to distribute it to other locations wich have their own space limitations. As an example imagine a 40ft container filled with fencing grid rolls, to distribute along the shelves of a warehouse wich already have other older rolls. Userful, if you can subtract from the shelves location max loading value the already existing stock, that number would be the max value by location for the distribute
func.
- bubnenkoff
- 08:27Am I right understand that if I am using
throw
function on success should always return none
at the end?
foo: function[] [ print "foo1" if (x > 1) [throw "x is greather than one"] return none]
result: catch [ foo ]
probe result
- hiiamboris
- 08:36Yes.08:37@planetsizecpu thanks. Indeed, I'm using it after subtracting the current values too.
- GalenIvanov
- 10:21@hiiamboris The closest thing to
distribute
I remember I needed was in this [Pie-chart-direct-interface](https://github.com/GalenIvanov/Pie-chart-direct-interface). It's a good function to have.
- hiiamboris
- 10:22dead link10:22or private?
- GalenIvanov
- 10:23oh, sorry - a private one10:25Do you see it now?
- hiiamboris
- 10:26yes, thanks10:27so there was a minimum limit for each slice?10:31well I guess pie charts can use a simpler algorithm, just divide the circle
- GalenIvanov
- 10:31The minimum is 1% of the circle, since the sectors indicate the contribution of the 5 possible types to 100%10:31Yes, indeed
- hiiamboris
- 10:32an interesting use case anyway, thanks
- GalenIvanov
- 10:32:+1:
- hiiamboris
- 10:33also interesting is how to make slices logarithmic in scale
- bubnenkoff
- 10:49What is the proper way to not break loop, but just stop iteration and continue it from same place?
foo: function[] [
foreach el ["aa" "bb" "cc" "dd" "ee"] [
if (el = "bb") [
; user need do some action in UI before continue iteration
]
]
]
foo
- hiiamboris
- 10:51in existing UI or you can show a new dialog?
- bubnenkoff
- 10:52In existing
- hiiamboris
- 10:57
flag: off
view [
base yellow "click to start loop"
on-up [
foreach el [1 2 3 4 5] [
print el
if el = 2 [
while [not flag][do-events/no-wait]
]
]
]
base blue "click to continue" on-up [flag: true]
]
- bubnenkoff
- 10:59Thanks for example!!
- hiiamboris
- 11:01it's not a good practice though, you should weigh if it's necessary
- bubnenkoff
- 11:05what problems this approach have? 11:05infinity loop?
- hiiamboris
- 11:11for example, you can reenter into this loop many times by clicking yellow base11:11of course you can work around that, but such code flow will be hard to predict and debug11:13also, idk what will happen if you close the window before loops finish :)11:13maybe it'll work, maybe not
- bubnenkoff
- 11:19So it's better to display modal window?
- hiiamboris
- 11:46yes
- bubnenkoff
- 11:49ok. Is it possible to display same list in main and new modal
view
?
view [
list: text-list data ["aaa" "bbb" "ccc"] [ print list/selected ]
button "modal" [
view [
list ; I want to display same list
]
]
]
- hiiamboris
- 12:03
view [text-list data list/data]
- bubnenkoff
- 12:04thanks!
- greggirwin
- 17:28
Distribute
is a very nice func. I haven't used it exactly, because things needed to be in order, but I did a disc production system that needed to group data and then sort by what kind of disc to use (CD or DVD).
- bubnenkoff
- 17:39Is it possible to display non-modal window/zone in main app window?
- hiiamboris
- 18:15what do you mean by that?
- ne1uno
- 18:17docked? you can make a group or panel
loose
- bubnenkoff
- 07:07I mean creating not blocking dialog. For example ask user about some action without creation new window
- dsunanda
- 08:41@bubnenkoff You probably want to use a technique like sub-panels - a way to switch in and out parts of the window display. The old Rebol website has some examples - you need to edit these very slightly as Rebol's VID dialect is not quite the same as Red's (eg VH2 --> H2 etc)
http://www.rebol.com/how-to/subpanels.html
- endo64
- 08:58you can set a layout's parent to a window to show it inside:
layout/parent [button "ok" [unview]] view/no-wait [size 300x300] none do-events
- hiiamboris
- 09:09Or make a hidden panel in advance. Then show it when you want.
- bubnenkoff
- 16:51Thanks!
I also have plan to do small app for creation block-schemes. Which dialect it's better to use? Draw? Or there is something more suitable?
- hiiamboris
- 17:02https://gitter.im/red/red/gui-branch?at=6244113409092523184bb0cf
- greggirwin
- 17:04All those ideas would make a nice article.
- bubnenkoff
- 17:17> https://gitter.im/red/red/gui-branch?at=6244113409092523184bb0cf
Thanks, but if diagram dialect is not in active developing, than how I could try to solve this problem?
And which dialects have guarantees to have community support in future?
- greggirwin
- 17:19> And which dialects have guarantees to have community support in future?
Those that are included in standard Red releases.
- hiiamboris
- 17:48@bubnenkoff still better to fix it than to roll your own ;)
- bubnenkoff
- 09:43Does crossbuild works now? I want to build GUI app from Windows for Linux
- ldci
- 09:46@bubnenkoff Yes. I’m writting apps under macOS and can cross-compile for Windows and Linux without problems: just red -t target filenane :)
- rebolek
- 11:10It always worked.
- bubnenkoff
- 14:49
>> a
*** Script Error: a has no value
*** Where: catch
*** Near : a
*** Stack:
>> if not unset? 'a [print "value is exists"]
value is exists
>>
>> if (not unset? 'a) [print "value is exists"]
value is exists
>>
Why next code is show that value is exists, while it's not?
- hiiamboris
- 14:52
help unset?
14:53also source unset?
- ldci
- 15:07@bubnenkoff. Using ‘a creates a word.
Type? 'a —> word
, but a has no value
- bubnenkoff
- bubnenkoff
- 09:29I have block values for substitition in next format:
mydata: [ [1 "Dopey"] [2 "Doc"] [3 "Bashful"] [4 "Sneezy"] [5 "Happy"] [6 "Grumpy"] [7 "Sleepy"] ]
The function that accept prepared statment is accept data as:
insert snowwhite [
"INSERT INTO Dwarves (Num, Name) VALUES (?, ?)"
[1 "Dopey"] [2 "Doc"] [3 "Bashful"] [4 "Sneezy"] [5 "Happy"] [6 "Grumpy"] [7 "Sleepy"]
]
remember me please how to make from mydata list of blocks? to get:
[1 "Dopey"] [2 "Doc"] [3 "Bashful"] [4 "Sneezy"] [5 "Happy"] [6 "Grumpy"] [7 "Sleepy"]
foo: function[blk] [
probe blk
]
foo mydata
- hiiamboris
- 10:23mydata is already a block of blocks
- bubnenkoff
- 10:27So I can simply pass it without unwrapping?
- hiiamboris
- 10:33try it
- bubnenkoff
- 11:15
insert data-insert-statement reduce [
insert-part ; INSERT INTO lots ("purchaseNumber", "lotNumber", "deliveryTerm", "currency_code") VALUES (?,?,?,?)
["0373200040814000009" 1 "Some text here" "USD"] ; works
]
do not works:
insert data-insert-statement reduce [
insert-part
prepared-values-part ; [["0373200040814000009" 1 "Some text here" "USD"]]
]
error:
*** Script Error: ODBC error: ["07002" 32 {The # of IPD parameters 1 < 4 the # of parameter markers}]
*** Where: ctx||610~execute-statement
*** Near : param
So it seems that it's need it not as block of blocks
- hiiamboris
- 11:52seems so
- gurzgri
- 12:52First form: Simple block, gets
reduce
d
insert statement simple: ["SELECT INTO table VALUES (?, ?, ?)" a b c]
Second form: Param block, won't get reduced, therefor e.g. compose/deep
insert statement block: compose/deep ["SELECT INTO table VALUES (?, ?, ?)" [(a) (b) (c)]]
Third form: Param "array", won't get reduced
insert statement array: compose/deep ["SELECT INTO table value (?, ?, ?)" [(a1) (b1) (c1)] [(a2) (b2) (c2)] [(a3) (b3) (c3)]]
Strictly speaking, the second form is no form on it's own, it's just a special case of the third form / array form with array length of 1. 12:55But pretty much all of this is documented in https://github.com/gurzgri/red/blob/odbc/environment/schemes/odbc.md I pointed you to already, it's in the "Parameter Arrays" section.13:57@bubnenkoff Sorry, my bad - I see now that in private chat I edited your code sample such that there was this "inner outer block" ["SELECT ..." [[...] [...] [...]]]
(sic!) which I didn't noticed w/o beeing able to actually run the code. At least the documentation is correct on this.
- meijeru
- 15:21For a toy implementation of the WORDLE game (see [here](https://wordlegame.org/)) I would need to print letters in color on the console. I looked at rich text, but that seems to be for the GUI only. How can I use ANSI escape codes?
- gurzgri
- 15:25
print "^[[32mTest"
- meijeru
- 15:27Tried that, didn't work!
- gurzgri
- 15:29Works in Windows Terminal, might not work in other consoles.15:30~~Works in cmd.exe, too.~~ My cmd.exe runs in Windows Terminal, too, probably that's why it works.
- meijeru
- 15:36I tried in the Red console. @Qtxie what can you tell me?
- hiiamboris
- 15:38@meijeru your OS version?15:40https://superuser.com/questions/413073/windows-console-with-ansi-colors-handling/1050078#1050078
- meijeru
- 15:44@hiiamboris W11
- hiiamboris
- 15:45No idea there. On W10 ANSI is supported by default I think.
- meijeru
- 15:46@hiiamboris My desire is to have colors etc. show up in the Red console, not in the Windows console.
- hiiamboris
- 15:48In Red GUI console?15:48I don't think it's supported.15:54Use CLI or reinvent it.
- greggirwin
- 17:35There is experimental work on syntax highlighting in the Red console (IIRC), but that will probably be harder than other approaches right now.
- bubnenkoff
- 18:35> @bubnenkoff Sorry, my bad - I see now that in private chat I edited your code sample such that there was this "inner outer block"
["SELECT ..." [[...] [...] [...]]]
(sic!) which I didn't noticed w/o beeing able to actually run the code. At least the documentation is correct on this.
You mean that it's impossible to pass list of blocks like? [ [] [] [] ]
But I have problem to generate blocks for passing without nesting. Because I do not understand how to pass data to statement
Or I need way to deblock
it to make it as statement expected it.
- gurzgri
- 18:48Problems exists so that people start looking out for solutions. And the answer to that particular problem you are able to find out by yourself by now. Experiment in the console, help yourself with
help
. Even if that may cost a bit of *your* time, it pays back with more experience.
- ThatOneAlexDev
- 15:04Hey guys, pretty new to red. What's an effective way to concatenate multiple strings? In Java, i simply have the "+" operator. In red, i saw "append", but i'd have to type that for every new part. What's the best way to do that?
- hiiamboris
- ThatOneAlexDev
- 15:12Ohh rejoin works without a flaw, thanks!
- greggirwin
- 16:11Welcome @ThatOneAlexDev !
- ThatOneAlexDev
- 18:53Hey thanks!
- ThatOneAlexDev
- 18:58What does it mean if i have a file and there is just "context [...]" without any assignments? I often see a file start with "context [...]", where the context block contains the whole code. Does it just create an object with the file name or what does that do?18:59https://i.imgur.com/RwOhZyz.png18:59like that18:59Couldn't find it in any tutorial
- dsunanda
- 19:13@ThatOneAlexDev If you literally, have a file that begins with CONTEXT, you can load it and assign it to a word.....Simple example:
write %test.txt "context [a: 1 b: 2 c: func [][print a + b]]"
x: do load %test.txt
x/c
== 3 ; Result!
It's a way of saving and reloading Red data structures.
- gurzgri
- 19:14"anonymous" contexts these are. They are a common idiom often used as poor man's module system, probably setting (exporting) only selected global words but keeping most of their inner parts hidden in the context to not litter the global / the calling context.
- ThatOneAlexDev
- 19:16Thanks!
- ThatOneAlexDev
- 13:32What's the best way to extract the host of an url? For example: If the input is "https://example.site/users/10", i'd like to extract the host "example.site". I could not find it in any of the docs i'm using.13:33What are good docs anyway? Any suggestions?13:33Red by example is pretty useful, and helpin.red13:33Idk if there is anything better13:33besides looking at the source code
- hiiamboris
- 13:33
>> probe decode-url https://example.site/users/10
make object! [
scheme: 'https
user-info: none
host: "example.site"
port: none
path: %/users/
target: %10
query: none
fragment: none
ref: https://example.site/users/10
]
- cloutiy
- 14:36@ThatOneAlexDev another option once you have a bit more experience with red is extracting with
parse
- ThatOneAlexDev
- 15:06Yeah i've looked at that, just wanted to see if there is something implemented already, and decode-url is perfect
- greggirwin
- 16:47@ThatOneAlexDev something else you can do is use
help
with partial keys, or strings. e.g. ? url
or ? "url"
. Use help
(?
is a shortcut for it) by itself for more hints on how to use it.
- bubnenkoff
- 12:09Does
map
have any guaranies about ordering elements?
- rebolek
- 12:59No. It’s implementation dependent and you shouldn’t rely on any current order.
- hiiamboris
- 13:23@bubnenkoff
hash!
does
- bubnenkoff
- 14:13thanks!!
- bubnenkoff
- 09:36Is sees that
reduce
do not evaluate a path:
>> data: [a: [b: 1 c: "hello" d: []] e: 123]
== [a: [b: 1 c: "hello" d: []] e: 123]
>> reduce to-path [data a/b]
== none
>> data/a/b ; but direct access to path work
== 1
- hiiamboris
- 09:42
[data a b]
- bubnenkoff
- 09:51But why
reduce to-path [data a/b]
do not work? the spelling of result look like normal
- hiiamboris
- 09:52because second item in this path is
a/b
09:52do you have a/b
in data?
- bubnenkoff
- 09:54ah....15:52I need help with fixing algorithm.
This function should find return list of blocks before current tag.
data: [
purchaseNumber: ""
lots: [
lot: [
lotNumber: 1
customers: [
customer: [
customer_regNum: ""
]
]
lotMaxPrice: none
deliveryTerm: {}
currency_code: ""
objects: [
object: [
price: none
]
]
]
]
tag: ""
]
find-path-to-node: function[data node-name /parent] [
stack: copy []
current-tag-level: 0
level: 0
isFound: false
walk: function [data /extern isFound level current-tag-level] [
foreach [key value] data [
if block? value [
level: level + 1 ; increment level
either ((to-lit-word key) = node-name) [ ; if find needed node
either parent [ ; finding parent
isFound: true
return stack ; return from walk with result
] [
isFound: true
append stack to-word key ; add to stack and exit from walk
return stack ;
]
] [
append stack to-word key ; needle node still not found add current node to stack
]
print ["level:" level " key:" key ]
walk value
level: level - 1
]
]
]
walk data
either isFound [
return stack
] [
return none
]
]
probe find-path-to-node data 'object
For example for object
parents is: lots lot objects object
.
I'm stuck and can't figure out how to fix the feature. Obviously it's supposed to remove blocks of the same level so they don't go into the chain.
I am getting next result:
probe find-path-to-node data 'object
[lots lot customers customer objects object]
customers customer
should not be here, but I can't understand when I should remove them.
- hiiamboris
- 15:54@bubnenkoff remove last item from the stack once you leave the scope15:55and just an advice: use Parse
- bubnenkoff
- 15:57> and just an advice: use Parse
Why? I do not think that code in parse would be more readable\short?
- hiiamboris
- 15:58I have a feeling it can be *much* simpler with Parse, because it provides recursion out of the box.
- bubnenkoff
- 15:58> @bubnenkoff remove last item from the stack once you leave the scope
Please show me right place, I tried, but every time I am getting wrong result
- hiiamboris
- 15:58before
level: level - 1
15:58only if you haven't found it
- bubnenkoff
- 16:01
if (isFound = false) [
take/last stack
]
level: level - 1
Wrong result:
probe find-path-to-node data 'customer
[lots lot customers customer objects object]
- hiiamboris
- bubnenkoff
- hiiamboris
- 16:24just check
isFound
16:25at walk
start for example
- bubnenkoff
- 16:27Still not working:
find-path-to-node: function[data node-name /parent] [
stack: copy []
current-tag-level: 0
level: 0
isFound: false
walk: function [data /extern isFound level current-tag-level] [
foreach [key value] data [
if block? value [
level: level + 1 ; increment level
either ((to-lit-word key) = node-name) [ ; if find needed node
either parent [ ; finding parent
isFound: true
return stack ; return from walk with result
; exit
] [
isFound: true
current-tag-level: level
append stack to-word key ; add to stack and exit from walk
return stack ;
; exit
]
] [
append stack to-word key ; needle node still not found add current node to stack
]
print ["level:" level " key:" key "isFound:" isFound]
if (isFound = false) [
walk value
take/last stack
]
level: level - 1
]
]
]
walk data
either isFound [
return stack
] [
return none
]
]
probe find-path-to-node data 'object
- hiiamboris
- 16:33what does it return?
- bubnenkoff
- hiiamboris
- 16:34well, scratch this and start over then :)
- bubnenkoff
- 16:35I wouldn't have asked if I hadn't tried this
- hiiamboris
- 16:35use Parse now! ;)
- bubnenkoff
- 16:38I am trying to rewrite old solution from Parse. It's work, but I do not like it really. Maybe it can be improved, but I prefer use Parse only when I am working with text data. Btw old solution code:
find-pos: function[xdata w /parent] [
word-founded?: false
current_level: 1
tag_level: 1
stack: copy []
parse xdata rule: [
some [
set-word! [integer! | string! | 'none ]
| ahead [set-word! block!] ahead [ set block-name to block! ] [fail]
| ahead block! ( if (not word-founded?) [ append stack to-word block-name ] ) (if find stack w [word-founded?: true]) into rule ( if (not word-founded?) [ stack: remove-last stack ] )
| skip
]
]
if word-founded? [
if parent [ either (length? stack) > 1 [ ;
return head clear back tail copy stack ;
] [ ;
; return first copy stack
return [] ;
]
]
return stack ;
]
]
- hiiamboris
- 16:38although I think it's almost correct, you just have
append
in the wrong place
- bubnenkoff
- 16:39Really? But it's working!
- hiiamboris
- 16:39no, I mean the other one that returns
[lots]
- bubnenkoff
- 16:42> no, I mean the other one that returns
[lots]
You mean this append:
append stack to-word key ; needle node still not found add current node to stack
?
- hiiamboris
- 16:43yep16:43although wait16:44what a mess :)
- bubnenkoff
- hiiamboris
- 16:54nope, think again
- bubnenkoff
- 16:55oh, yes, I understand, but what do you suggest?
- hiiamboris
- 16:55check again?
- bubnenkoff
- hiiamboris
- 16:56I mean check
isFound
- bubnenkoff
- 16:59Again wrong result
if (isFound = false) [
walk value
if(isFound = false) [
take/last stack
]
]
probe find-path-to-node data 'customer
== [lots lot customers customer objects]
- hiiamboris
- bubnenkoff
- 17:06@hiiamboris cool!!! Many thanks!!! It's seems that it works!
find-path-to-node: function[data node-name /parent] [
stack: copy []
current-tag-level: 0
level: 0
isFound: false
walk: function [data /extern isFound level current-tag-level] [
foreach [key value] data [
if block? value [
level: level + 1 ; increment level
either ((to-lit-word key) = node-name) [ ; if find needed node
either parent [ ; finding parent
isFound: true
return stack ; return from walk with result
] [
isFound: true
current-tag-level: level
append stack to-word key ; add to stack and exit from walk
return stack ;
]
] [
if (isFound = false) [
append stack to-word key ; needle node still not found add current node to stack
]
]
print ["level:" level " key:" key "isFound:" isFound]
if (isFound = false) [
walk value
if(isFound = false) [
take/last stack
]
]
level: level - 1
]
]
]
walk data
either isFound [
return stack
] [
return none
]
]
probe find-path-to-node data 'object
But I really still thinking that it's easier to read than Parse
- hiiamboris
- 17:08I think both versions are very ugly :)17:08good exercise for you
- bubnenkoff
- 17:12ok, thanks, I will try, I think I understand why do you suggest it -- to prevent multiple check of
isFound
?
- hiiamboris
- 17:13yes, logic will be simpler and more predictable
- bubnenkoff
- 17:31ok, but before I tried to introduce
current-tag-level
and play with it. It was bad idea? I thought I can compare current level and some another level or something like it
- hiiamboris
- 17:43I don't think you need level there at all
- toomasv
- 06:01@bubnenkoff One posssibility in spirit of your original approach:
find-path-to-node: function [data node-name /parent] [
stack: copy []
level: 0
isFound?: no
walk: func [data] [
foreach [key value] data [
case [
node-name = to-word key [
isFound?: yes
if not parent [append stack to-word key]
return stack
]
block? value [
level: level + 1
append stack to-word key
walk value
if isFound? [return stack]
clear at stack level
level: level - 1
]
]
]
]
walk data
if isFound? [stack]
]
- bubnenkoff
- 07:16As usually Perfect!! Thanks)
- toomasv
- 07:38You are welcome!
- bubnenkoff
- 12:36I need any workaround for this bug https://gitter.im/red/bugs?at=625919878db2b95f0ab88c99
[["aa" "cc"] ["aa" "aa"] ["aa" "aa"] ["aa" "bb"] ["aa" "aa"]]
- gurzgri
- 13:16Something like
uniquify: function [values] [
singles: make hash! length? values
foreach value values [any [
find/only singles value
append/only singles value
]]
to block! singles
]
13:17Untested.
- hiiamboris
- 13:20just sort it and remove all sequential duplicates
- bubnenkoff
- 14:34thanks!
- greggirwin
- 17:54Here's one I did a loooong time ago, before Red had set-oriented functions.
unique: function [
"Returns a copy of the series with duplicate values removed."
series [series!]
; /case "Perform a case-sensitive search"
; /skip "Treat the series as fixed size records"
; size [integer!]
][
res: make series length? series
foreach val series [
if not find/only res val [append/only res val]
]
res
]
- rsheehan
- 01:53Is there any way to discover the cursor position in an
area
?
- gltewalt:matrix.org
- 03:17offset-to-character, character-to-offset
I think 🤔
- bubnenkoff
- 07:52What is my error? I am trying to move last element to first position with
move
x: [1 2 3 4 5]
probe move/part x x 5 1
[1 2 3 4 5]
- rebolek
- 07:54The error is that both your positions are at the start of the block.07:55
back tail x
will point to the last element
- toomasv
- 08:02@rsheehan With Red/System code only. Here is [example for Windows](https://gist.github.com/toomasv/0085fd7c61e53dc9cedb45ae98f777e9).
- bubnenkoff
- 08:04> The error is that both your positions are at the start of the block.
why first head
is needed? I understand that is move to header, but why it's before move? Because it setting place that accept result of moving?
- toomasv
- 08:14Otherwise just position at last element is returned by
move
, because move
was given series at this position. head
is needed only if you require the whole series immediately. Otherwise not needed. You can just refer to x
to get the whole series with rearranged elements.
- rebolek
- 08:21as @toomasv said
head
is not needed, I added it just to show the result.
- rsheehan
- 20:34@toomasv Thanks. I will try that.
- bubnenkoff
- 08:11Eght... back to checking if value has been set. I tried
unset?
and value?
. Both gave an error:
foo: func[][
either value? aaa [
print "aaa is exists"
] [
print "aaa not exists!"
]
]
foo
- ldci
- 08:25@bubnenkoff aaa is just a word with no value:)
- bubnenkoff
- 08:26yes, but how to check if it has been set or not?
- ldci
- 08:28@bubnenkoff aaa: 45 value aaa -> true08:31@bubnenkoff or set ‘aaa 45 value? aaa -> true
- bubnenkoff
- 08:31yes, I understand that if
aaa
have value I can check it with value?
But:
foo: func[][
either unset? aaa [
print "unset -> true"
] [
print "unset -> false"
]
]
foo
error:
*** Script Error: aaa has no value
*** Where: either
*** Near : aaa [print "unset -> true"] [print "unset"]
*** Stack: foo unset?
08:32I do not need error, I need just print that value did not set
- ldci
- dsunanda
- bubnenkoff
- ldci
- 08:57@bubnenkoff . Your function
foo: func[][
either unset? get/any 'aaa [
print "unset -> true"
] [
print "unset -> false"
]
]
foo
- bubnenkoff
- 09:08thanks!
- ldci
- 09:09@bubnenkoff You’re welcome :)
- bubnenkoff
- 09:55> also, idk what will happen if you close the window before loops finish :)
I checked, it's really hangs. I still want to try find way to ask user about action in current windows, without creation separate windows (just usablity question).
User case. There is some processing. There is menu in UI (list-list) that show current section. Sometimes section can't be detected and we need to ask user to select one of section from menu.
foo: function [] [
foreach el ttt/data [
if (el = "bb") [
; I need to ask user to click on any element in next list to continue
]
]
]
view [
button "start" [foo]
ttt: text-list: data ["aa" "bb" "cc" "dd"]
]
Or maybe to display some addition button and wait for it clicking before processing
- hiiamboris
- 11:13In this case, I recommend leaving the loop, displaying some text telling the user what should be done, and making
ttt
selection enter a new loop.11:13Any loop can be written using while
or forever
. Just stash the last index somewhere and continue once you're ready.
- cosacam1
- 14:38Hi again. When I type ? scroller! I see there are props like position, page-size, min-size, etc. However, if I use a scroller in VID there's nothing like those props. I think they are different objects. How can I use a scroller in VID with those props? Or, how can I make a scroller's thumb to move to it's top (or bottom or elsewhere) position when I set it's data to some value? Thanks
- hiiamboris
- 14:44
view [scroller rate 2 on-time [face/data: 1 - face/data]]
- cosacam1
- 14:59@hiiamboris , thanks for your fast answer. Actually I wrote this example and I realized that my problem was I was assining integers to data, not floats. Now, with to-float, it works as desired:15:00'''Red [needs: view]
min-val: 10
max-val: 68
val: 54
view [
scr: scroller 120x20
text "0" react [face/text: to-string scr/data * (max-val - min-val) + min-val]
button "go" [
scr/data: (val - min-val) / to-float (max-val - min-val)
]
]'''15:02
Red [needs: view]
min-val: 10
max-val: 68
val: 54
view [
scr: scroller 120x20
text "0" react [face/text: to-string scr/data * (max-val - min-val) + min-val]
button "go" [
scr/data: (val - min-val) / to-float (max-val - min-val)
]
]
15:03Sorry, how to send some code? I forgot it
- hiiamboris
- 15:04Ctrl+Shift+M to see the syntax15:04you forgot newlines before/after \
\
\`
- cosacam1
- 15:11Thanks again. I think this example is better:
Red [needs: view]
min-val: 10
max-val: 68
range: max-val - min-val
view [
scr: scroller 120x20
text "0" react [face/text: to-string scr/data * range + min-val]
button "click again" [
val: min-val + random range
scr/data: (val - min-val) / to-float range
]
]
15:13Oops. No "0" in text. Sould be text to-string min-val...
15:15Oops again. Just no "0" in text. Sorry.
- toomasv
- 15:38@cosacam1 These are different things indeed - standalone
scroller
style and embeddable scroller object that you see with ? scroller!
. I just used the embeddable one in a [table
style](https://github.com/toomasv/table-template). See table-template.red
, look from SCROLLING
downward how it is implemented.
- ldci
- 16:04@cosacam1 I don’t understand what you’re trying to do. As far I remember Scroller is not a view face. Use slider
min-val: 10
max-val: 68
range: max-val - min-val
view [
scr: slider 120x20
text "10" react [face/text: form to-integer scr/data * range + min-val]
button "click again" [
val: min-val + random range
scr/data: to-percent val - min-val / range
]
]
- hiiamboris
- 16:06@ldci have you tried his code?
- ldci
- 16:08@hiiamboris Yes under macOS:)
- hiiamboris
- 16:11If scroller doesn't work on Mac, you should file an issue probably ;)
- ldci
- 16:13@hiiamboris scroller is unknown on Mac for a direct use with view. But Toomas’s table code works fine :)
- hiiamboris
- 16:14Actually it is not documented, so was probably never finished or not supported by Mac :)16:15@qtxie may know
- ldci
- 16:16I think so. BTW no way to create a vertical slider under macOS. Not supported by the OS.
- cosacam1
- 19:01@ldci Well, there are both scrollers, one of them is a face. See Toomas comment19:04@toomasv - I only took a look at your table's readme so far. I find it very useful. I haven't seen the code because I was away of my PC. Now I get to go home. I'll study it later. Thanks to all for your help.
- toomasv
- 19:06:+1:
- dsunanda
- 07:10I have a Windows R2/View app that uses SQLite with Ashley's driver. Works fine (other than the growing R2 cruft). Been chugging away for years. Happy user.
I have converted it to Red. Nicer GUI. But SQLite access is via CALL to SQLite's command line utility. Too clunky to really consider as a replacement for the R2 app.
But what I'd really like is to be able to run the app on Android and IOS.
How insanely naive am I?
- rebolek
- 07:30Doesn't @Oldes have SQLite driver for Red?
- toomasv
- 08:12It worked when I [played](https://github.com/toomasv/sqlite) with it ~two years ago. Haven't tried it since then, probably broken.
[](https://toomasv.red/images/DB/db-admin.gif)
- greggirwin
- 19:00> But what I'd really like is to be able to run the app on Android and IOS. How insanely naive am I?
A lot of work went into Android some time back, and a community member is looking at what they can do to help. We hoped to get it updated this year, but I'm not sure we'll make it. :^( iOS is a different beast completely, and we have no work done on it or a place in the roadmap for it.
- GiuseppeChillemi
- 08:42@toomasv are you aware that your "toys", once fully functional, are the foundations of beautiful future application we could make with Red? This table browser is fantastic!08:46@greggirwin we are near the end. Once IO will be merged, we will have everything needed to build full applications. If you concentrate your forces to complete the Android version, everyone will have a complete toolset to create applications for companies and Red adoption will be bosted. (and also will start for everyone the source of income coding with Red)
- dsunanda
- 16:44@greggirwin Thanks Gregg. IOS would be nice, but Android is strategic.
- toomasv
- 16:46@GiuseppeChillemi Thanks! But they are still just toys. There is looong way from toys to real things, I've learned..
- GiuseppeChillemi
- 17:56@dsunanda I agree, Android with support for external libraries to read barcodes, would open an incredible market and attracts coders and companies.17:56@toomasv I have learned it too.
- planetsizecpu
- 06:42Well done @toomasv this kind of tools are useful for DB developers, push hard 🦾
- toomasv
- 08:43Thanks, @planetsizecpu !
- GiuseppeChillemi
- 09:55 I want to create a block with
field-name
and validation rule
in a block, like:
[
code [integer?]
description [25 < length?]
]
I think only of making a context and with a word and bind the block like:
validation: [
code [integer? value]
description [25 < length? value]
]
ctx: [
value: none
]
code: 25
ctx/value: code
valid? do bind validation/code ctx
Have you a better approaches?
- hiiamboris
- 10:38Start from the top. How do you intend to use it?
- GiuseppeChillemi
- 10:47Validation of gui field input, connected to database columns.
- hiiamboris
- 10:49That was obvious :) But doesn't tell any of the specifics needed to answer your question.10:49Bind it, put into an
all
block and you're done
- GiuseppeChillemi
- 11:41Because I want reusable code to use the for different fields. So I write
fieldname validator-name
and selxt the validator in another block12:04Example:
validation: [
string-40 [40 <= lenght? value]
integer-less-25 [25 < length? value integer? value]
]
field-specs: [
code integer-less-25
description string-40
id integer-less-25
]
- hiiamboris
- 12:16I see12:17context makes sense then, or replacement of
value
with the column name during validation rule composition
- GiuseppeChillemi
- 12:34Yes, it seems the only viable way to go.
- hiiamboris
- 18:39Why can't we set "absent" tuple parts (even in R2)?
>> c: 0.0.0.0
== 0.0.0.0
>> c/4: none
== none
>> c
== 0.0.0
>> c/4: 0
*** Script Error: value out of range: none
*** Where: set-path
*** Near : 0
*** Stack:
18:48I have to first add a new part, only to be able to remove it:
> c: 0.0.0
== 0.0.0
>> c/4: none
*** Script Error: value out of range: none
*** Where: set-path
*** Near : none
*** Stack:
>> c: c + 0.0.0.0
== 0.0.0.0
>> c/4: none
== none
>> c
== 0.0.0
- greggirwin
- 19:14My first guess is that Red did it for Rebol compatibility. It may also have eased the implementation or align more closely with, e.g.
block!/vector!
behavior. Though vectors return none
if you ask for an out of bounds index. And tuples cast none
to 0
for all values following the index, if les than 3, setting the "size" of the tuple. If longer than 3, they go away. 19:15Worth a design review IMO.19:20value out of range: none
isn't helpful either. That's a bug.
- hiiamboris
- 19:26An issue would do or issue and a rep?
- greggirwin
- 19:27At the very least we'll get better docs out of it. And it's another case where we scratch our heads, because types are different and behave differently. Sometimes by design and sometimes...it can be improved. e.g. tuples can never be empty, or even have a length less than 3. Currently also a max length of 12 (which *likely* won't change, but is really an implementation side effect).
And because they aren't series values, using none
to clear them is kind of like the question on that for removing map keys when they were first implemented. But you can't use at+clear
. The joy of language design.19:27Maybe a brief REP to start, to lay out the current and desired behavior.
- hiiamboris
- 19:34Since it's a scalar, no need to be consistent with series.19:34
tuple/i: none
is a bit of a hack, agreed
- greggirwin
- 17:02While it's a bit of a hack, and a specific
set-length
action is more meaningful, I can't say it would be categorically better. But a set-length
mezz might be worth considering. I have an old one for R2 (below), but like my shift
and rotate
series funcs, I only used it in a few cases. This is where it will be great when we have a collection of mezzanines and can evaluate and assemble things in a real ecosystem.
This doesn't support tuples, but could easily.
set-length: func [
"Sets the length of a series, trimming or padding as necessary."
series [series!] "(modified)"
length [integer!]
/with "Override default pad fill value (space for strings, none for blocks)"
value
][
default value either any-string? series [#" "] [none]
if length = length? series [return series]
either length < length? series [
head clear skip series length
][
append/dup series :value subtract length length? series
]
]
- hiiamboris
- 17:24I'm also using smth like that, for further indexed write:
;; extend & expand are taken already
enlarge: function [
"Ensure certain SIZE of the BLOCK, fill empty space with VALUE"
block [any-block!] size [integer!] value [any-type!]
][
insert/dup skip block size :value size - length? block
;; returns after size
]
- greggirwin
- 17:27Part of your
tube
work?
- hiiamboris
- 17:28No, used in popups code.
- greggirwin
- 17:29There are times where normalizing by size simplifies things, at the cost of space.
So popups aren't just like regular layouts?
- hiiamboris
- 17:29https://codeberg.org/hiiamboris/red-spaces/src/commit/a387dfb186e77d53b4796f7b4c3258d217fb5017/popups.red#L5817:29and L6917:30> So popups aren't just like regular layouts?
No, popups live in another faces with a predefined layered structure:
- layer 0 is tooltips
- layer 1 is top-level menu
- layer 2 is second-level menu and so on
- greggirwin
- 17:30So stacks there are not strictly LIFO accessed.17:31Ah, that explanation helps a lot.
- hiiamboris
- 17:31Basically, stack in that case is not a FIFO/LIFO stack but just a collection of layers.
- greggirwin
- 17:32Though I'll ask why tooltips are grouped with menus, rather than, say an object that names the elements. Outsider question. :^)17:33If every face has them, blocks will be a lot lighter, per
node!
.
- hiiamboris
- 17:36It's just a registry of faces that I'm adding to the
window
and using for my own purposes (later I must find and remove them or repurpose). For example, when new level 2 menu is shown it hides previously opened menus of level 2 and above, but not level 1 menu. Also all menus hide tooltips.17:37Each such "registry" stack is associated with a top level window.17:39Anyway it's an internal implementation detail, not exposed to the user.
- greggirwin
- 17:39Thanks. Fortunately, Red gives us nice ways to deal with this too, e.g. named indexes into block structures.
- hiiamboris
- 17:52An experiment: function constructor that allows to write readable code and make a mess out of it:
probe test: modifying-function ['a [word!] 'b [word!]] [
a: also b b: a
probe 'a/:b/1/(b + 1)
]
func ['a [word!] 'b [word!]] [
set a also (get b) set b (get a)
probe 'a/(get/any b)/1/((get b) + 1)
]
But I can't find a name for it :/ Any ideas?
- greggirwin
- 17:57If the goal is to make a mess of the code, ala obfuscation, call it
messify
. If it has a different purpose, like working around compiler issues, just use do
.
- cloutiy
- 18:07You can call it
spagettify
- hiiamboris
- 18:07Goal is to write readable code passing multiple values in and out.
- greggirwin
- 18:11I'm still not clear then. We've been writing readable code like that in Red for years. :^)
- hiiamboris
- 18:13Like many languages allow you to declare an argument "in/out" or ["pass by reference"](https://www.educative.io/edpresso/pass-by-value-vs-pass-by-reference) and it will automatically modify the variable (containing the argument value).
- greggirwin
- 18:16Got it. That seems like a custom/extended func spec need, since I'm guessing doc strings aren't enough in your case. You want the added protection and control.
- hiiamboris
- 18:17I'm just rewriting lit-args.18:17
#include %keep-type.red
modifying-function: function [spec [block!] body [block!]] [ ;@@ shitty name
lit-words: keep-type spec lit-word!
block-rule: [any [
ahead set w get-word! if (find lit-words w)
change only skip (as paren! reduce ['get/any to word! w])
| ahead set w word! if (find lit-words w)
change only skip (as paren! reduce ['get to word! w])
| ahead set w set-word! if (find lit-words w)
insert ('set) change skip (to word! w)
| ahead any-list! into block-rule
| ahead any-path! into path-rule
| ahead word! 'quote skip
| skip
]]
path-rule: [any [
ahead set w get-word! if (find lit-words w) change only skip (as paren! reduce ['get/any to word! w])
| ahead any-list! into block-rule
| skip
]]
parse body: copy/deep body block-rule
function spec body
]
18:18No need to change the spec.
- greggirwin
- 18:21
by-ref-lit-arg-func
, mod-lit-args-func
, in-out-lit-arg-func
all long, but maybe in-out-func
is enough, if the doc string tells you how it operates.18:23I like mod
better in there. arg-modding-func
isn't great though. by-ref
isn't great either, because of so many values being by reference anyway, not to mention ref!
.
- hiiamboris
- 18:36
in-out-func
is okay 18:37thanks for ideas18:42also maybe two-way-func
- greggirwin
- 19:07
two-way
sounds like it calls back out, rather than just modding args.
- hiiamboris
- 18:26
>> ?? repend
repend: func [
{Appends a reduced value to a series and returns the series head}
series [series!]
value
/only "Appends a block value as a block"
][
head either any [only not any-block? series] [
insert/only tail series reduce :value
] [
reduce/into :value tail series
]
]
I'm wondering here... Has anyone *ever* used the first branch of repend
?18:29I can only see it as a shortcut repend/only series block
for append/only series reduce block
, but then how common is it?18:30For non-block types, what's even the point?
- toomasv
- hiiamboris
- 18:39Can you point me to the code?18:39Found one in diagram. A few even.18:43OK I see your use case. Stacks of saved values.18:48Funny, I don't think I ever used even
append/only series reduce block
.18:49I guess we have our habits in how we model processes :)
- toomasv
- 19:31> Can you point me to the code?
[Latest](https://github.com/toomasv/table-template/blob/main/table-template.red)
- hiiamboris
- 19:36I don't see repend/only there
- toomasv
- 19:43Ah, ok. [Here](https://github.com/toomasv/GA) are some.
- hiiamboris
- 19:46Thanks
- toomasv
- 19:48:+1:
- greggirwin
- 19:49I've used it a small number of times in R2 code, from a quick search, as have others.
- bubnenkoff
- 08:25Hi!
foo: [button "test"]
; how to check here if view is already loaded/displayed or no?
view foo
- ldci
- bubnenkoff
- hiiamboris
- 09:07you'll have to add your own flag, yes
- ldci
- 11:56Hi everybody. Why this code is wrong? face/extra object is not initialized.
Red[
needs: view
]
extend system/view/VID/styles [
iosBtn: [
default-actor: on-down
template: [
type: 'base
size: 48x25
color: red
data: 0
actors: [
on-create: [
face/extra: object [
fColor: snow
bColor: face/color
bSize: face/size
radius: to-integer bSize/y / 2
lCenter: as-pair radius radius
rCenter: as-pair bSize/x - radius radius
;--make default image (off)
blk: compose [
line-join round
fill-pen fColor box 0x0 (bSize) (radius)
fill-pen fColor circle (lCenter) (radius)
]
bDraw: draw bSize blk ;--call draw method
bClick: func [face][
either face/data = 0 [
face/data: 1 blk/4: bColor blk/12: rCenter
][face/data: 0 blk/4: fColor blk/12: lCenter]
;--update face image with draw
bDraw: draw bSize blk
face/image: face/extra/bDraw
]
];--end of object
];--end of create
on-down: function [face] [
print "here"
probe face/extra
face/extra/bclick face
]
];--end of actors
];--end of template
];--end of style
];--end of extend
view [iosBtn green 48x24 [face/extra/bclick face]]
- hiiamboris
- 12:02forgot
function
?
- ldci
- 16:38@hiiamboris . Thanks :)
- GiuseppeChillemi
- 20:45
bind
does not allow path
for its target argument. Is there a way to bind
the first word of a path
without converting it to block
?
- hiiamboris
- 21:36
bind as block! path target
- ALANVF
- GiuseppeChillemi
- 21:39@hiiamboris
I didn't know this way of doing. To me it should have been:
to-path bind as block! path target
- ALANVF
- 21:40that way it doesn't copy anything
- GiuseppeChillemi
- 21:40I like both methods21:42This don't understand if the other words other than the first one are bound, because they are symbolically used until they are
get-word!
- ALANVF
- 21:42then you could just skip the forall and do
path/1: bind path/1 target
- GiuseppeChillemi
- 21:58Path has confused me. I have thought
path/1
would have returned a word unlinked to the path itself
- ALANVF
- 21:59well since
path
is a path!
(and therefore a series!
), it's gonna return its first value, which is a word
- GiuseppeChillemi
- 08:06Yes if you bind the series, you can't pick from a block a word and rebind it:
>> o: make object! [a: 22]
== make object! [
a: 22
]
>> o2: make object! [a: 99]
== make object! [
a: 99
]
>> append x: [] in o 'a
== [a]
>> bind x/1 o2
== a
>> reduce x
== [22]
08:11It would be nice to Rebind in place without changing the word, either for blocks
and paths
but it seems to me impossible, only bind seems to have this power when managing blocks.
- BuilderGuy1
- 21:58I'm trying to use two drop-downs to make a "Category" drop-down that feeds a "sub-category" drop-down.
I can't get the second drop-down to see the results of the first.
This is what I have (which does not work).21:58
RED [
needs: 'view
]
Categories: ["MyList1" "MyList2" "MyList3" ]
MyList1: ["1" "2" "3" "4"]
MyList2: ["A" "B" "C" "D"]
MyList3: ["Arf" "Barf" "Carf" "Darf"]
Add2Log: function [] [
append log/data append now append " " pick ItemSelect/data ItemSelect/selected
]
Cat1: []
view [
across
text "Category" 120x25 text "Sub Category"
return
CatSelect: drop-down 120x25 "Choose..." data Categories
on-change [probe pick CatSelect/data CatSelect/selected
ItemSelect/data: pick CatSelect/data CatSelect/selected]
ItemSelect: drop-down 120x25 "Choose..." data Cat1
[probe Cat1: pick CatSelect/data CatSelect/selected]
MyAdd: button 30x25 "+" [Add2Log]
return
below
text "Today's log"
Log: text-list 200x200
]
- hiiamboris
- 22:03forgot
on-change
?
- BuilderGuy1
- 22:07I had that in there but I get an error stating that it can't use "none"
- ALANVF
- BuilderGuy1
- 22:09ok I put it back and no error. i must have done something different before. Second droip-down still doesn't get any data22:10I'll try it :-) @ALANVF 22:15Will the drop-down accept its DATA as text? Or do I have to change it's type inorder to point it to my other blocks?
- hiiamboris
- 22:17data should be a block22:18https://w.red-lang.org/en/view/#drop-down22:18we have docs btw
- ldci
- 08:33@BuilderGuy1 Something like that?08:33[](https://files.gitter.im/5780ef02c2f0db084a2231b0/Cqks/image.png)08:35Here’s the code
Red [
needs: 'view
]
Categories: ["MyList1" "MyList2" "MyList3"]
MyList1: ["1" "2" "3" "4"]
MyList2: ["A" "B" "C" "D"]
MyList3: ["Arf" "Barf" "Carf" "Darf"]
uChoice: none
Add2Log: does [append log/data rejoin [form now " " uChoice]]
view [
across
text "Category" 120x25 text "Sub Category"
return
CatSelect: drop-down 120x25 "Choose..." data Categories
on-change [
clear ItemSelect/data
switch face/selected [
1 [ItemSelect/data: copy MyList1]
2 [ItemSelect/data: copy MyList2]
3 [ItemSelect/data: copy MyList3]
]
;select ItemSelect first row and uChoice
ItemSelect/selected: 1
uChoice: ItemSelect/data/(ItemSelect/selected)
]
ItemSelect: drop-down 120x25 "Choose..." data []
on-change [uChoice: face/data/(face/selected)]
button 30x25 "+" [Add2Log]
return
below
text "Today's log"
Log: text-list 200x200 data []
]
09:05A better solution without switch test.
CatSelect: drop-down 120x25 "Choose..." data Categories
on-change [
clear ItemSelect/data
subCategory: to-block get to-word face/data/(face/selected)
ItemSelect/data: copy subCategory
;select ItemSelect first row and uChoice
ItemSelect/selected: 1
uChoice: ItemSelect/data/(ItemSelect/selected)
]
11:07@BuilderGuy1. More concise:
CatSelect: drop-down 80x25 "Choose..." data Categories
on-change [
clear ItemSelect/data
ItemSelect/data: to-block get to-word face/data/(face/selected)
;select ItemSelect first row and uChoice
ItemSelect/selected: 1
uChoice: ItemSelect/data/(ItemSelect/selected)
]
- BuilderGuy1
- 15:17@ldci This is fabulous!! I'm examining the code now :-) I had made more progress on it yesterday. I could get data into the second drop-down but it was not syncing right. I love your examples!! Even at first glance I'm learning new things :-)
- ldci
- 15:21@BuilderGuy1 You’re welcome :)15:23@BuilderGuy1 The second way without swich is better: you can add all sub-categories you need.
- BuilderGuy1
- 15:25Yes, I like the version without Switch too. I am glad you used it in an example thought! More examples are always better ;-)
- ldci
- 15:28Yes, Red is fabulous for testing idea.15:29
Red[
Needs: 'View
]
names: ["Carl Sassenrath" "Nenad Rakocevic" "Chris Lattner"]
languages: ["Rebol" "Red" "Swift"]
win: layout [
title "Picker"
below center
text "Languages" center font-size 14
drop: drop-list data languages select 1
H2 300 center react [face/text: names/(drop/selected)]
button "Quit" [quit]
]
view win
- gor77
- 14:39Hello,
I've just started experimenting with Red. Seems very interesting!
Right now I'm trying to understand why something as simple as this:
falsy: [off false none]
to-logic falsey/1
to-logic first falsey
14:39returns true?14:47sorry, first line should have been falsey: [off false none], just a typo
- hiiamboris
- gor77
- 15:26Hi, it says ==word!
- hiiamboris
- 15:26So you see, you have 3 words in your block, because block contents is not evaluated by default. And word is a truthy value.15:27Try
falsey: reduce [off false none]
15:28And don't forget to check the type again ;)
- gor77
- 15:29Aha, think I get it ...it will take some time to get these concepts, obviously :)
- hiiamboris
- 15:30Indeed. Red is one of the most mind bending languages ;)15:31Red is a data format first. Everything in Red is just data.. until it is evaluated.
- gor77
- 15:33I mean, I knew block is not evaluated by default...but I was under impression, that somehow, since this:
first falsey
```
gives back **off**, it seemed logical to me that this
to logic first falsey
`
also returns off. But it's all about the meaning, the types behind it - not the way it looks like :)
- toomasv
- gor77
- 15:36Yes, my understanding was that **first** will also **get** it :) But obviously, it will not do that.15:41But also, I realized I could change lots of things, even some basic things like true and false.
For example
false: true
15:42I mean, it looks like there is no bottom-line here :)
- toomasv
- 15:43Yes, you can... but then you'll stop dead soon :)
- ne1uno
- 15:43
falsey: [off #[false] #[none]]
- gor77
- 15:44Yes, but still...shouldn't some things be like, set in stone...it's important for sanity :)
- hiiamboris
- 15:46One day it may happen
- gor77
- 15:46If I'm not wrong, I think Rebol has something like that?
- hiiamboris
- 15:48Yes, it has
protect
- gor77
- 15:51That's useful. Now I'm maybe going too far with this, but if the whole concept of the language is around words (like a giant hashmap), would it be possible to reset it to clean state? For example, if I do something stupid like false: true :)15:52I know I can simply start the console again...but I'm trying to understand what is possible within the language15:53Still not very much resources out there, and it's a very interesting language. So different and extremely productive.
- ldci
- 15:54@gor77 Have a look here: https://github.com/red/docs/blob/master/en/SUMMARY.adoc
- hiiamboris
- 15:54It's possible to copy
system/words
and then set things back. At least some of them.
- gor77
- 15:54Aha, thanks, I will.
- hiiamboris
- 15:56That's a reference. You may wanna start with [Rebol/Core](http://www.rebol.com/docs/core23/rebolcore.html) manual which is mostly applicable to Red
- gor77
- 15:57@hiiamboris Yes, that's probably what I had in mind. There is a lot to learn. But when I realized how little code you need to display red image in a window, for example. Also, after fighting with regexes, parse looks like a revelation worth learning.15:59But when it comes to Rebol, it's mostly V2 Red is based on?
- hiiamboris
- 16:00R2, R3 and Red are somewhat equidistant from each other16:00R2 manual is just most well-written one :)
- gor77
- 16:01Aha, I see. Thanks a lot! :)
- hiiamboris
- 16:02https://helpin.red/ and https://crypticwyrm.neocities.org/learningred/ are Red resources but I can't vouch for their coverage and quality
- gor77
- 16:09Yes, I know for helpin.red, and also for www.red-by-example.org . These are very useful, but don't go very deep. I mean, in programming it's extremely important to understand how things are defined. I've also found https://github.com/meijeru/red.specs-public/blob/master/specs.adoc - definitely not an easy read, but clear definitions are very important
- hiiamboris
- 16:14:+1:
- gor77
- 16:20I just think this is the type of language people should start with..if nothing, they probably won't start to hate programming so quickly :) If it succeeds - like mass adoption - it could be a game changer.
- hiiamboris
- 16:26It depends on the person. Red blows the mind, because literally everything can be approached from multiple angles. People who like puzzles will love that, and it will help them develop their skill further. But other people can't have that much space in their head, and they may favor a rigid language with a few simple hardcoded directives like
if
and for
.
- gor77
- 19:31Well, what I like about Red is that it somehow hits that spot between high-level language (like, *really* high) and a language that still has in mind what programming should be about. I think it gives nice abstractions so people don't have to write boring code over and over again.
At the same time it's not boring because it seems to me that it manages to abstract just the boring/tedious parts :)
And the only problem I see with this is the possibility it won't be taken seriously, simply because of that attitude that I think is still very much present in the programming world - if it's not C++/Java/C#
and if you can open a window or a file (God save URL!) with a single line of code, it's probably something for kids.
Maybe Red/System will change that.
- greggirwin
- 20:59Welcome @gor77 ! Others have noted some important details, but you also found
parse
already. Being a data format first is fundamental, and also using parse
to build dialects (internal DSLs, using Red values and blocks rather than string parsing). As you've also seen, a bit, "There is no spoon." The idea of words being able to refer to other values in a given context or domain is also deeply part of Red, but there are times when you want to lock some stuff down. R/S proves this too, that you can create a more strict language out of a dynamic one, while sharing a syntax.
Happy Reducing!
- gor77
- 22:32Thanks! I'm just surprised that it hasn't really got the attention I think it deserves.
There are so many (too many, actually :) languages out there, so maybe people don't care so much. But many of them are really not that much different.
Something like Linux distributions...
And even when they get something important right - like, maybe safety in case of Rust - the fun part while trying to learn them, or while trying to do something concrete with them just wasn't there. It was completely missing. But the pain was almost constant, only with maybe few bright moments :)
And yes, @hiiamboris is right - a lot of it depends on the person. I can speak only for myself.
But then again - a lot of languages are not really human friendly *at all*. It's almost like they are made for machines, not humans.
Red definitely looks and feels different, and that's a good thing!
- henrikmk
- 10:51This neither works in Red, nor R2 or R3:
>> t: [(fc) 'custom-action (fc) (event)] ; I want to replace (fc)
== [(fc) 'custom-action (fc) (event)]
>> replace/all copy/deep t to-paren 'fc 'y ; replace (fc) with 'y
== [(fc) 'custom-action (fc) (event)]
>> replace/all load mold/all t to-paren 'fc 'y ; try harder
== [(fc) 'custom-action (fc) (event)]
It doesn't work with blocks either.
What am I missing? It's something obvious, I know it.
- toomasv
- henrikmk
- 11:17That still doesn't work in R2 or R3, and crashes in my Red build, so I guess this is a recent change.11:17I'm using PARSE instead. Thanks. Was just curious.
- toomasv
- 11:39Tried this in 30-April build.
- fergus4
- 13:49What is the equivalent of rebol's reform?
- hiiamboris
- 15:32just write your own
- rebolek
- gltewalt:matrix.org
- 18:01> Yes, I know for helpin.red, and also for www.red-by-example.org . These are very useful, but don't go very deep. I mean, in programming it's extremely important to understand how things are defined. I've also found https://github.com/meijeru/red.specs-public/blob/master/specs.adoc - definitely not an easy read, but clear definitions are very important
Unfortunately, Carl has never written (or a least has never released) REBOL design papers. So no one stop source for all of the "why"s and deep corners
- ALANVF
- 19:51@fergus4 it's not exactly the same (since the result type is determined by the first value), but
rejoin
seems to be similar
- BuilderGuy1
- 21:08I'm trying to save a BLOCK to a csv file. When I try to use "to-csv" i get the error "*** Script Error: to-csv has no value"21:08What am I missing ??
- gurzgri
- 21:09
save/as data 'csv
?
- BuilderGuy1
- ALANVF
- 21:11seems like
to-csv
isn't a function21:11what build is your version of Red?
- BuilderGuy1
- 21:11today's
- ALANVF
- 21:11weird, I have one from last week and it works for me
- BuilderGuy1
- 21:11to-csv is in the wiki and was added back in 2019
- ALANVF
- 21:12[](https://files.gitter.im/5780ef02c2f0db084a2231b0/PRxX/image.png)
- BuilderGuy1
- 21:12let me try...
- ALANVF
- 21:12if that doesn't work, enter
system/build/date
and tell me what it says
- BuilderGuy1
- 21:13
>> to-csv [1 2 3]
*** Script Error: to-csv has no value
*** Where: catch
*** Near : to-csv [1 2 3]
- ALANVF
- 21:13try what I just said then
- BuilderGuy1
- ALANVF
- 21:14weird21:14maybe it was accidentally removed recently?
- BuilderGuy1
- 21:14I am using the WINDOWS version in CrossOver on Mac. i could try the Mac version (so buggy though...)21:15I have to switch computers... hold on... M1 Mac Mini can't run RED. Have to use my laptop with 32-bit complient Mac OS21:16HA!! that worked ! May 17th build.
- ALANVF
- 21:16huh weird21:17now try the latest build on there, if it doesn't work again then I know what the problem is
- BuilderGuy1
- 21:17DAMN !!! That means i can't use my main system for RED. 21:17ok hold on...
- hiiamboris
- 21:22lol I can't use csv or json either
- BuilderGuy1
- 21:22It failed compiling !!! "Runtime error 1: access violation at: 0008524Ch"
- ALANVF
- 21:22interesting
- BuilderGuy1
- 21:22May 23rd Mac version
- ALANVF
- 21:22maybe today's build is just broken?
- BuilderGuy1
- 21:23I have an april 15th version in Crossover let me try that...
- ALANVF
- 21:23not sure how though
- BuilderGuy1
- 21:23
>> to-csv [1 2 3]
*** Script Error: to-csv has no value
*** Where: catch
*** Near : to-csv [1 2 3]
- ALANVF
- 21:24weird
- BuilderGuy1
- 21:25 I never seem to get a project done but BOY can I find bugs ;-)
- hiiamboris
- 21:26:D
- ALANVF
- 21:26the file it's defined in hasn't even been touched in months https://github.com/red/red/blob/c97690694b6a85bd23b04c23a6c474ffc16ec472/environment/codecs/CSV.red#L359
- hiiamboris
- 21:2614 may build has to-csv
- ALANVF
- 21:27I wonder if it's mac-only?21:27it would not surprise me
- hiiamboris
- 21:27he said bug is on windows
- ALANVF
- 21:27ah
- BuilderGuy1
- 21:27It failed in 2 windows builds for me as well (Using Wine/CrossOver)
- ALANVF
- 21:28has you tried running it on a vm or something?21:28I have a build from May 17th and it works fine for me natively (I use windows)
- hiiamboris
- 21:29try the latest?
- BuilderGuy1
- 21:29I could use my windows PC but it's not very convenient with my setup. My mac mini is my main system so trying to get as much working on it as possible.
- hiiamboris
- 21:31only 4 unrelated commits since 14th
- BuilderGuy1
- 21:31I tried the april 15th and may 23rd Windows builds in CrossOver. Both fail for "to-csv" but seem to work just fine for other basics (I can't do any thing complex so...)21:32My little GUI app I'm building to learn RED works just fine in the May23rd build. Just TO-CSV that fails that I have found so far
- ALANVF
- 21:36or rather just the latter
- hiiamboris
- 21:36Hm I get to-csv in latest build, wait. But not in a custom built cli console
but maybe because I skipped updates of some console files
- ALANVF
- 21:36oh do you think it's only enabled in gui console?
- BuilderGuy1
- ALANVF
- 21:36ah21:36what console are you using, gui or cli?
- BuilderGuy1
- 21:36gui
- ALANVF
- 21:37oh that complicates things
- hiiamboris
- 21:37Right, I don't have
needs: [json csv]
in my consoles21:37It was a new invention and I didn't get to modify my version21:38@BuilderGuy1 are you perchance building it yourself too?
- BuilderGuy1
- 21:38no
- hiiamboris
- 21:38weird
- ALANVF
- 21:39ahh here's something to try, enter
system/build/config/modules
and tell me what it says
- hiiamboris
- 21:39@BuilderGuy1 any directories you see in
%ProgramData%
path?
- BuilderGuy1
- ALANVF
- 21:39ahhhhhh21:39it's not loading JSON or CSV modules21:39no clue why
- BuilderGuy1
- 21:41@hiiamboris How to I check that path?21:41oh, I understand...21:42This is a bottle in CrossOver (WINE). There are 2 directories directly in ProgramData: Windows and RED
- hiiamboris
- 21:43well maybe wine's the issue21:43sorry path I wanted you to check is
ProgramData/Red
- BuilderGuy1
- 21:43Could be but the Mac version doesn't work either
- hiiamboris
- 21:43there shouldn't be any leftover source directories21:44but now I think it's the problem of OS version detection
- BuilderGuy1
- 21:44ProgramData/Red has 3 files: console-cfg.red crush-2022-5-23-6725.dll gui-console-2022-5-23-6725.exe21:45It is in a Windows XP bottle. It would not work in Win7 or Win10 bottles. Same error as compile error with mac version
- ALANVF
- 21:46that's weird21:47maybe you need to include additional windows libs?
- hiiamboris
- 21:47@BuilderGuy1 if you run R2, what does
system/version/4
say under Wine?
- BuilderGuy1
- 21:48rebol?
- hiiamboris
- 21:48yeah21:48though if it said anything else than
3
you would not get windows build21:49really weird, idk
- BuilderGuy1
- 21:49i don't have that handy, don't use it...
- hiiamboris
- 21:49I guess Wine worked for you previously?
- BuilderGuy1
- 21:49I has been working fine. But now finding things that don't work21:50My little GUI app works fine but can't use CSV
- hiiamboris
- 21:53idk, I guess just file [an issue](https://github.com/red/red/issues/new?template=bug_report.md) and maybe Qingtian has wine to test21:53I've no idea what was broken
- BuilderGuy1
- 21:54weird... ok, I guess I will just need to use a real windows environment then
- ldci
- 04:59[](https://files.gitter.im/5780ef02c2f0db084a2231b0/seBD/image.png)
- ne1uno
- 12:02polka dot demo and a few anomalies.12:02rate doesn't work if added to a style? is
rate 7
not 7 seconds?12:02/no-wait
exits now interpreted? I think it used to work differently.12:02(polkadot demo)[https://gist.github.com/ne1uno/b9c13330f563462038a75e4710743b64#file-polkadot-demo-red]
- pekr
- 13:50IIRC,
rate
accepts either the time type, or an integer, where it meanx - x-times per second. So if you want 7 secs, you have to specify it as a time 00:00:07
- ne1uno
- 13:53thanks, I forgot
layout
on the view so am rechecking things13:55yes, time format worked
- snotbubble
- 06:38Is there a way to tell the difference between
"string"
and {string}
? They're both of type string!
- ne1uno
- 06:44literal
{string}
can have newlines. I think form
shows {string}
after some minimal length or if there are newlines.
- snotbubble
- 07:12Some context: Need to make view fields from
"string"
data, areas from {string}
data, but can't tell the difference... besides doing something awful like getting-at the curly-braces.
- hiiamboris
- 07:33Look for a newline in the text 07:34Or, parse the input
- snotbubble
- 07:48won't work in this case as some ui items must be areas (eg: for sourcecode), even if the incoming data is a one-liner. Also I can't determine if it should be an area by checking the data name (word) as its set by the user. Everything is determined by type, but
"string"
and {string}
are the same to Red.
Is there a non-string string with a unique type that can be (ab)used for this task?
- ne1uno
- 07:48https://stackoverflow.com/questions/14765993/whats-the-fastest-most-efficient-way-to-count-lines-in-rebol07:50make everything an
area
?
- rebolek
- Oldes
- snotbubble
- 08:37@rebolek got it thanks! Will use tag for field, string for area...
- hiiamboris
- 09:15
areas: make hash! 100
transcode/trace {"string" {multiline string}} func [e i t l k] [
[load] repend areas [k i/1 = #"}"]
]
?? areas
areas: make hash! ["string" false "multiline string" true]
09:16https://github.com/red/docs/blob/master/en/lexer.adoc#52-transcodetrace
- rsheehan
- 01:26Just wondering if anyone knows of a Red binding to ncurses?
- ALANVF
- 01:37@rsheehan does this work? https://github.com/red/code/tree/master/Library/Curses
- rsheehan
- 01:39@ALANVF Thanks. I will try it out.
- GiuseppeChillemi
- 10:38Is there a way to rebind the body of a function, once created, without recreating it?
- hiiamboris
- 11:15
bind body-of :fun ctx
11:15obvious, right?
- GiuseppeChillemi
- 11:59I remember the body being copied and "closed" to further changes.11:59I could try only later
- gurzgri
- 12:04
Red
>> a: 4 f: does [prin [a ""]] f o: context [a: 5 f] bind body-of :f o f
4 4 5
It's not "closed".
- GiuseppeChillemi
- 12:46Good news.
- bubnenkoff
- hiiamboris
- 17:19add a new key, remove the old
- bubnenkoff
- 17:22it's only way? I thought about it, but value is big array and I think it would be many unnecessary allocations
- hiiamboris
- 17:22map does not hold a copy of (series) value, just the reference
- GiuseppeChillemi
- 21:06This is what I was trying to do:
s: 22
x: 33
f1: func [/local s x] [
probe [s x]
]
f2: func [/local s x] [
probe reduce [s x]
]
o: make object! [
m: :f1
n: :f2
]
bind body-of :o/m 's
bind body-of :o/n 's
probe o/m
probe o/n
But in Rebol I get:
** Script Error: Cannot use reflect on block value
** Near: make error! reduce [err-type err-id pick args 1 pick args 2 pick args 3]
So this is not possible in Rebol but only in RED:
o: make object! [
m: :f1 bind body-of :m 's
n: :f2 bind body-of :n 's
]
- ALANVF
- 21:07trying to insert function values into an object is a pain
- GiuseppeChillemi
- 21:08In Red it is easier
- ALANVF
- 21:08slightly yes
- GiuseppeChillemi
- 21:08Why "slightly"?
- ALANVF
- 21:09dunno, I just remember trying something similar a while back and it took like 10 minutes to get it working correctly
- GiuseppeChillemi
- 21:10In Rebol the function body seems locked.
- ALANVF
- 21:11I think rebol copies the body so yeah21:15ughhhhhh that means I need to reimplement red.js stuff21:16[](https://files.gitter.im/5780ef02c2f0db084a2231b0/5Yjm/image.png)21:16it's weird because you can't treat them like words anywhere else21:20it seems like issues are also words, but that doesn't explain the above behavior??
- hiiamboris
- 21:22refinements still carry the binding (because of functions using them, primarily), but it was hidden recently (~year ago)
- ALANVF
- 21:23then what about issues?
- hiiamboris
- 21:23issues have the binding slot too, but it's unused, so issues are purely symbolic
- ALANVF
- 21:23well that's annoying
- hiiamboris
- 21:23what is?
- ALANVF
- 21:24the implementation for this
- hiiamboris
- 21:24why?21:24each datatype serves different purposes
- ALANVF
- 21:24because now I get to rewrite a lot of Red.js code, since I had assumed refinements and issues were separate from words21:25this is primarily painful due to implementing actions for the datatypes
- hiiamboris
- 21:25will teach you to design in more modular fashion ;)
- ALANVF
- 21:25well I like to think I already have
- hiiamboris
- 21:25every skill can be improved21:26what really changes other than comparison for sameness?
- GiuseppeChillemi
- 21:26
=?
returns if 2 elements are "identical". Refinement has binding while issue should have no binding, so the /c
could be considered different because belong to different bindings, but I may be wrong.
- hiiamboris
- 21:27:turtle:
- ALANVF
- 21:27yeah basically
- GiuseppeChillemi
- ALANVF
- 21:28> what really changes other than comparison for sameness?
mainly the way comparison works, since issues and refinments use a different data structure layout / base type than words
- hiiamboris
- 21:29in Red, they have the same base, I'm sure you've seen21:29which is the basis for
all-word!
typeset
- GiuseppeChillemi
- 21:29@hiiamboris
Oh, I was so concentrated into writing that I have not seen you have already answered, so yes: :turtle:
- ALANVF
- 21:29yeah I never really thought about it at the time after observing the behavior of issues and refinements
- hiiamboris
- 21:29:)
- GiuseppeChillemi
- 21:31@ALANVF I have found this article while searching for info:
https://stackoverflow.com/questions/14818324/what-is-the-summary-of-the-differences-in-binding-behaviour-between-rebol-2-and21:32And another interesting link I will report in red/red
- ALANVF
- 21:36oh that's interesting, thank you21:36this reminds me that I wish the
use
native was in Red22:35ok got it working correctly in Red.js now, thanks :+1:22:35[](https://files.gitter.im/5780ef02c2f0db084a2231b0/TbxV/image.png)
- GiuseppeChillemi
- 00:19Ottimo!00:19Here is the only solution I have found in Rebol to include already made functions in objects and rebind they body:
oo: make object! compose/deep [
f1: func copy/deep [(spec-of :f1)] copy/deep [(body-of :f1)]
]
- bubnenkoff
- 13:25I have next data structure:
data: [
foo: 1
bar: 2
lots: []
]
I need to wrap every set words with not block value to object
:
data: [
object [
foo: 1
bar: 2
]
lots: []
]
I started with follow code:
data: copy [
foo: 1
bar: 2
lots: []
]
foo: function [] [
isObjectAdded: false
foreach [key value] data [
if not block? value [
if (isObjectAdded = false) [
insert data 'object
isObjectAdded: true
]
]
]
]
foo
But I think that it would be hard to open [
and ]
symbols. At least I can't figure out how to add them.
Would it be better to start with parser here?13:40And it seems that adding square brackets not trivial task. At least I can't find way to do it
- hiiamboris
- 13:46I think you're again seeing the code textually, not as a tree.13:46you can sort the data, putting blocks to the bottom, then do your thing
- toomasv
- 13:48Just joking:
data: [foo: 1 bar: 2 lots: []]
parse data [any [change copy x to [set-word! block!] ('object) insert only (x) 2 skip]]
data
== [object [foo: 1 bar: 2] lots: []]
- bubnenkoff
- 13:53> Just joking:
>
> data: [foo: 1 bar: 2 lots: []]
> parse data [any [change copy x to [set-word! block!] ('object) insert only (x) 2 skip]]
> data
> == [object [foo: 1 bar: 2] lots: []]
>
As usually thanks! I am reading, just not understand how to add brackets to block....13:54> you can sort the data, putting blocks to the bottom, then do your thing
Yes, but I can't figure out how to add block symbols ....
- hiiamboris
- 13:54Oh come on. Your code **is not text!**13:54You don't insert symbols into it.
- bubnenkoff
- 13:56ah....understood, but what way is to wrap it with block?
- hiiamboris
- 13:56
reduce
- bubnenkoff
- 13:57to
reduce
what? words with not block values? 14:21@toomasv you are:
1. collecting all words and values till [set-word! block!]
2. than change all of them to .... (and here I can't understand what happens). 14:33@toomasv
Base on your example I wrote this code:
parse data [ any [ change copy x to [set-word! block!] (to-block x) ] ]
probe data
it's not work now, but I think it's logical.
it's collect all words that have not block value, do block from it, and should replace original with it (leave out for simplification inserting object
word).
and it's now work now because I can't understand if change should change all till [set-word! block!]
- toomasv
- 14:42@bubnenkoff
1. **copy** all values until [set-word! block!]
2. change
copied part into word object
3. insert
copied part as block (with only
)
4. skip
set-word! block!
5. repeat if any
more...
- bubnenkoff
- 14:51big thanks for explanation! and what do
2 skip
? it's seems that they should skip last value that have a block, or no?
- toomasv
- 14:51Point 4, yes
- bubnenkoff
- 14:53so it can be written as:
parse data [ any [ change only copy x to [set-word! block!] (x) skip [set-word! block!] ] ]
?
- toomasv
- 14:54No
- bubnenkoff
- 14:55ah! Thanks!
- toomasv
- 14:56You are welcome!
- bubnenkoff
- 08:22@toomasv
I stuck with algo. The idea is next: I have got data structure that I should be able to prepare for casting to JSON:
data: [
item1: none
+lots: [
foo: none
lot: [
bar: none
baz: none
+objects: [
price: 123
count: 1
object: [
item: "apples"
]
object: [
item: "bananas"
]
]
]
]
]
Every array is started with "+". Other elements is objects. So I need to get at result:
data: [
object [ item1: none ]
lots: reduce [
object [foo: none]
object [
bar: none
baz: none
objects: reduce [
object [price: 123 count: 1]
object [item: "apples"]
object [item: "bananas"]
]
]
]
]
print to-json object data ;
I wrote follow code:
is-any-except-block-inside?: function[data] [
foreach [k v] data [
if not block? v [return true]
]
return false
]
foo: func [] [
walk: function [data] [
if is-any-except-block-inside? data [
parse data [change copy x to [set-word! block!] ('object) insert only (x) set-word! block! ]
]
foreach [key value] data [
if block? value [
either find to-string key "+" [
parse data [ to [set-word! block!] set-word! insert ('reduce) to end ]
] [
; parse data [to [set-word! block!] change set-word! ('object)]
]
walk value
]
]
]
walk data
]
foo
probe data
But all problem with commented lines. It should change
every block
name without +
symbol to object
like: lot: []
should become object []
but it does not.
Could you help me?
- hiiamboris
- toomasv
- 11:13@bubnenkoff Is this you aim for?
{"lots":[{"foo":null},{"bar":null,"baz":null,"objects":[{"price":123,"count":1},{"item":"apples"},{"item":"bananas"}]}]}
- bubnenkoff
- 11:16@toomasv yes, one moment I am looking more detail, but it's seems that yes
- toomasv
- 11:17Quite a challenge it was:
type: copy []
in-array?: yes
parse data rule: [any [
s: copy x [any [set-word! not block! skip] e:]
opt [if (all [in-array? not empty? x]) (b: change/part s reduce ['object x] e) :b]
change copy x set-word! (
insert type in-array?
either in-array?: #"+" = first y: form x [reduce [to-set-word next y 'reduce]]['object]
)
[ahead block! [into rule (in-array?: take type)] | skip]
]]
print to-json object data
- bubnenkoff
- 11:22Oh my god!
P.S. I did not checked you example but in json string first object [ item1: none ]
was missed
- toomasv
- 11:23
probe data
[object [item1: none] lots: reduce [object [foo: none] object [bar: none baz: none objects: reduce [object [price: 123 count: 1] object [item: "apples"] object [item: "bananas"]]]]]
- bubnenkoff
- 11:24One moment) I am trying to understand how it's works)) it's too different from my attempt))
- toomasv
- 11:27First
objet [item1: none]
is lost because it is not retained in result after object data
-- there is no set-word for it.
- bubnenkoff
- 11:30> First
objet [item1: none]
is lost because it is not retained in result after object data
-- there is no set-word for it.
Yes! I just discovered this problem! Is there any way so save it?
- toomasv
- 11:36Well, you design the output :)
- bubnenkoff
- 11:39it seems that it's work:
print to-json reduce data
!
- toomasv
- 11:40Ok, change
in-array?: no
:
{"item1":null,"lots":[{"foo":null},{"bar":null,"baz":null,"objects":[{"price":123,"count":1},{"item":"apples"},{"item":"bananas"}]}]}
- bubnenkoff
- 11:41Hah! it's work too!
- toomasv
- bubnenkoff
- 11:41ah... one moment, I will look again11:42You are right! I am losing
lots:
- toomasv
- 11:43But with my way
item1
is not in separate object any more
- bubnenkoff
- 11:46Thanks... I am looking at code, it seems that you are right....11:50@toomasv Egh... it's seems that your are right again, and it's more correctly not to make other key-value not part of object, but be as you did with first element....11:52Ah... one moment %) they are part of an array so they should be an object
- lucindamichele
- 00:33https://youtu.be/CMNry4PE93Y
- ALANVF
- 00:53why post that here?
- greggirwin
- 04:28May have been mis-posted. 04:31Lucinda helped us with PR for a while, and probably remembers me as a zombie child.
- GiuseppeChillemi
- 06:47Maybe Lucinda has a Children and was he who mis-posted
- ne1uno
- 10:04@iceflow19 is zombie
- GiuseppeChillemi
- 11:26OMG, you are confusing me. Is it an affirmation? Is it a Joke? Is someone else with a fake account? Is he really a Zombie from the world of deads? Do you know something about @iceflow19 we do not know? Are you him??? 😱
- ne1uno
- 11:31never let a crisis go to waste
- GiuseppeChillemi
- 12:54You have been awarded with the first prize in cryptology. 🏆
- cosacam1
- 19:21Hi everybody19:27 I have problems with split. It brakes a quoted string in several words and I want the quoted string as a whole. For example.
s: {john mary "Life is good" truck plane} r: split s " " print r
- hiiamboris
- 19:32use
parse
- cosacam1
- 19:32The result is
[john mary {"Life} "is" {good"} truck plane]
however I need the quoted sentence not to be splitted. Is it possible? Thanks.
- hiiamboris
- 19:32https://www.red-lang.org/2013/11/041-introducing-parse.html
- cosacam1
- 19:37Yes I considered to use parse (though difficult for me yet) so I tried split, maybe with a /only refinement but split doesn't have it. Any other way to do it? Only through parse?
- greggirwin
- 19:38
>> print mold load-csv/with s " "
[["john" "mary" "Life is good" "truck" "plane"]]
Just pull the first item in the result block, since CSV make it a "row".
- cosacam1
- 19:41Impressive! Thanks a lot19:44 Anyway I must study hard parsing
- greggirwin
- 19:44It's an advanced topic. Do the easy thing when you can. :^)
- hiiamboris
- 19:53nice solution ;)
- rebolek
- 09:15@greggirwin hah, I would've never thought of that :D09:17@cosacam1 here's the
parse
version:
parse s [collect [some [#"^"" keep to #"^"" skip | keep to space skip]]]
- cosacam1
- 11:04Thanks both.15:13I see to-csv is a function in csv.red. I guess I must #include %cav.red in my program. I wonder if it is possible to do it in Red like in Python: from some module import somefunctio. Is it?
- rebolek
- 15:17Not yet, Red will get module support eventually. However, you can write your own Python-like
import
right now, if you want.
- cosacam1
- 15:31Let me finish my app first. Thanks. It would be a good exercise. I hope I can do it16:11@rebolek to use your solution with parse I must include a space at the end of the source string otherwise the last element (plane in my example) is not collected. Ok, I can handle that
- rebolek
- 16:57@cosacam1 you're right. sorry, I'm somehow missed it. Here's the correct version:
>> parse s [collect [some [#"^"" keep to #"^"" skip | keep to space skip] keep to end]]
== ["john" "mary" "Life is good" "truck" "plane"]
- cosacam1
- 12:48Thanks again
- bubnenkoff
- 18:45Is there any way to prevent auto-parsing values?
I want to create word: foo@bar:
but it's recognizing as wrong email
- hiiamboris
- 19:04
@
is an invalid char in words
- greggirwin
- 19:09You *can* work around it, but you'll end up creating more problems for yourself in the long run. Once you have
email!
values, you can modify them and convert them to words.
- ALANVF
- 22:09@hiiamboris that's interesting, I discovered the other day that
+@a
is a valid word22:10[](https://files.gitter.im/5780ef02c2f0db084a2231b0/73He/image.png)
- GiuseppeChillemi
- 22:23In Rebol even
"+@ print hello word!"
is a valid word.
>> type? probe to-word "+@ print hello word!"
+@ print hello word!
== word!
>>
- ALANVF
- 22:23lol
- GiuseppeChillemi
- 22:25I think it could have a valid reason. You can create phrases that act as a single function, or couple of words with
verb
+ subject
like add row |
which could be useful for human oriented languages.
- ALANVF
- 22:32I personally think it's just an oversight in the lexer22:32but sure
- greggirwin
- 22:42@ALANVF worth a ticket on that lexer issue, if not already there.
- ALANVF
- 22:43I would but I'm not sure why it happens in the first place22:43in theory,
@
should never be allowed in words22:44(also not really sure what to search on github for this issue lol)
- greggirwin
- 22:47Start by looking for
lexer
and email
. I think it's just a lexer bug when +/-
are followed by @
.
- ALANVF
- 22:53ahhh I'll bet I know why it happens then22:58since rebol allows it, maybe it should be kept?
- greggirwin
- 23:02Q1) Can email addresses, per their spec, have only
+/-
as the user part?
Q2) Even if the spec allows it, does it make any sense or have any practical use?
If either of those are No, keep it as is and make a note somewhere.
- ALANVF
- 23:03I don't see any good reason to have
+
/-
as the user part in an email, though I can look into it further
- GiuseppeChillemi
- 11:03@ALANVF I think that's because the combination could have meaning outside the emails context. So you are left free to build words like
+@data
for your DSL.
- gltewalt
- 15:37If it's
/
or //
it throws "operator is missing an argument".
If you stack more of them, so it doesn't think it is math, it is word! again
- dukereg:matrix.org
- 21:00How do you make a function that uses refinements? I found documentation of how to make a refinement! symbol but not how they are worked into functions. Any links to examples would be appreciated
- greggirwin
- 21:05Look at the source for
view
. We can craft an example, but if you do ? function!
you'll see all the mezz level funcs that you can use source
on and poke around from there.21:06You can also look at http://www.rebol.com/docs/core23/rebolcore-9.html#section-3.4
- dukereg:matrix.org
- 21:20Thanks, that link should suffice
- cosacam1
- 02:17Hi. I posted this question earlier today but I don't see it here so here I go again. Text-list will show a vertical scroll bar when needed but neither drop-list nor drop-down do it. What must be done so the scroll bar shows? Thanks
- GalenIvanov
- 07:04@dukereg:matrix.org
> How do you make a function that uses refinements? I found documentation of how to make a refinement! symbol but not how they are worked into functions. Any links to examples would be appreciated
Maybe [this](https://github.com/red/red/wiki/A-short-introduction-to-Red-for-Python-programmers#functions) will help you.
- toomasv
- 07:51@cosacam1 Add
scrollable
, e.g. view [drop-list 150 data read %./ scrollable]
NB! It seems to be not documented, maybe experimental/temporary?
- greggirwin
- 12:30@qtxie can you say if it's experimental, or maybe platform specific? In any case, we should doc it, and can note limitations or caveats.
- cosacam1
- 12:48Thanks both but my red 0.6.4 says invalid syntax at: [scrollable], both in my program and in Toomas example in CLI
- greggirwin
- 13:14Are you using the very old "stable" build, or automated? If stable, use the automated build.
- hiiamboris
- 13:41Maybe we should remove
b
from "stable"
- greggirwin
- 13:52<rimshot>
- ldci
- 14:19Toomas’s sample runs under Windows 11 but not under macOS
- cosacam1
- 18:17I'm using Windows 10. Please, clarify me about stabla and automated versions of Red. i'm using a version I downloaded a couple of months ago or less
- hiiamboris
- 18:23see the build date:
>> about
Red 0.6.4 for Windows built 1-Jun-2022/7:18:47+03:00 commit #c619918
- cosacam1
- 18:59Wow, mine is 21-Nov-2018. But I'm pretty sure I downloaded it recently. Well, I'm 60 years old. Maybe that explains everything. haha. And I'm still programming!
- hiiamboris
- 19:01Great!19:02you should download the automated build, we don't recommend "sta(b)le" to anyone
- cosacam1
- 19:15I just browsed what I downloaded recently. it was downloaded on may 24 but it's nov 2018 version. Where is the automated version? On github?
- hiiamboris
- 19:16on the same download page
- cosacam1
- 19:19I'm seeking... Oh, 2 june 2022 downloaded. Let me see...
- hiiamboris
- 19:2119:22actually it has a huge regression since 1st of june, but if you're not using
hash!
you're good
- cosacam1
- 20:17downloaded, installed, running, drop-list with scroll bar ok, also load as fast as read. In the Bible application I'm writing reading the Bible database (about 3 Mb) was fast but loading it was way too slow more than 15 seconds. Not so in rebol. Now kn this Red version both are fast. I'm sure I'll rind more improvements. Thank you all.
- hiiamboris
- 20:30:+1:
- qtxie
- 06:23> @qtxie can you say if it's experimental, or maybe platform specific? In any case, we should doc it, and can note limitations or caveats.
It's experimental. It's made for the gui-console. IIRC, it has been implemented on Windows and macOS backend.
- ALANVF
- 20:28mostly concerned with the decimal part at the end for milliseconds
- hiiamboris
- 20:45https://github.com/red/red/pull/5069 in this branch
- ALANVF
- 20:45ah, so that's a no for now I guess
- hiiamboris
- 20:45yep
- ALANVF
- 20:45dang
- hiiamboris
- 21:40https://codeberg.org/hiiamboris/red-common/src/branch/master/timestamp.red
you can do a quick hack if you really need it I guess21:40just no standard/flexible way
- ALANVF
- 21:40I figured something out21:41in the process, I discovered that using
on-time
on a 10ms delay is slower than on a 100ms delay (who knew?)
- hiiamboris
- 21:46https://github.com/red/REP/issues/26
- ALANVF
- 21:48ah that explains it
- ALANVF
- 21:06apparently when using a
toggle
rather than a button
, all text id aligned to the right if it has a custom font and has a short width21:06[](https://files.gitter.im/5780ef02c2f0db084a2231b0/3IiN/image.png)21:06compared to a button:21:06[](https://files.gitter.im/5780ef02c2f0db084a2231b0/L78r/image.png)21:06any ideas why?
- hiiamboris
- 21:12report a bug if one does not exist
- ALANVF
- 21:12wasn't sure if it was intentional or not21:13skimming through the View code, I don't see why it would be happening
- hiiamboris
- 21:13https://github.com/red/red/issues/428021:13closed but root issue is the same obv
- ALANVF
- 21:13hmm ok
- hiiamboris
- 21:14https://github.com/red/red/issues/4429 also related (for cross linking)
- ALANVF
- 21:16do you think it's this? https://github.com/red/red/blob/master/modules/view/backends/windows/events.reds#L929
- hiiamboris
- 21:21unless you see a relation with font, then no
- ALANVF
- 21:21this is specifically when I add a font
- hiiamboris
- 21:21I mean that part of code21:21doesn't look like font related
- ALANVF
- 21:22ok that actually was it lmao
- hiiamboris
- 21:24haha21:25push a fix then
- ALANVF
- 21:25doing that now :+1:21:30#5152
- cosacam1
- 10:20Hi guys. I've been studying Helpin Red and Red by example/parse and I can count the times a substring appears in a string, but I have not found out how to count the exact word. For example "less" appears 4 times in "A lesser blessing is less than blessed" but the exact word is just once. How can I tell parse to count only the exact word "less". Thanks
- hiiamboris
- 10:21use
split
first
- cosacam1
- 11:07Yes, I though that, but in that case I must remove any punctuation symbols before so I can split on spaces. Ok, thanks.
- hiiamboris
- 11:07then define a parse rule what is a *word* and count on it
- cosacam1
- 11:27Right
- ldci
- 15:32@cosacam1 . A sample
#! /usr/local/bin/red
Red [
Needs: 'View
]
flag: 1
punct: rejoin [",.;:!?-_(){}'" form #"^""]
loadFile: does [
tmp: request-file
unless none? tmp [
txt: lowercase read tmp ;--lowercase for all text
trim/lines txt ;--suppress all line breaks and extra spaces in text
ar/text: read tmp ;--orginal text
countWords ;--count words in text
]
]
removePunct1: function [
aText [string!]
][
trim/with aText punct ;--trim method
]
removePunct2: function [
aText [string!]
][
remove-each c aText [find punct c] ;--remove-each method
]
removePunct3: function [
aText [string!]
][
_punct: charset punct
parse aText [any [remove _punct | skip]] ;--parse method
]
countWords: does [
foreach fcval [wordsList f1 f2] [face: get fcval clear face/text]
copycat: copy txt ;--a copy since methods modify text
do-events/no-wait
t1: now/time/precise
switch flag [
1 [removePunct1 copycat]
2 [removePunct2 copycat]
3 [removePunct3 copycat]
]
wordBlock: split copycat space ;--get words
sort wordBlock ;--sort words
n: length? wordBlock; - 1
count: 1
wordCount: copy []
repeat i n [
key1: wordBlock/:i key2: wordBlock/(i + 1)
either key1 = key2 [count: count + 1][append wordCount rejoin [key1 ": " count] count: 1]
]
;append wordCount rejoin [key1 ": " count] ; last word in block
wordsList/text: ""
foreach v wordCount [append wordsList/text rejoin [v newline]]
t2: now/time/precise
elapsed: to-integer (third t2 - t1) * 1000
f1/text: rejoin [form n + 1 " words"]
f2/text: rejoin ["in " form elapsed " ms"]
]
mainWin: layout [
title "Word Count: Tests"
button "Load" [loadFile]
drop-down 80 data ["Trim" "Remove" "Parse"]
select 1
on-change [flag: face/selected countWords]
f1: field 120 center
f2: field 100 center
pad 140x0
button "Quit" [Quit]
return
ar: area white 400x400 wrap
font [name: "Arial" size: 14 color: black]
wordsList: area black 200x400
font [name: "Arial" size: 14 color: green]
]
view mainWin
15:35@cosacam1. With 3 different methods for word counting :)
- ALANVF
- 21:01[](https://files.gitter.im/5780ef02c2f0db084a2231b0/VNlJ/image.png)21:01how do you make a context menu like this in View that includes the keyboard shortcuts on the side?
- greggirwin
- 21:04[menu.red](https://files.gitter.im/5780ef02c2f0db084a2231b0/hAYf/menu.red)
- ALANVF
- 21:06[](https://files.gitter.im/5780ef02c2f0db084a2231b0/tG6E/image.png)21:06yeah but then it's not aligned 21:06also, having access to those menu dividers would be nice though not necessary
- greggirwin
- 21:06Did you run what I posted?
- ALANVF
- 21:07not yet, only looked21:07oh
- greggirwin
- 21:07So...maybe do that, and read the comments.
- ALANVF
- 21:09ahhh it uses tabs21:09thanks
- greggirwin
- 21:11Menus are mentioned in https://github.com/red/docs/blob/master/en/view.adoc, but not doc'd. As you explore, including popups, that would be a great task.
- ALANVF
- 21:11yeah I noticed that, I could probably work on that after I finish this demo
- greggirwin
- 21:11:+1:21:12The best time to write docs is when what you didn't know is fresh in your mind. :^)
- ALANVF
- 21:12and related, I think it'd be nice if the
menu
option was available within VID21:12the current method is... clunky
- greggirwin
- 21:16You can do it this way:
view layout/options [size 640x480] [
menu: [
"File" [
"New Ctrl+N" new
"New Window Ctrl+Shift+N" win
"Open ... Ctrl+O" open
"Save Ctrl+S" save
"Save As ... Ctrl+Shift+S" save-as
"Quit Ctrl+Q" quit
]
]
]
- ALANVF
- 21:17sure, but for multiline view blocks it's kinda out of place since you have to scroll all the way to the bottom to view the config
- greggirwin
- 21:17It's a good thought experiment for you. Why *isn't* it included in VID already?
- ALANVF
- 21:18there's also the issue of
menu
for widgets that support it21:18yeah
- greggirwin
- 21:19
window-opts: [
menu: [
"File" [
"New Ctrl+N" new
"New Window Ctrl+Shift+N" win
"Open ... Ctrl+O" open
"Save Ctrl+S" save
"Save As ... Ctrl+Shift+S" save-as
"Quit Ctrl+Q" quit
]
]
]
view layout/options [size 640x480] window-opts
Now it comes first. :^)
- ALANVF
- 21:19ehhh
- hiiamboris
- 21:21Personally I consider having word commands in the menu a mistake. Something I avoided in Spaces.
- ALANVF
- 21:22yeah I also think it's a bit odd
- greggirwin
- 21:22So think about it. Is that *really* better overall? How so? Does it come with any tradeoffs? Are menus really part of the layout? Do you think it just hasn't been considered? Of course, here I agree that if we *did* think about it, and decided not to include it that way, it would be good to mention.21:22Do you use strings, or func refs in
spaces
@hiiamboris? Or something else?
- ALANVF
- 21:23well my thing is that many other properties are directly configurable for the window object as well as other widgets in VID21:23so it would make sense for menus to also be supported there
- greggirwin
- 21:24Feel free to spec out the rationale your design, and post it. But maybe @dockimbel will weigh in on the current design before too long.21:25Consistency in how container options are handled is a good goal.
- hiiamboris
- greggirwin
- 21:29Ah, interesting, so you can include code directly. Nice idea.
- hiiamboris
- 21:29Yeah. I hate that words appear in different places and have to be kept in sync. Humans have better things to do
- greggirwin
- 21:30I do like the aspect of words that menus are best suited as a dispatch mechanism, and that making you put things behind words makes those access points from code.21:31Menus are arg-less commands (though don't rule out the idea of menu currying :^).
- hiiamboris
- 21:31
"menu line" (call your func)
is no less powerful, but doesn't require indirection
- greggirwin
- 21:32So even if I used parens in spaces, I would almost certainly never inline code there.21:33Agreed, that's why I first asked if you used func, e.g. via get-words, to avoid that.
- hiiamboris
- 21:33it's just normal code block, use func when it works
- greggirwin
- 21:35It's possible that
menu
could add paren support, as it shouldn't break anything. Something to remember.
- gltewalt
- 21:35> Yes, I though that, but in that case I must remove any punctuation symbols before so I can split on spaces. Ok, thanks.
Why must you remove punctuation?21:38
>> b: split "A lesser blessing is less than blessed!" space
== ["A" "lesser" "blessing" "is" "less" "than" "blessed!"]
>> n: 0
== 0
>> foreach element b [if find element "less" [n: n + 1]]
== 4
- hiiamboris
- 21:40you're not solving his task :)
- gltewalt:matrix.org
- 21:50I thought he wanted to count "less"
- greggirwin
- 22:02> How can I tell parse to count only the exact word "less".
- gltewalt:matrix.org
- 22:10Well if he insists on parse...
- greggirwin
- 22:26I think the key is that he wants to match the exact word, which implies ignoring punctuation.
- GiuseppeChillemi
- 23:39Is there a quick way to avoid typing the same word and perform a series of operations on it, and at the end it will be updated to the new value?
Example:
value: 0
value: value + 22
value: value * 50
value: value + (totals/income)
value: value - calculate-depreciation tot 01/01/2000 01/01/2022
Should be:
value: 0
do-operation 'value [
+ 22
* 50
+ (totals/income)
- calculate-depreciation tot 01/01/2000 01/01/2022
]
Has anyone done something like this?
- gltewalt:matrix.org
- 00:38Conditional assignment?00:39People have done a few different "method chain" styles
- gltewalt
- 02:55probably something like:
value: if 'true [
do reduce [
0
+ 22
* 50
+ (totals/income)
- calculate-depreciation tot 01/01/2000 01/01/2022
]
]
- toomasv
- 04:46
value + 22 * 50 + …
- cosacam1
- 08:43Hi again. @ldci thanks for your program, actually more than what I needed. You count every word in the text, I only needed to count one. Thanks a lot. And you put a bonus- three methods to remove punctuations! I just made an improvement- instead of appending directly to wordsList/text I did it to a temporary list, then I assigned it to wordList/text
`wl: copy ""08:45foreach v wordCount [append wl rejoin [v newline]]08:45wordsList/text: wl
`08:46It' much faster08:48Anyway I had done my program too. Here it is
Red [needs: view]
letter: charset [#"A" - #"Z" #"a" - #"z" "áéíóúüñ-"] ; every letter in Spanish
; not interested in capital accented ones nor Ñ
; but interested in compound words like Baal-peor with a hyphen
do-search: func [wrd [string!]] [
cnt: 0 ; the counter
foreach s txt [ ; for every string in the text
init-len: length? s
n2: 1 ; start searching the word from the beginning of the string
done: false
until [
p1: none ; points to where the word appears in the string
p2: none ; points to the char right after the word found in the string
parse/case at s n2 [to wrd p1: thru wrd p2:] ; note that parsing starts at n2 in every loop, see below
either p1 [ ; is the word present in the string?
n1: index? p1 ; index of the first char of the word in the string
n2: index? p2 ; index of char right after the word; besides, is where the next parsing will start
; next, is the word the first one in the string?
; otherwise, is it not preceded by any letter?
; I mean, is it not a part of a longer word?
startOk: any [n1 = 1 not find letter s/(n1 - 1)]
; next, is the word the last one in the string?
; otherwise, is it not succeded by any letter?
; I mean, is it not a part of a longer word?
endOk: any [n2 > init-len not find letter p2/1]
if all [startOk endOk] [cnt: cnt + 1] ; the "exact word" has been found
done: n2 > init-len ; the whole string is parsed?
][done: true]
done
]
]
r/text: rejoin [wrd " has been found " cnt " times"]
]
view [
title "Counting Exact Words"
button "Load" [ff: request-file if ff [txt: read/lines ff]]
text "Word to search for" f: field
button "Search!" [do-search f/text]
return
r: text 200
]
08:49What do you think?
- ldci
- 09:19@cosacam1 Could you send a formatted version of your code? Muchas gracias.
- cosacam1
- 10:35I'll try again10:38
Red [needs: view]
letter: charset [#"A" - #"Z" #"a" - #"z" "áéíóúüñ-"] ; every letter in Spanish
; not interested in capital accented ones nor Ñ
; but interested in compound words like Baal-peor with a hyphen
do-search: func [wrd [string!]] [
cnt: 0 ; the counter
foreach s txt [ ; for every string in the text
init-len: length? s
n2: 1 ; start searching the word from the beginning of the string
done: false
until [
p1: none ; points to where the word appears in the string
p2: none ; points to the char right after the word found in the string
parse/case at s n2 [to wrd p1: thru wrd p2:] ; note that parsing starts at n2 in every loop, see below
either p1 [ ; is the word present in the string?
n1: index? p1 ; index of the first char of the word in the string
n2: index? p2 ; index of char right after the word; besides, is where the next parsing will start
; next, is the word the first one in the string?
; otherwise, is it not preceded by any letter?
; I mean, is it not a part of a longer word?
startOk: any [n1 = 1 not find letter s/(n1 - 1)]
; next, is the word the last one in the string?
; otherwise, is it not succeded by any letter?
; I mean, is it not a part of a longer word?
endOk: any [n2 > init-len not find letter p2/1]
if all [startOk endOk] [cnt: cnt + 1] ; the "exact word" has been found
done: n2 > init-len ; the whole string is parsed?
][done: true]
done
]
]
r/text: rejoin [wrd " has been found " cnt " times"]
]
view [
title "Counting Exact Words"
button "Load" [ff: request-file if ff [txt: read/lines ff]]
text "Word to search for" f: field
button "Search!" [do-search f/text]
return
r: text 200
]
10:39What I'm I doing wrong? It does not format10:40Red [needs: view]
letter: charset [#"A" - #"Z" #"a" - #"z" "áéíóúüñ-"] ; every letter in Spanish
; not interested in capital accented ones nor Ñ
; but interested in compound words like Baal-peor with a hyphen
do-search: func [wrd [string!]] [
cnt: 0 ; the counter
foreach s txt [ ; for every string in the text
init-len: length? s
n2: 1 ; start searching the word from the beginning of the string
done: false
until [
p1: none ; points to where the word appears in the string
p2: none ; points to the char right after the word found in the string
parse/case at s n2 [to wrd p1: thru wrd p2:] ; note that parsing starts at n2 in every loop, see below
either p1 [ ; is the word present in the string?
n1: index? p1 ; index of the first char of the word in the string
n2: index? p2 ; index of char right after the word; besides, is where the next parsing will start
; next, is the word the first one in the string?
; otherwise, is it not preceded by any letter?
; I mean, is it not a part of a longer word?
startOk: any [n1 = 1 not find letter s/(n1 - 1)]
; next, is the word the last one in the string?
; otherwise, is it not succeded by any letter?
; I mean, is it not a part of a longer word?
endOk: any [n2 > init-len not find letter p2/1]
if all [startOk endOk] [cnt: cnt + 1] ; the "exact word" has been found
done: n2 > init-len ; the whole string is parsed?
][done: true]
done
]
]
r/text: rejoin [wrd " has been found " cnt " times"]
]
view [
title "Counting Exact Words"
button "Load" [ff: request-file if ff [txt: read/lines ff]]
text "Word to search for" f: field
button "Search!" [do-search f/text]
return
r: text 200
]
`10:41
Red [needs: view]
letter: charset [#"A" - #"Z" #"a" - #"z" "áéíóúüñ-"] ; every letter in Spanish
; not interested in capital accented ones nor Ñ
; but interested in compound words like Baal-peor with a hyphen
do-search: func [wrd [string!]] [
cnt: 0 ; the counter
foreach s txt [ ; for every string in the text
init-len: length? s
n2: 1 ; start searching the word from the beginning of the string
done: false
until [
p1: none ; points to where the word appears in the string
p2: none ; points to the char right after the word found in the string
parse/case at s n2 [to wrd p1: thru wrd p2:] ; note that parsing starts at n2 in every loop, see below
either p1 [ ; is the word present in the string?
n1: index? p1 ; index of the first char of the word in the string
n2: index? p2 ; index of char right after the word; besides, is where the next parsing will start
; next, is the word the first one in the string?
; otherwise, is it not preceded by any letter?
; I mean, is it not a part of a longer word?
startOk: any [n1 = 1 not find letter s/(n1 - 1)]
; next, is the word the last one in the string?
; otherwise, is it not succeded by any letter?
; I mean, is it not a part of a longer word?
endOk: any [n2 > init-len not find letter p2/1]
if all [startOk endOk] [cnt: cnt + 1] ; the "exact word" has been found
done: n2 > init-len ; the whole string is parsed?
][done: true]
done
]
]
r/text: rejoin [wrd " has been found " cnt " times"]
]
view [
title "Counting Exact Words"
button "Load" [ff: request-file if ff [txt: read/lines ff]]
text "Word to search for" f: field
button "Search!" [do-search f/text]
return
r: text 200
]
10:42Sorry I can't
- ldci
- 11:00Something like that
Red [
needs: view
]
letter: charset [#"A" - #"Z" #"a" - #"z" "áéíóúüñ-"] ; every letter in Spanish
; not interested in capital accented ones nor Ñ
; but interested in compound words like Baal-peor with a hyphen
do-search: func [
wrd [string!]
][
cnt: 0 ; the counter
foreach s txt [ ; for every string in the text
init-len: length? s
n2: 1 ; start searching the word from the beginning of the string
done: false
until [
p1: none ; points to where the word appears in the string
p2: none ; points to the char right after the word found in the string
parse/case at s n2 [to wrd p1: thru wrd p2:] ; note that parsing starts at n2 in every loop, see below
either p1 [ ; is the word present in the string?
n1: index? p1 ; index of the first char of the word in the string
n2: index? p2 ; index of char right after the word; besides, is where the next parsing will start
; next, is the word the first one in the string?
; otherwise, is it not preceded by any letter?
; I mean, is it not a part of a longer word?
startOk: any [n1 = 1 not find letter s/(n1 - 1)]
; next, is the word the last one in the string?
; otherwise, is it not succeded by any letter?
; I mean, is it not a part of a longer word?
endOk: any [n2 > init-len not find letter p2/1]
if all [startOk endOk] [cnt: cnt + 1] ; the "exact word" has been found
done: n2 > init-len ; the whole string is parsed?
][done: true]
done
]
]
r/text: rejoin [wrd " has been found " cnt " times"]
]
view [
title "Counting Exact Words"
button "Load" [ff: request-file if ff [txt: read/lines ff]]
text "Word to search for" f: field
button "Search!" [do-search f/text]
return
r: text 200
]
- cosacam1
- 11:37Thanks that's what I tried to do. I used the three apostrophs. Isn't it the way to do it? Thanks anyway
- toomasv
- 11:41Apostrophs on separate line.
- ldci
- 11:41Don’t forget shift+enter for line break:)
- cosacam1
- 16:52Thanks. Today is Father's Day in my country and some other ones so Congratulations and Blessings to all fathers in the Red community.
- gltewalt
- 23:36Blocks can be typed out however is pleasing to you.
value: do reduce [
value
+ 22
* 50
+ (totals / income)
- calculate-depreciation tot 01/01/2000 01/01/2022
]
- ALANVF
- 18:26even better, use a paren
- BuilderGuy1
- 16:47simple question; I want to make a Block of Blocks. How do I add an existing block into my Block of Blocks without it being added as a String?16:48
>> a: [["a" "b" "c"]]
== [["a" "b" "c"]]
>> b: ["z" "v"]
== ["z" "v"]
>> append a b
== [["a" "b" "c"] "z" "v"]
:-(
- ne1uno
- 16:51@BuilderGuy1, try
append/only a b
- BuilderGuy1
- 16:52Works! Awesome Thanks!16:52I will reread the docs to understand why that works
- hiiamboris
- 16:59
? append
- BuilderGuy1
- 17:31@hiiamboris I checked that too. Reading "Insert block types as single values" seemed like it would be inserting a single "string" as that's what APPEND was already doing. I understand now, but the description was not clear enough for me.
- hiiamboris
- 17:33Nice imagination ;)
- greggirwin
- 17:38@BuilderGuy1 it wasn't appending as a string, but as the values inside the block.
>> a: [["a" "b" "c"]]
== [["a" "b" "c"]]
>> b: [1 @builderguy 2x3 <oh no!>]
== [1 @builderguy 2x3 <oh no!>]
>> append a b
== [["a" "b" "c"] 1 @builderguy 2x3 <oh no!>]
- BuilderGuy1
- 17:40That makes sense. Looking closer it's clear it isn't a string. Thanks!
- loziniak
- 12:21hi, am I doing something wrong? I want to delete *map!* element:
>> m: #(k1: 1 k2: 2)
== #(
k1: 1
k2: 2
)
>> m/k1: none
== none
>> m
== #(
k1: none
k2: 2
)
12:22[in docs](https://red-language-documentation.readthedocs.io/en/latest/Map!-datatype/): "In order to delete a key/value pair from a map, you simply set the key to none value using one of the available ways."
- toomasv
- loziniak
- 12:29<312:32thanks
- toomasv
- loziniak
- 12:38ok, I had also an outdated link to documentation. on github it's already fixed: https://github.com/red/docs/blob/master/en/datatypes/map.adoc#removing-keys
- greggirwin
- 13:54We need to see where readthedocs gets its data, or how to refresh or remove it, if it's out of date.
- GiuseppeChillemi
- 12:34Pardon my ignorance about the sum of floating point numbers: is it normal that summing a lot of numbers like
180.0 20.4 40.6
I get a number with many digits like: 346773.38999999996
13:11(a result I have got in red summing 1000 of such numbers) 13:12I have also counted decimals after the decimal point and none was over length of 1.
- endo64
- 14:22I think it is about
mold
>> s: 20.4 + 20.4 + 20.4
== 61.2
>> mold s
== "61.199999999999996"
>> print s
61.2
- GiuseppeChillemi
- 14:48I have used Probe14:48I have summed and probed the total value14:58I confirm: if you
PRINT
it, you get 2 digits; if you PROBE
it, you get all digits. I don't now if PROBE/MODEL
work is correct. To you the answer.
- Respectech
- 16:02This is a well-known issue in the binary representation of floating-point numbers in computer science. Any language that uses floating-point numbers in the pure binary representation will run into this issue. The reason to use this type of floating-point number is speed, so most languages concerned with speed use this method.
- hiiamboris
- 16:33Use https://en.m.wikipedia.org/wiki/Pairwise_summation16:33And round16:35You can also sum numbers as 'money'
- GiuseppeChillemi
- 19:30Thank you
- GiuseppeChillemi
- 21:58Is it possible to convert from yearday to date?
- hiiamboris
- ALANVF
- 22:01wondering if this is intentional or not? accessing the
size
of the window during initialization will not access the configured size, for example:
view [
size 500x500
base with [
size: parent/size
]
]
will cause the base
widget to have a size of 100x100, since that's the default size for the window
- GiuseppeChillemi
- 22:11@hiiamboris Thank you, I remember there where accessors but I forgot how to use them22:12And, how whould I do to list all accessors?
- ne1uno
- 22:19
print [system/catalog/accessors/date!]
- GiuseppeChillemi
- 22:37I have made a typo and something interesting has happened:
>> probe d:week
d:week
== d:week
>> probe type? d:week
url!
Is this correct?
- Respectech
- 22:59Yes.
- GiuseppeChillemi
- 23:03Thank you, I am also having a problem with date accessors: I am able to calculate everything but 2 values:
* The end of the last/next/nth month, without having an auxiliary table
* The end of the year without doing math by myself to understand if the year is a leap one.
* The last week of of the year as they are sometime 52 and sometime 53
All other calculations are doable but I can't say:
date/yearday 'last
or
date/day 'last
or
date/week 'last
- Respectech
- 23:19Here is one way to solve it without tables:
>> d2: now/date
== 28-Jun-2022
>> d2/month: d2/month + 2
== 8
>> d2/day: 1
== 1
>> d2: d2 - 1
== 31-Jul-2022
>> d2/day
== 31
23:21
>> d2/year: d2/year + 1
== 2023
>> d2/month: 1
== 1
>> d2/day: 1
== 1
>> d2: d2 - 1
== 31-Dec-2022
>> d2/yearday
== 365
23:22I did these samples in R2, but I imagine the same/similar could be done with Red.23:26Here's a slightly shorter method:
>> d2: now/date
== 28-Jun-2022
>> d2/year: d2/year + 1
== 2023
>> d2: d2 - d2/yearday
== 31-Dec-2022
>> d2/yearday
== 365
- GiuseppeChillemi
- 23:30Thank you.
- ALANVF
- 00:09is there a way to animate a GIF in View?
- greggirwin
- 00:16@GiuseppeChillemi I have old funcs for those, but it sounds like you want to avoid some approaches. In any case, there's a subtlety to weeks in year. This is old R2 code:
;ISO 8601 specifies that Week 01 of the year is the week containing
;the first Thursday; Monday is Weekday 1, Sunday is Weekday 7;
weeks-in-year: func [year [date! integer!]] [
if date? year [year: year/year]
jan-1: to-date join "1-Jan-" year
dec-31: to-date join "31-Dec-" year
52 + either any [equal? 4 jan-1/weekday equal? 4 dec-31/weekday] [1] [0]
]
00:24@ALANVF on window sizing, it's expected. The panel (parent) size isn't set until the entire layout is processed. Whether that could change is a good question for @qtxie or @dockimbel. That is, it could be set when size
is seen, then later adjusted, but there may be a reason it doesn't do that.
- ALANVF
- 00:24it seems counterintuitive which is why I asked about it
- greggirwin
- 00:25On GIFs, I want to say someone wrote a codec for them in R2 and did it manually, but I don't remember it being done for Red.
- ALANVF
- 00:25in general, window and widget resizing is all sorts of annoying and probably needs reworked at some point00:26hmm, how hard would it be to add proper GIF support in that case?00:27(if you don't know that's fine, just thinking it could be put on the roadmap)
- greggirwin
- 00:30On sizing, there are things which may seem more convenient, but also have pretty easy solutions already. If @qtxie doesn't see an issue, initializing this one sooner seems and easy change.
On GIFs, there are a couple things 1) Does each OS have a standard loader for them? If not, it's a bit of work there. Then there are changes to event loop handling for them. The real question for me is value. I can see people wanting it, even if I don't. :^)
- ALANVF
- 00:32I can look into the loader thing tomorrow :+1:
- ne1uno
- 00:34
a: load %"animated.gif" ? a
locked up recent console. I only test a few images
- qtxie
- 01:35@ALANVF Opened an issue for it. https://github.com/red/red/issues/5154
- ALANVF
- 01:35:+1:
- cosacam1
- 03:18Hi guys. Has anyone converted a Red program into an Android apk? How to do that? Besides, taking acount that many Android devices have different screen sizes, how to make my application to look the same in any device? RFO-BASIC! has scale_width and scale_height (or something like that) for that matter. How to in Red? Also, does Red have functions for Android's SQLite? Thanks
- greggirwin
- 04:34Red's Android branch is quite stale at this time, and isn't production ready. When it was in active development, you could create an Android app without any other tools. SQLite bindings were never ported there AFAIK.
- cosacam1
- 10:47However I see the demo with the tiger. It is a real example, isn't it? And there's a library for SQL in github, right?
- GiuseppeChillemi
- 11:10Do we have a command to create a function with all locals but no specs block? Just the body argument....
- cosacam1
- 11:57Afaik all words used in
function
are local unless specified as /extern
- rebolek
- 12:25@GiuseppeChillemi I don't think there's such function. But making your own is very easy.
- Oldes
- 12:44@cosacam1 you mean _set-words_.12:45Having all words local would be pretty useless
- cosacam1
- 15:28Well, I mean all vars needed in the function can be local. The function receives parameters and returns a result. That's how the black box communicates with the outside world. If any outside global var needed, it can be declared as /extern. I'm talking about information hiding. That's what Giuseppe needs. Otherwise I missunderstood his question
- hiiamboris
- 15:36I think he wants a shortcut for
function []
- cosacam1
- 15:40Interesting
- gurzgri
- 15:50@cosacam1 Yes! :wink: And you really only *mean* words of type
set-word!
:wink: The Redbol languages have no notion of "variables". They only have values. Some of these values are of type word!
or it's different flavours like set-word!
, get-word!
etc. function
only binds words of type set-word!
to the context of the function it creates, with the exception of those declared as /extern
.
- greggirwin
- 16:36> However I see the demo with the tiger. It is a real example, isn't it? And there's a library for SQL in github, right?
The tiger demo is 100% real, and still runs on my Android phone, and you *may* be able to build things, but that branch is terribly out of date, so no guarantees. And, yes, there are bindings people have written, but I haven't heard of anyone using the SQLite binding on Android.
- cosacam1
- 17:27Thanks. I think Red development for Android should be a must. Smart phones are pocket computers everyone use now 24/7. I wish I had time and knowlege to enhance Red to its top!
- GiuseppeChillemi
- 17:49@rebolek yes, I know and it is super easy. Just asking if one exists, so I can use the standard one.
- cosacam1
- 20:14Yes, Rebol/Red has no vars as "some value is assigned to some symbol", but rather it is "some symbol is assigned to some value that exists in memory", kinda a pointer. That's what I refered to when I spoke of variables in a function. Ok, just briefing-
does
uses global words; has
uses globals and locals, the later are in spec; func
uses globals and locals specified by /local
; finally function
uses local words and globals specified by /extern
- cloutiy
- ldci
- 17:09Hi, I have a 10x10 gif that consists of 4 colors, white, red, blue, black.
47 49 46 38 39 61 0A 00 0A 00 91 00 00 FF FF FF FF 00 00 00 00 FF 00 00 00 21 F9 04 00 00 00 00 00 2C 00 00 00 00 0A 00 0A 00 00 02 16 8C 2D 99 87 2A 1C DC 33 A0 02 75 EC 95 FA A8 DE 60 8C 04 91 4C 01 00 3B
I'm able to parse the gif file and get the gif structures such as the Global Color Table
[#{FFFFFF} #{FF0000} #{0000FF} #{000000}]
I have image data above (labeled imageData) and I'm trying to decompress the data so that I get the original image.
imageData: [8C 2D 99 87 2A 1C DC 33 A0 02 75 EC 95 FA A8 DE 60 8C 04 91 4C 01 00]
GIF packs LZW codes into bytes in LSB-first order. The first code is stored as the 3 least-significant bits of the first byte; the second code as the next 3 bits; and so on.
Any idea?
- Oldes
- 17:54
load/as bin 'gif
isn't enough?
- ldci
- 18:24@Oldes. Thanks, that’s perfect for gif image with a unique image. Now the question is about a gif file with more than 1 image :)
- hiiamboris
- 18:28I guess you'll have to study how lempel-ziv decoding works
- ldci
- 18:29@hiiamboris. Yes, but I do not understand the logic :)
- hiiamboris
- 18:30find a better explanatory article ;)
- ldci
- 18:32@hiiamboris. https://www.matthewflickinger.com/lab/whatsinagif/ is very good :)
- hiiamboris
- 18:34yeah looks nice :+1:
- greggirwin
- 18:44https://github.com/rebol/rebol/blob/master/src/core/u-gif.c has LZW C code in it.
- ldci
- 18:49@greggirwin. Thanks a lot:)
- cosacam1
- 12:08Hi. I compiled the program I've been working on into an exe. I run it and it shows a CLI window besides the main window. Is there any way to not show CLI window? Thanks
- hiiamboris
- 12:12
-t windows
12:13red --help
12:15https://github.com/red/red/wiki/%5BDOC%5D-FAQ#how-do-i-make-it-so-that-compiled-gui-programs-on-windows-dont-spawn-a-parent-console-on-startup
- cosacam1
- 12:22Ok thanks
- ldci
- 20:30Is Red a vaporware? No commication on https://www.red-lang.org since December 31, 2021.
- ALANVF
- 20:31nah
- ldci
- 20:31communication :)
- ALANVF
- 20:31they're posting a new blog soon iirc
- ldci
- 20:36I have invested a lot in Red and Rebol before and I feel abandoned: no news about programming language advances.
- ALANVF
- 21:45lots of new things happen, we just don't always have the time to write about them
- dockimbel
- 21:46@ldci We are finishing a complete reorganization of the project. More news soon.
- GiuseppeChillemi
- 00:20I need to
copy/deep
an object but it truncates each of its series at index, and the new object has only series starting from it. Is there a command to copy/deep
an object and also PRESERVING every element in series which is before their current index?
- ldci
- 04:09@dockimbel Thanks
- hiiamboris
- 08:08No, @GiuseppeChillemi
- GiuseppeChillemi
- 10:04@hiiamboris I have made a little recursive function to copy/deep in each element, preserving the whole series but I don't know how to handle the danger of circular references.
- Oldes
- 10:06Your function would have to keep a map, what was already converted (copied) to what.10:07But I believe, that you are again in the field where you should not be. Mines are waiting for you!
- hiiamboris
- 10:46Just let it fail. 'copy/deep' does.
- GiuseppeChillemi
- 14:56@Oldes I am working on a datatype. made using an object which has the data container inside. It is a block which contains a table like:
make object! [
type: 'bob-table
Data: [[col1 col2 col3][1 2 3][4 5 6]]
....
]
data
block is kept using Red block position. So, when a I need another instance of the data, copy/deep
it,. The problem is that I get truncation of the data block, so if index is at 2, the new container will be without elements before.
make object! [
type: 'bob-table
Data: [[1 2 3][4 5 6]]
....
]
(Note: BOB = Block of Blocks ;-)
- hiiamboris
- 15:24here's a badass trick for you:
>> o: object [type: 'bobby data: reduce [next [1 2 3] next [a b c]]]
== make object! [
type: 'bobby
data: [[2 3] [b c]]
]
>> p: load/as save/as #{} o 'redbin 'redbin
== make object! [
type: 'bobby
data: [[2 3] [b c]]
]
>> head p/data/1
== [1 2 3]
>> head p/data/2
== [a b c]
>> same? p/data/1 o/data/1
== false
- GiuseppeChillemi
- 15:25Super Badass23:36How do I clean a string of the LF to not have them visibile?The original string spawns multiple lines in the source and when I print it I get the following:
{^/^-^-^-insert into MY-OWN-TABLE^/^-^-^-(col1 , col2 , col3)^/^-^-^-values^/^-^-^-('1' , '2' , '3''4' , 'a' , '6');^/^-^-}
I do not want to remove them but have a clean multiline output23:41@Oldes
> But I believe, that you are again in the field where you should not be. Mines are waiting for you!
I am also a creative, I like inventing and experimenting new solutions with the things I use. Often this leads to innoviations that could olnly be seen in the future. 23:43When Carl has started, had a strange idea of experimenting with words... Lets see where we are now!
- GalenIvanov
- 06:20@GiuseppeChillemi It works fine for me:
>> s: {^/^-^-^-insert into MY-OWN-TABLE^/^-^-^-(col1 , col2 , col3)^/^-^-^-values^/^-^-^-('1' , '2' , '3''4' , 'a' , '6');^/^-^-}
== {^/^-^-^-insert into MY-OWN-TABLE^/^-^-^-(col1 , col2 , col3)^/^-^-^-val...
>> print s
insert into MY-OWN-TABLE
(col1 , col2 , col3)
values
('1' , '2' , '3''4' , 'a' , '6');
>>
- GiuseppeChillemi
- 07:52It a side effect of having just moved from Rebol my codebase:
probe {
a
b
c
}
Red:
{^/a^/b^/c^/}
Rebol
{
a
b
c
}
I must rewire my brain to remember that I must use Print
instead of Probe
to see the sting printout as I have meant it to be.18:05I am hitting some limits: I have 2 blocks with 28.000 lines each, coming from 2 queries. I have asked the system to unique set1 set2
but I receive a stack overflow
. Is there any way to raise the stack? Do you have other sulutions?
- greggirwin
- 18:09Will this work for you @GiuseppeChillemi ?
unique: function [
"Returns a copy of the series with duplicate values removed."
series [series!]
; /case "Perform a case-sensitive search"
; /skip "Treat the series as fixed size records"
; size [integer!]
][
res: make series length? series
foreach val series [
if not find/only res val [append/only res val]
]
res
]
(old code, from before set ops and collect
existed)18:10If it doesn't crash, let us know how slow it is. :^)
- GiuseppeChillemi
- 18:11Yes, thank you. I just hoped a way to rise the stack existed but I can use this function too.18:13Why are you making RES of the same length of series?
- greggirwin
- 18:14The problem with raising the stack size is that you'll have to do it again, and again, ...or maybe not, but then we can also ask how big the stack limit should be on modern systems.
Pre-allocating for the worst case, so appends don't slow down as it grows incrementally.18:14Feel free to test without that, and post results.
- GiuseppeChillemi
- 18:15I have made a mistake...18:15I will write my own one
- greggirwin
- 18:16
series-difference: function [
"Returns the unique symmetric difference (XOR) between two sets."
series1 [series!]
series2 [series!]
; /case "Perform a case-sensitive search"
; /skip "Treat the series as fixed size records"
; size [integer!]
][
res: make series1 length? series1
series1: unique series1
series2: unique series2
foreach val series1 [
if not find/only series2 val [append/only res val]
]
foreach val series2 [
if not find/only series1 val [append/only res val]
]
unique res
]
- GiuseppeChillemi
- 19:46Thank you but it took very long times. 5 minutes for 28k rows
- hiiamboris
- 19:47convert to hash
- GiuseppeChillemi
- 20:09I will test it
- GiuseppeChillemi
- 23:03How do I run another instance of red from the previous directory and pass it arguments via
CALL
?
call {../red.exe "argument1" "argument2"}
This does not work
23:32Previous directory problem solved. It is just how to pass the arguments the problem
- hiiamboris
- 06:57How is it a problem?
- GiuseppeChillemi
- hiiamboris
- 08:00You probably messed it up then.08:00Badly, as usual ;)
- GiuseppeChillemi
- 08:24It's a simple call! No trickery!08:24[](https://files.gitter.im/5780ef02c2f0db084a2231b0/dbcC/image.png)08:26Well, solved. 08:26;-)
- gltewalt
- 03:36load it03:38
load "15-jun-2022"
- GiuseppeChillemi
- 07:17Thank you. I would prefer it implemented in a
to
function to avoid loading something dangerous.
- rebolek
- GiuseppeChillemi
- 08:57This is correct.
- cosacam1
- 03:07Hi there! How can I know all possible error ids?03:13I mean, I want to use cause-error. I need to know all possible err-type and err_id available. Thanks
- greggirwin
- 03:22
system/catalog/errors
- gltewalt
- 03:24
help system/catalog/errors
If you want to inspect a certain category, like math
:
help system/catalog/errors/math
- cosacam1
- 03:32Thank you very much!
- gltewalt
- 03:41Categories and their numbers:
>> ws: words-of system/catalog/errors
== [throw note syntax script math access reserved1 reserved2 user internal]
>> foreach word ws [print [word system/catalog/errors/:word/code]]
throw 0
note 100
syntax 200
script 300
math 400
access 500
reserved1 600
reserved2 700
user 800
internal 900
- cosacam1
- 14:03Thanks again. By the way, I've read about catch and throw in Red by example, Helpin Red and other book Learn Red... (I don't remember it's name now) but I couldn't grasp the concept. I remember I once used them in Delphi or Borland Pascal (I guess) long ago but always related to exceptions. However those books I mentioned say they are not for error handling. Could anyone clarify me or direct me to other readings? Thank you.
- Oldes
- 14:25
throw
is a special type of exception (similar to error). When it is reached, it stops current evaluation and rewinds to the state, where is catch
found, where it resumes the execution.14:25
>> test: does [print catch [ print 1 f: does [print 2 throw 4] f print "this is not reached"] print 5] test
1
2
4
5
14:31Compare with:
>> test: does [probe try [ print 1 f: does [print 2 1 / 0] f print "this is not reached"] print 5] test
1
2
make error! [
code: 400
type: 'math
id: 'zero-divide
arg1: none
arg2: none
arg3: none
near: [0]
where: 'try
stack: 74584876
]
5
- hiiamboris
- 15:501st hit in google: https://chenyitian.gitbooks.io/rebol-core-user-manual/content/docs/words/throw.html
- GiuseppeChillemi
- 16:47How should it be used for functions?
f: func [
"My Func"
[catch]
arg1 [integer!]
] [
if arg1 > 22 [make error! rejoin ["Number to big!: " arg1 " max is 22!"]
]
Is it ok?
- hiiamboris
- 16:50where did you get that, and what are you trying to do?
- GiuseppeChillemi
- 17:03I have read in somebody else code on Rebol2. I would like to return an error from the inside of a function to the caller one and have the message returned in console if the error is not managed. I dont remember if
[catch]
in specs was after or before the function description.17:09Here is a code with it
string-length?: func [[catch] string [any-string!] /local counter][
either parse/all string amend [
(counter: 0)
any [[ascii | utf-8] (counter: counter + 1)]
][counter][raise "String contains invalid characters."]
]
Taken here: https://github.com/rgchris/QuarterMaster/blob/master/qm.r
- greggirwin
- 17:25The best description for their use, IMO, is "non-local flow control".
- hiiamboris
- 17:51http://rebol.com/docs/core23/rebolcore-9.html#section-7 @GiuseppeChillemi
- GiuseppeChillemi
- 17:59Thanks, read.18:00I have seen that in Rebol2 there is
FUNCT
which let you use a permanent object. Do we have it in Red?
- rebolek
- 18:12No, but it's easy to add.
- greggirwin
- 18:12No, but it's a mezzanine in R2 so you can see the source.18:14Looking at the source, this line (
unless object? object [object: make object! object]
) reminds me of Ladislav's default
, which I used sometimes. Lines like the above are *awful* IMO.18:17I have a number of experimental versions for Red, which extended the idea to support defaulting multiple words in one call.
- GiuseppeChillemi
- 18:17Are they pubblic?
- greggirwin
- 18:19Option 1, works like
set
with a block of words and a block of values.
default: function [
"Sets the value(s) one or more words refer to, if the word is none or unset"
'word "Word, or block of words, to set."
value "Value, or block of values, to assign to words."
][
def: func [w "Word" v "Value"][
; We're setting one word, so don't need to use set/only.
if any [not value? :w none? get w][set w :v]
get w
]
; CASE is used, rather than COMPOSE, to avoid the block allocation.
case [
word? :word [def word :value]
block? :word [
collect [
repeat i length? word [
keep/only def word/:i either block? :value [value/:i][:value]
]
]
]
]
]
e.g. [
default a 1
default [a b c] [2 3 4]
default f :append
;default [g h i j "k" #l m] [1 2 [3] 4 5 6 7]
;default [g h i j "k" #l m n o] [. . . . . . . .]
default [g h i j k l m] [1 2 [3] 4 5 6 7]
default [g h i j k l m n o] [. . . . . . . .]
]
18:20Option 2, uses a key-value block approach.
; word(s)-value pairs interface.
default: function [
"Sets the value(s) one or more words refer to, if the word is none or unset"
input [block!] "word(s) value pairs"
][
def: func [w "Word" v "Value"][
; We're setting one word, so don't need to use set/only.
if any [not value? :w none? get w][set w :v]
get w
]
; CASE is used, rather than COMPOSE, to avoid the block allocation.
foreach [word value] input [
case [
word? :word [def word :value]
block? :word [
collect [
repeat i length? word [
keep/only def word/:i either block? :value [value/:i][:value]
]
]
]
]
]
]
e.g. [
default [a 1]
default [
a 2
b 3
c 4
[d e] -1
]
default compose [f (:append)]
default [g 1 h 2 i [3] j 4 k 5 l 6 m 7]
default [[g h i j k l m n o] '.]
print [a b c d e :f g h mold i j k l m n o]
]
18:21The basic version is just for single words.
default: func [
"Set a value for the word if the word is not set or is none."
'word
value
][
if any [not value? :word none? get word] [
set word :value
]
get word
]
- hiiamboris
- 18:25I'm using
default
a lot. But for the case above it's not useful as it would create the object even if it's not needed.
- greggirwin
- 18:26You mean the case in
funct
?
- hiiamboris
- 18:26Yeah18:26Or rather it will cause an error 18:27Oh it depends..18:27
>> object object [x: 1]
*** Script Error: object does not allow object! for its spec argument
*** Where: object
*** Near : 1
*** Stack: run eval-command do-command try-do object
>> make object! object [x: 1]
== make object! [
x: 1
]
- greggirwin
- 18:27Yes, it would need to be extended if that's an issue.
- hiiamboris
- 18:28All tradeoffs. I tried feeding a block to default, but then it's not any more readable than
any
.
- greggirwin
- 18:28That is, if you want control over making necessary values or not.18:29For me the main value by *far* is having the name there itself, because it's so meaningful.
- hiiamboris
- 18:29Also
default
won't check for object vs block, only falsey values. So not an option here anyway.
- greggirwin
- 18:46The case of
object
only allowing blocks is one of those subtle things that we don't often think about. Where it forces you to use make
or copy
, which are very clear in meaning. Object
is declarative, but a function.
- cosacam1
- hiiamboris
- 14:24no14:24but if you don't get the meaning of
=?
, why use it?
- cosacam1
- 14:39I do get the meaning of =? It is used to find out if two objects have the same id, if they both point to the same location in memory. So, a and b have the same value but they are different words. I guess they are binded to different data, in different memory locations. In that case =? should return false. I took the example from Red by example.
- hiiamboris
- 14:43there are basically 2 kinds of values in Red: series and immediates14:43series do not14:44and you can append stuff to them14:44so they fit no measure eventually, save for the amount of RAM Red can address14:44series are a cell that points to a memory location14:45by
same?
or =?
you ask if the cells are identical, which in case of series means also pointing to the same memory location, but in case of an immediate it's just the cell itself14:47pseudo example: cell1: [type: block! address: 153914916]
and cell2: [type: block! address: 7140601]
are not identical, but cell3: [type: integer! value: 123]
and cell4: [type: integer! value: 123]
are14:48when you write a =? b
both a
and b
get evaluated, and =?
receives their *values* (which are cells)14:48so it's not about words at all!14:48you wanna compare words, type 'a =? 'a
14:49makes any sense?
- cosacam1
- 15:13Yes. Thanks for your explanation. Never heard of inmediaates. Just words, series, blocks, etc. A lot of useful data-types Rebol and Red have.
- hiiamboris
- 15:20
>> ? immediate!
IMMEDIATE! is a typeset! value: [datatype! none! logic! char! integer! float! word! set-word! lit-word! get-word! refinement! issue! typeset! pair! percent! tuple! time! handle! date! money!]
- cosacam1
- 15:30My boss asks me to program in Python. And my probably-next boss too! I know it's popular and easy to learn. I studied 4 years ago but I could not use it for several reasons. I discovered Rebol and got fascinated: how could it do sooooo much with tooooo little, only 844 kb! Then moved to Red, the same! Well, I am comparing Python and Red to show myself which is better (so far I preffer Red) I took the samples from ellibrodepython.com and I'm studing and rewriting them in Red. Today I was studing Python's is which is equivalent to Red's =? Wish me luck!15:33I need to study more Red. Inmediate was there and never saw it. I need time. I told you once I'm a very busy guy... And I'm 60 already.
- hiiamboris
- 15:41Nice! ☻15:42@cosacam1 might find this useful https://github.com/red/red/wiki/A-short-introduction-to-Red-for-Python-programmers
- Oldes
- 15:43If I can give you an advise, use Python or whatever else to earn some money and have Rebol or Red as a hobby. Btw... you may easily use Rebol or Red with Python... I was using Rebol scripts to control Python powered AI code recently.
- GiuseppeChillemi
- 16:02I still don't know which language to learn other than Red. I need to develop for web and mobile and also do some AI. Candidates are Phyton, C#, Javascript and Flutter. C# because it works well on all environments. I don't know in which order to start or if I should change some of the candidates.
- hiiamboris
- 16:05good luck with those, esp C#
- cosacam1
- 16:05@hiiamboris Thanks for the link. I see somebody else did the job. It's a good book.
- Oldes
- 16:06Knowing Javascript (or its clones) cannot hurt anybody. When you need AI, than there is only Python I guess (if you don't want to write everything from scratch).
- hiiamboris
- 16:06@cosacam1 kudos to @Galenivanov and PM him if you have ideas how to improve the read
- cosacam1
- 16:11@Oldes Yes, that's what I do. I wrote a program in Rebol to search in the Bible, read it and make sketches for sermons. I recently enhanced the app with Red. I want to make a version for Android. Let's see.
- GiuseppeChillemi
- 16:11@hiiamboris Which other suggestions to you have from your experience?
- hiiamboris
- 16:13none, sorry ;)
I don't write web or AI stuff
- GiuseppeChillemi
- 16:14Nice news, so you are always committed into doing great stuff on Red!
- cosacam1
- 16:19Two things I like most of Rebol/Red is VID and parse. I wonder why regex is so obfuscated with those weird symbols when it should be written in english as in R/R parse. Have you ever seen a kivy book? Just to install it is a nightmare. And so many lines for a simple interface. There's nothing like VID.16:32I read in Helpin Red that there is Nenad's Cheyenne, a small server for running Red scripts in the backend, for web development. I've never worked for the web
- hiiamboris
- 16:48Well, regex is concise. It was a nice solution for simple single-line pattern matching in the shell. People just abused it too much.
- cosacam1
- 17:58By the way. Is there an important market for Red coders? You guys earn your living with Red or just use it for hobby?
- gltewalt
- 18:17@GiuseppeChillemi learn Javascript. There are libraries for Android development, and tensorflow has a js library for A.I.18:22https://github.com/getify/You-Dont-Know-JS
- riprwwa
- 01:21C#: good for backend, graphical UIs (WPF, MAUI), good for mobile apps (Xamarin, Uno); pretty big ecosystem; it's statically typed so in some aspect less surprises; reasonably fast; lots of people to ask for help
Javascript: pretty easy to learn (though it has its quirks), good for backend (Nodejs), frontend (vanilla or using any of lots of web frameworks), mobile (hybrid apps with Ionic or Meteor or others) and even desktop (Electron); big ecosystem; dynamic (with quirks); lots of people to ask for help. For web development you might also need the other two in the web trinity: HTML and CSS
- cosacam1
- 02:17And all this could be done with Red if it had enough libraries as far as it is a full stack programming language. Right? I've spent all my programmer's life developing desktop apps with only one tool name it Basic In many flavors or Turbo/Borland Pascal/Delphi or Game Maker without needing almost anything else. It's difficult for me to link all those software pieces in order to get a hugh application with a lot of dependencies and error prone if they are not so well linkeda. Yes I know there's no need to reinvent the wheel but... how many car brands exist right now in the world? And they innovate all the time! That's the beauty of programming, the best job ever!
- greggirwin
- 02:40:+1:
- riprwwa
- 04:13I agree with you @cosacam1 that's why I'm here :), was just responding to @GiuseppeChillemi who seemed to be pondering a choice in programming languages for web and mobile and maybe even AI (there's at least ML.NET for C# and TenshorFlow.js for Javascript)
- pekr
- 06:52What we can see in terms of our enterprise, is basically partners using two streams - you are either a React (Native) team, or an Angular + Flutter team :-) I have seen just one company around using Xamarin.
- GalenIvanov
- 07:36@cosacam1 Hi! I wrote [A-short-introduction-to-Red-for-Python-programmers](https://github.com/red/red/wiki/A-short-introduction-to-Red-for-Python-programmers) last summer. I'm sure there are many things that can be improved and I'll appreciate your feedback.
- ldci
- 17:33@GalenIvanov Your text is excellent and it woulbe important to add some supplementary samples :)
- GalenIvanov
- 18:06@ldci Thank you!
- ldci
- 18:15@GalenIvanov Have a look to what we did with Toomas for LZW compression/decompression compaired to python :)18:16Most of my students use python and are really impressed when I show a reduced code with Red/REBOL:)
- pekr
- 18:22My team uses JAVA long time. Our company got acquired by big real estate one. The original tem used Kotlin (JAVA), but left the company and new team uses Python and React infrastructure. Now my team should learn Python as well, but is not happy about that. It is not easy to switch tools you are used to for long years.
- GalenIvanov
- 18:28@ldci I saw a discussion of LZW compression for GIFs but I don't think I've seen the final result. Can you share a link?
Do you students want to learn Red/Rebol?
- ldci
- 18:46@GalenIvanov I think that Toomas will relesea the code on Githun after some controls. Have a look to red/red/system room:)
- GalenIvanov
- 18:49OK, thanks!
- ldci
- 18:57Sorry release on Github.I’m exhausted:)
- GiuseppeChillemi
- 09:08I have a problem creating my
one-of?
function. It will return true if the data passed is any if the possible options. Well, in shich order would you write the args and why?
one-of? data [possible options]
or
one-of? [possible options] data
- hiiamboris
- 09:10
data has-one-of? [possible options]
09:10because it reads
- rebolek
- 09:10The convention is
data
first. There are exceptions to this rule, but generally you should abide by it.
- GiuseppeChillemi
- 09:10So you would make it as an operator?
- rebolek
- 09:11If you feel adventurous, go with infix operator, but that's not my preference.
- GiuseppeChillemi
- 09:11Pardon, the question was for @hiiamboris 09:12@hiiamboris So you would make it as an operator?09:12@rebolek
> The convention is data
first. There are exceptions to this rule, but generally you should abide by it.
have you a list of the rules?
- rebolek
- 09:15I can't find it now, IIRC it was called Rebol style guide or something like that.
- hiiamboris
- rebolek
- 09:16There's this http://rebol.com/docs/core23/rebolcore-5.html#section-5 but it doesn't mention the order of the args.
- hiiamboris
- GiuseppeChillemi
- 09:17I will make it an infix when I will leave Rebol2 totally, which should happen soon
- hiiamboris
- 09:17otherwise just
find [options] data
, no need for a function
- rebolek
- 09:20Ok, let me correct myself. By
data
I meant the series you are searching in, so in your example [possible options]
.
- GiuseppeChillemi
- 09:20@rebolek
> I can't find it now, IIRC it was called Rebol style guide or something like that
Why don't you a list of rules, so the community has reference?
- rebolek
- 09:21> Why don't you a list of rules, so the community has reference?
Carl set those rules, not me :-)09:21It's just that the documentation is scattered an hard to search...
- GiuseppeChillemi
- 09:25@hiiamboris
> otherwise just find [options] data
, no need for a function
It manages the special datatype case:
one-of?: func [
"Returns true if a value is found in allowed values"
allowed-values [block!]
value "The value to find, datatypes are searched as words"
/only "TBD:"
/local
out-data
] [
either not block? :value [
if datatype? :value [value: to-word value]
out-data: not none? find allowed-values :value
] [
forall value [
out-data: not none? find allowed-values value/1
if out-data = false [break]
]
]
out-data
]
09:26I need it for checking for datatypes as function does.
- toomasv
- 09:28@GiuseppeChillemi Can you pleeease stop using
not none?
. It hurts eyes, sorry! :)
- Oldes
- 09:30And if you want to check datatypes like function does, than you should use datatypes and typesets instead of words and block.09:31
>> allowed-types: make typeset! [string! file!]
== make typeset! [string! file!]
>> find allowed-types string!
== true
>> find allowed-types integer!
== false
- GiuseppeChillemi
- 09:34@toomasv I just discovered that a series at position =
true
09:35Coming from Rebol, the found?
function still confuses me09:35Even on Rebol it is not needed
- Oldes
- 09:36And if you really need something like that, than use:
[
either block? :value [
forall value [
if find allowed-values value/1 [return true]
]
][
if datatype? :value [value: to word! value]
if find allowed-values :value [return true]
]
false
]
- GiuseppeChillemi
- 09:37@Oldes
> And if you want to check datatypes like function does, than you should use datatypes and typesets instead of words and block.
I have no typesets in Rebol2. Also the function is not only meant for datatypes but for any value. I will create a datatype only version to check for datatypes. 09:38And if you really need something like that, than use: yes, now I can definitely abandon the found?
mental cage.09:44But why was found?
created? Was there a time were not
or if
like functions were not handling truthy values or series were not truthy?
- rebolek
- GiuseppeChillemi
- 09:54I think so: true? <something> is often better than
true =
- hiiamboris
- 10:00not the same thing
- rebolek
- 10:01
true
- GiuseppeChillemi
- toomasv
- 10:06@GiuseppeChillemi How about this:
one-of?: func [
allowed [block!] "Parse rule"
value [any-type!]
][
if not block? :value [value: append copy [] :value]
parse value [some allowed]
]
>> one-of? ['a | integer!] 'a
== true
>> one-of? ['a | integer!] [a 1]
== true
>> one-of? ['a | integer!] [a 1.5]
== false
>> one-of? ['a | function!] does [nothing]
== true
>> one-of? [word! | quote 1] [a 1]
== true
- GiuseppeChillemi
- 10:13@toomasv
My rulify
function: seems perfect to manage your allowed
arg.
rulify: func [
"Converts a block of words to a rule [one two three] -> [one | two | three]"
elements [block!]
/local
out-data
element
] [
;TBD: Validate elements
;TBD: make a vaersion just for datatypes
out-data: copy []
forall elements [
element: first elements
;probe type? element-value
case [
any [word? :element string? element] [
append out-data to-lit-word element
]
;lit-word? element [
;
;]
datatype? element [
element: to-lit-word to-word element ;you need this for datatypes on Rebol
append out-data element
]
]
if (length? elements) > 1 [append out-data [|]]
]
out-data
]
10:16It is a work in progess, I need to learn how to handle lit-word
s in Parse.
- toomasv
- 10:17> I need to learn how to handle lit-words in Parse
>> parse ['a][lit-word!]
== true
>> parse ['a][quote 'a]
== true
- GiuseppeChillemi
- 10:18Ok, so I should only output
[quote 'a]
inside the rule10:22Done, thank you
rulify: func [
"Converts a block of words to a rule [one two three] -> [one | two | three]"
elements [block!]
/local
out-data
element
] [
;TBD: Validate elements
;TBD: make a vaersion just for datatypes
out-data: copy []
forall elements [
element: first elements
;probe type? element-value
case [
any [word? :element string? element] [
append out-data to-lit-word element
]
lit-word? element [
element: reduce ['quote element]
append out-data element
]
datatype? element [
element: to-lit-word to-word element ;you need this for datatypes on Rebol
append out-data element
]
]
if (length? elements) > 1 [append out-data [|]]
]
out-data
]
probe rulify [hello word 'people]
= ['hello | 'word | quote 'people]
- toomasv
- 11:12My version:
rulify: func [rule [block!]][
rule: copy/deep rule
forall rule [
case [
all [
not all [word? :rule/1 #"!" = last to-string rule/1]
any [any-word? :rule/1 integer? :rule/1]
][
insert rule 'quote
rule: next rule
]
block? :rule/1 [
rule/1: rulify rule/1
]
]
if not last? rule [
insert next rule '|
rule: next rule
]
]
rule
]
one-of?: function [
allowed [block!] "To be rulified"
value [any-type!]
/plain
][
if not block? :value [value: append copy [] :value]
if not plain [allowed: rulify allowed]
parse/case value [some allowed]
]
>> rulify [a :b c: 'd 1 1.5 #hi [deeper] "string" ]
== [quote a | quote :b | quote c: | quote 'd | quote 1 | 1.5 | #hi | [quote deeper] | "string"]
>> one-of? [a :b c: 'd 1 1.5 #hi [deeper] "string" ] [deeper 1 a]
== true
>> one-of? [a :b c: 'd 1 1.5 #hi [deeper] "string" ] [deeper 1 a :c]
== false
But there are some parse
's quirks
>> one-of? ['d] 'd
== true
>> one-of? ['d] quote 'd
== true
>> one-of?/plain [quote 'd] 'd
== true
- GiuseppeChillemi
- 11:36This solution is an effective check if value belongs to a group of values or to a datatype. There could be some of interesting variations for the
allowed
arg:
* Checking for ranges
* Checking using a bound block
* Checking using an all/any block
* Checking using more convoluted parse rules as validation arguments
* Checking passing a check function
I will play with them 11:38And give to this extended version the name valid?
11:49@rebolek I have understood why one-of? arg [word! string!]
seems better this way on the first instance: it is because we are used to this order of things in function
specs dialect. I have encountered this effect other times in my journey into the Redbol world.11:51The sequence of visual symbols triggers the knowledge of the function specs dialect in our neurons and we are driven by that.
- gurzgri
- 16:02@GiuseppeChillemi
> why was found?
created?
found?
returns a value of type logic!, I remember seeing it used in patterns like pick [green red] found? find options value
.
The irony in this is, that in R2 it was implemented as not none? :value
— makes me feel sorry for @toomasv ;)
- Oldes
- 16:13I think that some prehistoric Rebol version required
logic!
in conditionals, so there was need for the found?
16:16https://www.curecode.org/rebol3/ticket.rsp?id=2053
- gurzgri
- 16:31:+1: Nice discussion between BrianH and Ladislav back then.
- GiuseppeChillemi
- 16:33Nice to see we still have trace of past discussions and decisions.
- toomasv
- 16:59@gurzgri NP, I just have to put on stronger R2-glasses.
- greggirwin
- 18:51On arg order, I have the same recollection as @rebolek, and we should address these notes in a new style guide, to go with new docs. My mental note, based on what I think Carl may have said (so many caveats), is "Order args by importance." So the most important args go first. Another consideration is chaining. It's common to return a set of data, so making the target data the first arg aids chaining.
- toomasv
- 19:35First material on which you work, then tool with which you work, and then all the tilu-lilu. First the stone, then the chisel.
- rebolek
- 20:02@toomasv great explanation!
- toomasv
- 20:29:)
- GiuseppeChillemi
- 16:31With these rules I have only a problem. When you have a block/ctx of values that describe the next block, then they should come first.
Think about:
button "click me" 30x20 [
actor code here
]
you understand where [code here]
actor applies, because descriptive elements are before.
If you write a section generator like:
my-section: reduce [type text size [
code
code
code
]
] make context! [type: 'button text: "click me" size: 30x20]
in this case, having a xbind which accept inverted arguments, it is more readable:
my-section: reduce xbind make context! [type: 'button text: "click me" size: 30x20] [type text size [
....
....
]
]
- rebolek
- GiuseppeChillemi
- 20:07Yes, I have my own
with
too. Such kind of phrases needs a premise with the details to be read correctly, or you won't understand what is appending. Otherwise you need to go back and forth, which also causes confusion.
- fergus4
- 18:01Trying to load XML (using Chris' altXML). Red really bogs down on large files. Rebol has no issue on same files using rebol version of altXML. What is the issue and can I do something on my end?
- hiiamboris
- 18:22just how huge your file is?
- rebolek
- 18:23@fergus4 there's built-in XML codec, maybe you can try this.
One possible improvement is turning the XML codec into a scheme. Recently I made an experimental CSV scheme that can load much bigger files than CSV codec. XML scheme would be a bit more complicated but doable.
- hiiamboris
- 18:26it's not builtin ;)
- cosacam1
- 19:08@fergus4 Some time ago I told the forum that load was too slow compared to read in Red, not so in Rebol. A little later I asked something to the forum for some other reason, the solution was to download the most recent version of Red. Well, the load delay was solved too, so update.
- fergus4
- 20:13My red build is from July 19. I too thought XML was added with json? Guess not...20:13File is only 3 megs . I have a 27 meg file further down my list of xml files....20:14I only need the first page so I parsed out what I needed to load-xml on....it works for what I need...
- hiiamboris
- 20:34@fergus4 https://raw.githubusercontent.com/rebolek/red/c7205002839fefffdc3ba58e98091d780013df3d/environment/codecs/XML.red
- greggirwin
- 04:37Profiling I did on @rebolek's XML codec came out to ~1.5MB/s, and it handled a 24M file just fine.
- fergus4
- 15:47@hiiamboris Thanks. This works. And I like the block layout. Thanks @rebolek
- hiiamboris
- 15:54@fergus4 it supports as high as 3 formats: https://gitlab.com/rebolek/markup/-/blob/main/README.md15:54all with their own benefits and drawbacks
- ldci
- 14:41Gurus’ help. New test for decoding compressed gif data, but without success.
#!/usr/local/bin/red
Red [
]
;--Based on Rebol3-master src/core/u-gif.c
;-- 4 colors 10x10 test image
codes_str: #{02168C2D99872A1CDC33A00275EC95FAA8DE608C04914C0100}
;codes: [140 45 153 135 42 28 220 51 160 2 117 236 149 250 168 222 96 140 4 145 76 1]
MAX_STACK_SIZE: 4096 ;--2 ** 12 max
NULL_CODE: -1
;--for tests
color_table: []
append color_table to-binary white
append color_table to-binary red
append color_table to-binary blue
append color_table to-binary black
decodeLZW: func [
data [binary!]
h [integer!]
w [integer!]
][
data_size: to-integer copy/part skip data 0 1 ;-- 2 OK
nBytes: to-integer copy/part skip data 1 1 ;--22 bytes OK
clear_code: 1 << data_size
end_of_info: clear_code + 1
available: clear_code + 2
old_code: NULL_CODE
code_size: data_size + 1
code_mask: (1 << code_size) - 1
prefix: copy []
suffix: copy []
top_stack: copy []
pixel_stack: copy []
datum: bits: count: first: 0
repeat i MAX_STACK_SIZE [
append prefix 0
append suffix 0
]
code: 0
while [code < clear_code] [
;prefix/(code + 1): 0
suffix/(code + 1): code
code: code + 1
]
;print [clear_code end_of_info available old_code code_size code_mask]
data: skip data 2;--codes begin here
y: 0
while [y < h][
x: 0
while [x < w][
;--if we don't have enough bits
if bits < code_size [
;--if we run out of bytes in the packet
if count = 0 [
;--get size of next packet
count: to-integer copy/part data 1
;--if 0, end of image
if (count == 0) [break]
]
;--add bits from next byte and adjust counters
data: next data
datum: datum + (to-integer copy/part data 1) << bits
bits: bits + 8
count: count - 1
continue
]
;--isolate the code bits and adjust the temps
code: datum AND code_mask
datum: datum >> code_size
bits: bits - code_size
;--sanity check
if any [code > available code = end_of_info] [
;print [code ": sanity check"]
;break
]
;--time to reset the tables
if code = clear_code [
;print [code ": Clear"]
code_size: data_size + 1
code_mask: (1 << code_size) - 1
available: clear_code + 2
old_code: NULL_CODE
continue
]
;--if we are the first code, just stack it
if (old_code = NULL_CODE) [
append top_stack suffix/(code + 1)
old_code: code
first_code: code
continue
]
in_code: code
if (code = available)[
;print [code ": Available"]
append top_stack first_code
code: old_code
]
while [code > clear_code][
append top_stack suffix/(code + 1)
code: prefix/(code + 1)
]
first_code: suffix/(code + 1)
;--add a new string to the table
if (available >= MAX_STACK_SIZE) [break]
append top_stack first_code
prefix/(available): old_code
suffix/(available + 1): first_code
available: available + 1
if all [(available and code_mask = 0) (available < MAX_STACK_SIZE)][
code_size: code_size + 1
code_mask: code_mask + available
;print [code_size code_mask]
]
top_stack: back top_stack
old_code: in_code
x: x + 1
]
y: y + 1
];--end y
?? top_stack
;--;--we get the pixel color
colors: copy #{}
foreach c top_stack [
append colors color_table/(c + 1)
]
colors
]
rgb: decodeLZW codes_str 10 10
;-- what we should get in top_stack
[
1 1 1 1 1 2 2 2 2 2
1 1 1 1 1 2 2 2 2 2
1 1 1 1 1 2 2 2 2 2
1 1 1 0 0 0 0 2 2 2
1 1 1 0 0 0 0 2 2 2
2 2 2 0 0 0 0 1 1 1
2 2 2 0 0 0 0 1 1 1
2 2 2 2 2 1 1 1 1 1
2 2 2 2 2 1 1 1 1 1
2 2 2 2 2 1 1 1 1 1
]
comment [
im: make image! reduce [10x10 green]
im/rgb: rgb
save %test.png im
call/shell "open test.png"
]
- toomasv
- 10:55Hi, @ldci! Here's my solution. Not sure yet, if it is general enough, but works for this little example:
Red []
data: #{02168C2D99872A1CDC33A00275EC95FAA8DE608C04914C0100}
aim: [4 1 6 6 2 9 9 7 8 10 2 12 1 14 15 6 0 21 0 10 7 22 23 18 26 7 10 29 13 24 12 18 16 36 12 5]
indices: copy []
codes: copy []
to-code: func [c [string!]][
to integer! debase/base pad/left/with copy c 8 #"0" 2
]
decode: func [data [binary!] /local prev code byte][
N: data/1
CC: 2 ** N
EOI: CC + 1
available: CC + 2
sz: N + 1
z: 0
stream: copy ""
clear indices
clear codes
data: next data
while [all [0 < count: data/1 data: next data]][
parse data [collect into stream count [
copy byte skip
keep (enbase/base byte 2)
(stream: head stream) data:
]]
]
collect/into [
while [not empty? c: take/last/part stream sz][
keep code: to-code c
case [
code = CC [
sz: N + 1
code-table: make map! copy/deep [0 [0] 1 [1] 2 [2] 3 [3] 4 -1 5 -2]
continue
]
code = EOI [
new-line/skip indices true 10
probe indices
probe codes = aim
return codes
]
]
either selected: select code-table code [
append indices selected
unless prev [prev: code continue]
k: first selected
available: length? code-table
put code-table available new: append copy select code-table prev k
if 2 ** sz - 1 = available [sz: sz + 1]
][
k: first selected: select code-table prev
append indices new: append copy selected k
put code-table code new
]
prev: code
]
] codes
]
decode data
Output:
>> do %giftest.red
[
1 1 1 1 1 2 2 2 2 2
1 1 1 1 1 2 2 2 2 2
1 1 1 1 1 2 2 2 2 2
1 1 1 0 0 0 0 2 2 2
1 1 1 0 0 0 0 2 2 2
2 2 2 0 0 0 0 1 1 1
2 2 2 0 0 0 0 1 1 1
2 2 2 2 2 1 1 1 1 1
2 2 2 2 2 1 1 1 1 1
2 2 2 2 2 1 1 1 1 1
]
true
== [4 1 6 6 2 9 9 7 8 10 2 12 1 14 15 6 0 21 0 10 7 22 23 18 26 7 10 29 13 24 12 18 16 36 12 5]
`
- ldci
- 14:06@toomasv Thanks for your solution :)
- toomasv
- 14:16:+1:
- koba-yu
- 10:50Just Sharing for other VS Code Extension fun.
I have tried new Red binary. As long as I tested, to enable VS Code extension, I need to copy both console binary and GUI console binary to C:\ProgramData\Red\
and rename them, red-29jul22-95f4da55a.exe
to console-29jul22-95f4da55a.exe
and gui-console-29jul22-95f4da55a.exe
to gui-console-29jul22-95f4da55a.exe
. Then I set VS Code settings "Red Path" to C:/ProgramData/Red/gui-console-29jul22-95f4da55a.exe
and Intelligence works.
It seems the sourece code around [here](https://github.com/red/VScode-extension/blob/master/src/RedConfiguration.ts#L29) requires the binary's prefix name as above.
- hiiamboris
- 11:01Thanks for pointing that out. Feel free to submit a PR there, I guess ;)
- koba-yu
- 12:09@hiiamboris i have no experience to write codes of extension and TypeScript but i’ll give myself a try tomorrow, thank you😊
- hiiamboris
- 12:43You're capable, I'm sure you'll manage ;)
- toomasv
- 14:41@ldci Working [gif-parser](https://github.com/toomasv/LZW/blob/main/GIF.red) (static only). See example in the end.
- ldci
- 15:27@toomasv
*** Internal Error: stack overflow
*** Where: code
*** Near : none code-size: 0 color-table: copy [] local-color-table:
*** Stack: do-file
- toomasv
- 15:32@ldci What gif did you try to decode?15:41[](https://files.gitter.im/5780ef02c2f0db084a2231b0/Iopx/image.png)
- ldci
- 15:55@toomasv It’s OK just an error in file name. I’m tired :)16:00[](https://files.gitter.im/5780ef02c2f0db084a2231b0/kZHN/image.png)16:00Nice Toomas :)
- dockimbel
- 16:05@toomasv I'm very interested in integrating in Red runtime library a GIF-anim decoder if you have one.
- toomasv
- 16:07@dockimbel I don't have it yet, but I'm working on it.16:08@ldci Nice! :+1:16:09Tried DiaGrammar on it:
[](https://files.gitter.im/5780ef02c2f0db084a2231b0/X2Jz/gif-parse.png)
- ldci
- 16:25@toomasv Very elegant :)
- toomasv
- 16:28@ldci Thanks!16:28[](https://files.gitter.im/5780ef02c2f0db084a2231b0/iYXn/image.png)
- greggirwin
- 16:37Great work as always @toomasv.
- toomasv
- 16:43Thanks!
- ldci
- 17:12@toomasv dancing.gif doesn’t work for me.
*** Script Error: invalid argument: none
*** Where: set-path
*** Near : colors system/words/view [image img]
*** Stack: view
- toomasv
- 17:16Works like charm here on W10. Interesting, what are our differences? Platform?
- ldci
- 17:20@toomasv W11 with Parallels desktop on Mac ARM 64-bits:)17:21I’ll test on Mac 32-bit
- toomasv
- 17:23Are these same for you?
>> length? gif/codes
== 29904
>> length? gif/indices
== 57840
>> length? gif/colors
== 173520
- ldci
- 17:31@toomasv Same problem with Mac 32-bit
- greggirwin
- 19:32Endian issue perhaps?
- qtxie
- 23:55> Just Sharing for other VS Code Extension fun.
>
We need to update the VS Code Extentsion for it.
- toomasv
- 13:35First try on gif animation:
do %GIF.red
GIF/decode %sample_2_animation.gif
im1: make image! reduce [gif/images/1/size gif/images/1/colors]
im2: make image! reduce [gif/images/2/size gif/images/2/colors]
im3: make image! reduce [gif/images/3/size gif/images/3/colors]
view compose/deep [
panel [
at (gif/images/1/pos) image im1
at (gif/images/2/pos) image im2 hidden
at (gif/images/3/pos) image im3 hidden
]
rate (100 / gif/images/1/delay)
on-time [
case [
tick % 3 = 0 [face/pane/2/visible?: face/pane/3/visible?: false]
tick % 3 = 1 [face/pane/2/visible?: true]
tick % 3 = 2 [face/pane/3/visible?: true]
]
tick: tick + 1
]
do [tick: 0]
]
[](https://toomasv.red/images/Animations/traffic-light.gif)
- ldci
- 14:07@toomasv Great :)
- toomasv
- 14:45Thanks, @ldci!
- ldci
- 16:17@toomasv
Red [
]
do %GIF.red
GIF/decode %1.gif
im1: make image! reduce [gif/images/1/size gif/images/1/colors]
im2: make image! reduce [gif/images/2/size gif/images/2/colors]
im3: make image! reduce [gif/images/3/size gif/images/3/colors]
im4: make image! reduce [gif/images/4/size gif/images/4/colors]
view compose/deep [
title "Toomas's Animated Gif"
bb: base im1
rate (5 / gif/images/1/delay)
on-time [
case [
tick % 4 = 0 [bb/image: im1]
tick % 4 = 1 [bb/image: im2]
tick % 4 = 2 [bb/image: im3]
tick % 4 = 3 [bb/image: im4]
]
tick: tick + 1
]
do [tick: 0]
]
16:171.gif
- toomasv
- 16:19:)
- ldci
- 16:21[](https://files.gitter.im/5780ef02c2f0db084a2231b0/5s7q/image.png)16:23@toomasv. For large gif file (here 522x547 pixels by image) decoding is very long.
- toomasv
- 16:25Yeah, no optimisations so far.
- ldci
- toomasv
- 16:42[](https://toomasv.red/images/Animations/spiral1.gif)16:59This was decoded several minutes
[](https://toomasv.red/images/Animations/giphy.gif)
- pekr
- 17:10What is
gif/decode
? Doesn't it work like a codec?
- toomasv
- 18:01It is not built as codec. Or rather, I've never looked how a codec is built. Just a research of gif's belly. And exercise in LZW decompression.
- greggirwin
- 18:08@dockimbel if 0.7 is freezing after IO is merged, and we won't have View for some time on the new roadmap, where does GIF support come in, and for what use cases?
- qtxie
- 22:47> What is
gif/decode
? Doesn't it work like a codec?
Why you want it to be a codec? Is it include it in your program and use gif/decode
not enough?
- pekr
- 04:45We could state the same about bitmap, jpeg, png and oter formats too then ....
- cosacam1
- 09:10Hi. I want a field to accept only digits. I've tried with on-key event and parse to reject any non digit char but with no avail. Something like
f: field on-key [unless parse key [digit][key: none]]
having previously defined digit: charset "0123456789"
I've read Helpin Red and Learn Red Fundamentals but the examples there are not suitable to my needs. Red by example refers to a url which don't show. Thanks09:21@galen ivanov Can you read spanish? The document I'm writing comparing Python to Red is in spanish. I would like to send you what I have done so far so you give me your opinion and use whatever you need to improve yours, which by the way is very good.
- hiiamboris
- 10:19
>> digit: charset "0123456789^H"
>> system/view/capturing?: on
>> view [field focus on-detect [all [char? event/key not find digit event/key 'stop]]]
@cosacam1
- GalenIvanov
- 12:05@cosacam1 No, unfortunately I don't speak (or read) Spanish. Btw I would love to be able to read Jorge Luis Borges in original.
- gurzgri
- 14:30
Red
collect [parse [] [(keep [value]) (keep/only [block])]] ;== [value [block]]
parse [] [collect [keep pick ([value]) keep ([block])]] ;== [[value] [block]]
Trying to overcome the collect [ parse [ (keep ...)
habit and instead use the outperforming parse [ collect [ keep (...)
form more often. The above [difference when keep
ing blocks](https://github.com/red/docs/blob/master/en/parse.adoc#collect) keeps getting in my way though. Is there really no way to collect the values of a block instead of keeping the block as a value with parse
?
- hiiamboris
- 16:05Open an REP? It was decided that keep and keep pick act the same: https://github.com/red/red/issues/4198 and so far nobody challenged it with a real world use case
- Oldes
- 17:37@gurzgri I was [asking there](https://gitter.im/red/parse?at=62db0bb6ef5ee44882d4009f), why the
keep pick
does not work with expressions.
- cosacam1
- 09:44@hiiamboris your code for capturring only digits works, however it does not work when I use the numeric key pad, only with the numbers above the letters on my laptop keyboard. I guess it is because the numeric keypad keys have different scan codes. I haven't tested it with a regular desktop keyboard. Thanks anyway
- hiiamboris
- 09:49Use NumLock ;)09:49Else how are you planning to edit it.
- cosacam1
- 17:46Numlock is activated. Tested again, it works with number keys above letters but not with keys in numpad.
- greggirwin
- 18:02
probe-event: function [e] [
foreach field system/catalog/accessors/event! [
if not find [face window] field [print rejoin [field ": " mold e/:field]]
]
print '____
]
view [
base red focus
;on-key [probe-event event]
on-key-up [probe-event event]
]
18:06With num-lock off I get special keys [end, down, page-down], but with it on I get lowercase chars [a b c], where the alpha keys return the uppercase variants, and the numbers above the keyboard return the numeric chars.
- hiiamboris
- 18:19well, confirmed18:19funny bug
- greggirwin
- 18:23Worth reporting if not already there.
- hiiamboris
- 18:24on it
- greggirwin
- 18:32Thanks.
- hiiamboris
- 18:43https://github.com/red/red/issues/5170 thanks @cosacam1 for finding this
- cosacam1
- 01:28So it is a bug. Ok, I solved it with what hiiamboris and gregg gave mi. Here it is
`01:29accept-digits-only: func [event] [
all [
not all [
95 < event/picked
event/picked < 106
]
char? event/key
not find digit event/key
'stop
]
]
`01:31Oops again bad formatting. I'm typing/pasting directly on my phone.01:32Here is the explanation01:39This function is for fields where user may only type digits.
The number keys in numeric keypad throw an event whose /key has a value different from what the key says.
For example, when typing 0 in numpad, its /key value is #"" not #"0".
/picked has the key's scan code; for 0 to 9 keys /picked varies from 96 to 105.
If the key pressed is a numpad key, the
all [95 < ...] statement returns true but
not makes it false so we exit the external
all~ block because it's not needed to analize anything else and in order to not execute the 'stop below.
In char? event/key:
/key could be char! or word! (for example in keys like tab, enter, capslock)
We'll only accept char! so
find in the next expression won't throw an error
In
not find... we check that the pressed key is a digit, not a letter or symbol.
If the key is a digit (from above the letters)
find returns true but
not makes it false so we exit the external
all block.
But, if the key is a letter or a symbol (+ ; ~)
find returns none and
not` makes it true so we go forward to the 'stop.
The 'stop statement makes the event not to propagate so the unwanted character is not added to field/text.01:40Please correct me if I am wrong. Thanks01:48Sorry I should put different example instead of 0 whose /key value is the same char used here to format the texts. I should say When typing in numpad the 1 its /key value is #"a" not #"1"05:34Hi again. AFAIK there is no way to make a function with optional parameters in Red. Something like volume: func [width: 1 height: 1 depth: 1]
that could be called like unit-vol: volume
or print volume 3 2
I guess one reason is there's no commas between args. Am I wrong?
- toomasv
- 06:36
>> context [width: 1 height: 1 depth: 1 set 'volume func [/width w /height h /depth d][print [any [w self/width] any [h self/height] any [d self/depth]]]]
== make object! [
width: 1
height: 1
depth: 1
]
>> volume
1 1 1
>> volume/width 3
3 1 1
>> volume/width/height 3 2
3 2 1
>> volume/width/height/depth 3 2 5
3 2 5
- GalenIvanov
- 06:41Nice, @toomasv ! @codemosaic_twitter Here's my try:06:41
unit-vol: func [args [block!]][
dim: context [width: 1 height: 1 depth: 1]
make dim args
]
probe unit-vol []
probe unit-vol [width: 2]
probe unit-vol [height: 3 depth: 2 width: 4]
06:41
make object! [
width: 1
height: 1
depth: 1
]
make object! [
width: 2
height: 1
depth: 1
]
make object! [
width: 4
height: 3
depth: 2
]
>>
- toomasv
- 06:42@GalenIvanov :+1:
Or
>> volume: func [/width w /height h /depth d][width: any [w 1] height: any [h 1] depth: any [d 1] print [width height depth]]
== func [/width w /height h /depth d][width: any [w 1] height: any [h 1] depth: any [d 1] print [width height depth]]
>> volume
1 1 1
>> volume/width 5
5 1 1
>> volume/width/height 5 3
5 3 1
>> volume/width/height/depth 5 3 2
5 3 2
- GalenIvanov
- 06:58:+1:
- hiiamboris
- 07:08
volume: function ['w [any-type!] 'h [any-type!] 'd [any-type!]] [
foreach a [w h d] [unless number? get/any a [set a 1]]
w * h * d
]
07:10good thing for shooting one's feet off ;)
(and getting better understanding of Red)
- toomasv
- 08:23@hiiamboris Nice :)
Then you must not forget parens
>> a: volume 2 b: 3
== 6
>> b
*** Script Error: b has no value
>> a: (volume 2) b: 3
== 3
>> a
== 2
- cosacam1
- 08:52Wow! So many answers. Thanks. Meanwhile I made my version
volume: func [args [block!] /local w h d][unless attemp [w: args/1][w: 1] unless attemp [h: args/2][h: 1] unless attemp [d: args/3][d: 1] w * h * d]
09:00I first thought to use refinements but I searched for a shorter solution09:07@GalenIvanov may you explain how make dim args
works?
- hiiamboris
- 09:10block is the idiomatic way, so congrats ;)
- cosacam1
- 09:11@toomasv those any [w 1]... are really short!!!09:22@hiiamboris didn't know of get/any. I've just checked it out in help. Oh, it was there since Rebol too! I need to study more. I wish my days last 72 hours09:23You guys help me so much. Thanks a lot09:26By the way, any comment or sugestion to accept-digits-only above?
- hiiamboris
- 09:29If it works, it's good enough ;)
- cosacam1
- 09:39Ok10:01I'm trying get/any in GUI but it gives me error. What I'm doing
`>>'a10:06Again. I type 'a just to create the word but without assigning any value. Then I try to print get/any a but it throws error a has no value. I thought it would not give any error
- GalenIvanov
- 10:33@cosacam1
dim: context [width: 1 height: 1 depth: 1]
creates an object! dim
with three fields (context spec
is short for make object! spec
- you can try source context
in the console). So this dim
object contains the default values for the dimensions. With make dim args
I create a new object using dim
as a prototype and args
as a specification, that is - the fields of the new object are set using the specification when present, and when not - the default values as in dim
will remain.
You can see more here: [Object! datatype / Creation](https://github.com/red/docs/blob/master/en/datatypes/object.adoc#creation)
- riprwwa
- 10:35
get
takes a word as its first argument. Let's say I have not defined a word a
get 'a
*** Script Error: a has no value
get/any 'a
So get
will not find the word a
either way, because I have not defined it. It's just that with the /any
refinement there is no error, it returns UNSET
.
My question is why does the following not work - I believe I'm using a get-word!
instead of a lit-word!
and get is supposed to take any-word!
get/any :a
- hiiamboris
- riprwwa
- 10:50thank you, so it tries to see if
a
is defined and fails
get/any quote :a
would prevent it from doing that
- cosacam1
- 11:12@GalenIvanov yes I had studied about objects but I thought make should always be followed by a datatype like in make block! Now I see it may be followed by a prototype. Thanks
- GalenIvanov
- 11:15:+1:
- cosacam1
- 11:22@riprwwa @hiiamboris thanks. I notice Hiiamboris volume function has w h d quoted so at foreach a [w h d] it happens that a gets qoted automatically.
- hiiamboris
- 11:24@riprwwa yes, basically the argument gets evaluated and
get
receives the result11:25@cosacam1 true, without quotation such variable arity is forbidden
- cosacam1
- 12:18So when I said "there is no way to make a function with opcional parameters in Red... Am I wrong?" Yeap, I was wrong. It seems to me that everything is possible in Red.
- GiuseppeChillemi
- 15:45Is there a way to encrypt the Red source to obfuscate it at compilation?15:45I mean: my program source running in red.
- hiiamboris
- 15:54If your program is compiled, there's no source code in it.
- GiuseppeChillemi
- 15:58My code is interpreted, I can't compile it as some partes are dynamically built.
- hiiamboris
- 16:26Is it so valuable that someone will bother reverse engineering it? ;)16:28There's still no source code, but a Redbin payload. Which one of course could theoretically extract, by unpacking it and figuring out the exe format from compiler's source code.16:28Or that's how I understand it anyway.16:37Try https://www.google.com/search?q=exe+obfuscator16:37But it won't be bulletproof since your program can unpack itself.
- GiuseppeChillemi
- 16:58@hiiamboris Yes, it is starting to be valuable. It is a food tracking app which maintains an aggregated bill of material.16:58I would like to give some test code around16:58When ready
- hiiamboris
- 18:13I have a
content-type
facet which can take only 3 values (as word!): planar
, horizontal
and vertical
. What would be a more specific word than -type
?
- ne1uno
- 18:22-axis
- gurzgri
- 18:25
orientation [planar | horizontal | vertical]
?18:26Or content-flow
maybe.
- hiiamboris
- 18:40
content-flow
seems fit, thanks
- ne1uno
- 18:42-fit
- hiiamboris
- 18:43no, not for this case18:44doesn't fit, sticks out (this parameters controls scrollbars logic)
- bubnenkoff
- hiiamboris
- 10:53you have a talent for finding weak points of Redbol design ;)10:54for this concrete example, try
get/any
if it doesn't error out, then find
on a/b
block for c
item10:54I don't think there's a general solution though10:55besides, there are cases like:
>> a: [b: %file]
== [b: %file]
>> a/b/c
== %file/c
>> a: compose [b: (func [/c]['result])]
== [b: func [/c]['result]]
>> a/b/c
== result
- gltewalt:matrix.org
- 14:02Path not existing returns
none
14:04As a refinement not existing, returns an error14:06I think all cases, no path, no refinement, no file, should error
- greggirwin
- 17:17Pretty sure @GiuseppeChillemi (or maybe it was someone else) has gone deep down this rabbit hole. This could be a good one for the
rethink
group here, as there's no single or perfect way to attack this problem. No universal solution.
- hiiamboris
- 17:32https://github.com/red/REP/issues/121
- greggirwin
- 17:32Thanks!
- hiiamboris
- 17:44Brian has attacked this with design, trying to invent a general solution that would take a path and return a block of items to visit (that would also convert get-words and parens into a final item). And then any other part should magically work on top of that. Not sure he has finished it though, and don't recall where I saw that :/
- GiuseppeChillemi
- 21:44@gltewalt:matrix.org I have long debated with myself about the current Red design, still with no definitive answer. Having been on Rebol, I have seen that Carl has creted 2 different sets of functions:
paths
and ordinals (first
, second
..) generate an error when you use a non-existing path or you pick out of range in the series; while pick
and select
returns a none
. On Red, you need additional tail?
and length?
to understand if your ordinal picker is out of range. Instead, using paths you could use the method suggested by Doc in the ticket: error? try [my/path]
This method actually has a problem:
A path on object!
always returns an error, independently from the non-existing path segment
A path on block!
returns an error only if the first word does not exist, or an intermediate one. So, you **CAN'T USE** error? try [my/path]
to check for paths when it is just the last word which does not exists, because it returns none
and does not trigger any error.
In other words:
x: [a [b c d]]
probe error? try [x/dd/z]
= true
x: [a [b c d]]
probe error? try [x/a/z]
= false
Actually, when you have a block with multiple nested blocks, it seems there is no way to know if the last element is a non-existing one. (But you can make your own path check function). Anyone is free to anyone to intervene if a method exists.
21:52We have too many path management combinations to deal with to access data. Carl has made paths to generate an error, and it works consistently across any data. With this observation, I think exists?
takes point as a good solution to implement if we want to keep paths returning none
, otherwise, let it fire an error!
- hiiamboris
- 21:55> Carl has made paths to generate an error, and it works consistently across any data
>> b: []
== []
>> b/1
== none
- dockimbel
- 22:04> A path on block! returns an error only if the first word does not exist, or an intermediate one.
That sentence is a nonsense. If the "first word" is not set, it cannot be "a path on block!".22:06> Actually, when you have a block with multiple nested blocks, it seems there is no way to know if the last element is a non-existing one.
x: [a [b c d]]
find x/a 'z
== none
find x/a 'b
== [b c d]
- GiuseppeChillemi
- 22:06On Rebol, picking using a number has the same working of
pick': it returns
none` if you are in a wrong position. He has made a parallel between path with a number and pick using number.22:07@dockimbel I did my best with my english and technical knowledge.22:15Thank you for the solution, I was not seeing it. But they are really too many combinations to manage for catching problems on path access, and all require different code. So, if you have a function that works with multiple datatypes, the error checking code will be long.
- GiuseppeChillemi
- 11:35I want to write a Red block which goes to the next line on
write
but I was not able to make it:
a: "hello"
b: "world"
;reduce
write %myfile.txt reduce [[o: 33] a b lf cr]
=[[o: 33] "hello" "world" #"^/" #"^M"]
;rejoin
write %myfile.txt rejoin [[o: 33] a b lf cr]
=[o: 33 "hello" "world" #"^/" #"^M"]
;rejoin + to-string
write %myfile.txt rejoin [to-string [o: 33] a b lf cr]
=o33helloworld
My need is to save a Red block and then later edit with proper formatting on multiple lines and not all in one line
- hiiamboris
- 11:49
write
molds it's value (mold it yourself, then add a newline)11:51or write/lines reduce [reduce [stuff]]
11:51randomly applying every function you can recall doesn't usually work ;)
- GiuseppeChillemi
- 12:20I am trying every combination to understand what molds and how everything works. The output of the console also confuses me as if you mold and probe, it seems you mold twice.
- dockimbel
- GiuseppeChillemi
- 12:22Thanks12:38@dockimbel I want to signal something happened doing some tests after your suggestion:
>> body-of :write
== 62
>> type? :write
== action!
I am currently investigating on it. I get this result only after a running long script which ends with an error on write/string
(which is a Rebol refinement run there by mistake) , while it does not happen on a pristine console.12:38What could be?
- dockimbel
- 12:41> while it does not happen on a pristine console.
C:\Dev\Red>console
--== Red 0.6.4 ==--
Type HELP for starting information.
>> body-of :write
== 62
>> type? :write
== action!
- GiuseppeChillemi
- 12:52I was currently on a subdir with an older Red version, my mistake.
>> about
Red 0.6.4 for Windows built 9-Aug-2020/23:49:48+02:00 commit #ab1a8eb
12:54However, I have solved the problem, but I admit it was difficult because of the high number of combinations and unknown (to me) workings:
write %myfile.txt rejoin [mold reduce [[o: 33] a b] lf mold reduce [[o: 44] a b] lf]
[[o: 33] "hello" "world"]
[[o: 44] "hello" "world"]
- gurzgri
- 15:05As Boris already suggested:
write/lines %test.txt reduce [reduce [[o: 33] a b] reduce [[o: 44] a b]]
[[o: 33] "hello" "world"]
[[o: 44] "hello" "world"]
will start each block on a new line. This seems to be so much easier then the rejoin mold reduce value lf
.15:12
Red
write %test.txt mold/only new-line/all reduce [reduce [[o: 33] a b] reduce [[o: 44] a b]] on
- GiuseppeChillemi
- 16:55@gurzgri I havn't understood the mechanism used by
write/lines
to add a new line.. This is the reason why I have skipped his solution
- hiiamboris
- 16:58Try reading the docstring of
write
.
- GiuseppeChillemi
- 17:01Yes, I knew that
/lines
would add a newline at each string in a block. Didn't know it worked for blocks inside blocks too.17:04Always something new to learn.
- luce80
- 17:08Is there a way to know if my script was started by another script or directly ?
- ne1uno
- 17:13
if find system/options/script "myscript.red" [print "hi"]
17:14not bulletproof maybe and hardwires name
- luce80
- 17:50@ne1uno thanks. Using the same "trick"
if "my title" = select select load system/options/script 'Red 'title [print "hi"]
a bit convoluted and slow but less hardwired
- ne1uno
- 17:58for anyone else wondering why do you want this? I use it to run inline tests on a library script that won't run when included from another. something like python
if __name__ == '__main__':
- luce80
- 18:05Exactly the same case for me. I wish system/script will be "filled in" and also
load/header
and also a complete script-module system will be available sooner or later.
- greggirwin
- 18:07I've just made a note for this use case.
- cosacam1
- 20:03Hi. Load-csv/with load %somefile.csv gives me invalid UTF-8 encoding.... However, I rename file to somefile.txt then load-csv "works"
- hiiamboris
- 20:05you mean
read %somefile.csv
?
- cosacam1
- 20:11Both read and load give same error
- hiiamboris
- 20:11check permissions maybe20:12file system bug possible too
- cosacam1
- 20:21I guess the reason is there are extended ascii chars (beyond 127) . I just edited the file with notepad, changed AÑO by ANO then run again and if gives same error but with another hex code possibly because another wrong char. I need to translate them all. Thanks anyway.20:21And20:22... is there any library for read/load xlsx files?20:47Confirmed. Translated all to utf-8 with Notepad++ and works using read.
- hiiamboris
- 21:27> ... is there any library for read/load xlsx files?
IIRC there was some VB integration demo of old
- GiuseppeChillemi
- 22:11@cosacam1 Rebolek has created a codepage translator. You find it [here](https://gitlab.com/rebolek/castr/-/tree/master/). 22:15Download the repository , include
codepage.red
and use read-cp
in and as follow:
myfile: read/binary %filename.red
myfile: read-cp myfile 'codepage-here
myfile: load-csv myfile
- cosacam1
- 23:01Ok thanks both. I will use it asap. I am in the middle of a black out right now
- GiuseppeChillemi
- 13:19I need advice from you. I have this web page with product cost: https://agerborsamerci.it/listino/web.htm
Which is the best approach to get each column element and store it as a table?
13:24I am confused because I have understood the developers have created some tools to parse Web Pages/XML (whose structure and working I know partially) and I really don't know where to start and what instrument to use.
- gurzgri
- 15:19> the developers have created some tools
Which developers? The ones of [agerborsamerci.it](agerborsamerci.it)? Then your best bet would be go ask them for some XML with a schema you can rely on instead of scraping web pages.
A very quick and dirty solution tailored only to that very page might be (it's only a start ...):
context [
do %castr/codepage.red
digit: charset "1234567890"
break-lines: func [block] [new-line/all block on]
table-rule: ["<table" thru ">" copy table any [table-rule | not "</table>" skip] "</table>" keep (table)]
tables-of: func [page] [parse page [collect any [to "<table" table-rule]]]
rows-of: func [table] [parse table [collect any [thru "<tr" thru ">" keep to "</tr>"]]]
cells-of: func [row] [parse row [collect any [thru "<td" thru ">" keep to "</td>"]]]
tidy: function [cell] [
parse cell [
any [
change [" " | "^/"] " " | change "<" "<" | change ">" ">"
| remove ["<" opt "/" [["font" | "a"] ahead [" " | ">"]] thru ">"]
| skip
]
]
parse cell [any [change some " " " " | skip]]
trim cell
if equal? cell "0,00" [clear cell]
any [
all [
parse cell [opt "-" digit any [opt "." some digit] opt ["," 2 digit]]
not equal? $0 value: to money! load trim/with cell "."
value
]
unless empty? cell [cell]
]
]
set 'scrape-prices function [page] [
break-lines collect [foreach table tables-of page [
keep/only break-lines collect [foreach row rows-of table [
row: collect [foreach cell cells-of row [keep tidy cell]]
parse reverse row [any [remove none!]]
keep/only reverse row
]]
]]
]
]
probe scrape-prices read-cp read/binary https://agerborsamerci.it/listino/web.htm 'Windows-1252
...
["FRUMENTO TENERO di produzione nazionale 2022"]
[{n° 1 - speciali di forza - prot. 14% min, p.s. 79/80 kg/hl, c.e. 1%} $408.00 $413.00 $408.00 $413.00]
[{n° 2 - speciali - prot. 12% min, p.s. 78/79 kg/hl, c.e. 1%} $361.00 $366.00 $364.00 $369.00 $3.00 $3.00]
[{n° 3 - fino - prot. 11% min, p.s. 78 kg/hl min, c.e. 1%} $354.00 $359.00 $357.00 $362.00 $3.00 $3.00]
["n° 4 - buono mercantile - p.s. 76 kg/hl, c.e. 2%" $347.00 $352.00 $350.00 $355.00 $3.00 $3.00]
....
- GiuseppeChillemi
- 15:31@gurzgri Some tools have been created by @Rebolek as a function to pick a an XML table form a web page but I suppose here it does not apply. Also, I have imagined that there could exists a function to transform a web page in a block hierarchy with its component and then you can pick one or another section. But as I have totally no experience on this, I am here to ask
- gurzgri
- 15:47You can't just "pick an XML table from a web page" if there is none. That very page is just plain HTML. Of course there are HTML to XML converters. But these would hand you out ... XML. Which you then would have to make sense of. Converting to XML doesn't magically provide semantic structure where it's missing in the source. And that very page doesn't even use CSS classes but just inlines pretty much all styles. So you don't even have class names to make some educated guesses what some particluar piece of information is all about.
- GiuseppeChillemi
- 16:45Which tools do we have in Red to split an HTML page in its parts and store it to a block? Are there any, apart the parse approach?16:46@gurzgri I forgot to say "Thank you" for the script. Here it is!
- dsunanda
- 07:26@GiuseppeChillemi When I had to parse a HTML page in Red, I shelled out to Rebol and used LOAD/MARKUP. Not ideal but it got the job done.
- hiiamboris
- 07:30@rebolek must have some tools
- Oldes
- 08:38When I need to parse a html.. I use just
parse
. I never try to load it.
- loziniak
- 12:51Hi, I don't understand why I have to use
/deep
when I want to replace part of a block using alternative in *parse* pattern:
>> a: [abc def ghi]
== [abc def ghi]
>> replace a ['def | 'xyz] [xxx] ;shouldn't this just work?
== [abc def ghi]
>> replace/deep a ['def | 'xyz] [xxx]
== [abc xxx ghi]
>> a: [abc def ghi]
== [abc def ghi]
>> replace a ['def] [xxx] ;this works ok!
== [abc xxx ghi]
- gurzgri
- 13:27Looks like a bug to me or like a misleading help string to me at best. According to the help string
/deep
should only be needed to replace nested occurences of abc
or ghi
too as in
replace/deep [abc [abc [def] ghi] def ghi] ['def | 'ghi] [xxx]
but not for replacing only on top level as in
replace [abc [abc [def] ghi] def ghi] ['def | 'ghi] [xxx]
But from a first glance, the way replace
is implemented, only with /deep
it switches to parse
here to do the replacing. Without /deep
it loops until
of all occurences that find
finds have been replaced.
But find
doesn't find any:
>> find [abc [abc [def] ghi] def ghi] ['def] ;== [def ghi]
>> find [abc [abc [def] ghi] def ghi] ['def | 'ghi] ;== none
Probably open a ticket.
- hiiamboris
- 15:51Replace is a known abomination, stitched together by different people for different tasks without a central design.15:53I have an experimental redesign: [replace (read the header)](https://codeberg.org/hiiamboris/red-common/src/branch/master/new-replace.red), [mapparse](https://codeberg.org/hiiamboris/red-common/src/branch/master/mapparse.red), but unreviewed.
- luce80
- 17:07with numbers I have:
>> n: 1.2
== 1.2
>> n * 2
== 2.4
>> n
== 1.2
but with vector!s I have:
>> v1: make vector! [1 2 3]
== make vector! [1 2 3]
>> v1 * 2
== make vector! [2 4 6]
>> v1
== make vector! [2 4 6]
Is this intended behaviour?
- hiiamboris
- 17:12https://github.com/red/red/issues/2216
- luce80
- 17:18luckily ther is a workaround:
>> v1: make vector! [1 2 3]
== make vector! [1 2 3]
>> v2: v1 * 2
== make vector! [2 4 6]
>> v2
== make vector! [2 4 6]
>> v1
== make vector! [2 4 6]
>> v1: make vector! [1 2 3]
== make vector! [1 2 3]
>> v2: (copy v1) * 2
== make vector! [2 4 6]
>> v1
== make vector! [1 2 3]
>> v2
== make vector! [2 4 6]
but surely it is not what one would expect to do, but maybe could be seen as a feature ;) ?17:25Sorry, it is also already documented as a feature.
- hiiamboris
- 17:31well IMO it's a mess
- dockimbel
- 19:41@luce80 In Rebol/Red,
vector!
is an array! of scalar values, so it's a series by nature. In Red, we allowed the math operations on it, until we get a better alternative (like fixed-sized vectors and matrix types). As it's a series, it's costly to be used for temporary values, so we decided to use in-place modifying semantics for math ops. If we hadn't done that, people would be using them in math-intensive tasks and then complaining that their memory usage is exploding or that the GC is not doing its job (sic)...But if that is causing troubles, we can remove the math ops support, so you can enjoy writting them yourself at mezz level. ;-)
- hiiamboris
- 19:46Is it proven that in-place modification is significantly faster? If so, where the slowdown occurs?19:47OK so it's GC issue again
- dockimbel
- 19:50The GC has no issue with vectors.
- hiiamboris
- 19:50Then what's slow? :)19:52Constructively, I already wrote enough about the topic. I'll just add that no performance matter can justify such counter-intuitive math in a high level language. Make C-like operators at least.
*=
+=
etc. At least people will *see* what happens. But as I wrote already, it's a kludge and it doesn't scale (will there be e.g. sin=
?).
- dockimbel
- 19:56> Then what's slow? :)
You are reading me wrongly. I've never mentioned speed, but memory pressure.
- hiiamboris
- 19:57But memory pressure is only a thing for us because GC is lazy :) Otherwise, why would anyone care?
- dockimbel
- 19:59> such counter-intuitive math
Maths does not define how arithmetic works between series and scalars, we do. It's part of the language semantics, not math rules.
- hiiamboris
- 20:01Such rules require a special case *in every* function that works on general arguments.20:02Besides, math doesn't have *variables*, so what should it define? ;)
- dockimbel
- 20:02You are again over-generalizing your own use-cases...
- hiiamboris
- 20:03Math defines e.g. commutativity and transitivity. And probably a couple more rules that are totally broken by this.20:03@meijeru will support me ;)
- dockimbel
- 20:04Anyway, as I said above: "we allowed the math operations on it, until we get a better alternative (like fixed-sized vectors and matrix types)." So this means that it's a temporary feature. I think we should rename that datatype, as we hesitated between
array!
and vector!
in the beginning.20:05Commutativity and transitivity do not apply on operands of different type/nature.20:05apple + orange = ?
- hiiamboris
- 20:06Type promotion?20:06Anyway, if it's temporary I'll stop criticizing it :)
- dockimbel
- 20:07Implicit type promotion from scalar to series? That's an horror!
- hiiamboris
- 20:07Well, for modelling behavior, not for implementing it ;)20:09I think, eventually, once GC is improved, it will just reuse recently created vector buffers, and this case will just resolve itself.
- dockimbel
- 20:09A series is not a number! So there's no possible "promotion", as they differ in nature!
apple + orange = ?
Let's promote the "orange" to "apple" to solve that, right?
- hiiamboris
- 20:09Not a correct analogy ;)
- dockimbel
- 20:10I think we should remove those math ops and rename the type to
array!
, so that people will stop misusing it.
- hiiamboris
- 20:12Ahh. Lazy. Let it be "my opinion" :)
- dockimbel
- 20:13:+1:20:17In some "high level languages" (like in C# IIRC), the math operators can be overloaded, but you can provide 2 implementations, depending on the operands order, as commutativity is not a given when the operands are of different natures, it needs to be defined case by case.
- hiiamboris
- 20:18Well, let's not follow their suit...20:18@dockimbel noticed [this comment](https://github.com/red/red/commit/19ebddde32e20ade110f54e55b3c599062fd02d6#commitcomment-81213457) btw?
- dockimbel
- 20:18Surely, the C# designers, like me, do not know about maths. ;-)
- hiiamboris
- 20:20Since it's a megacorp, I doubt there's any real design thought there. Just typical bureaucratic madness.
- meijeru
- 21:02On the vector arithmetic question, since I have been appealed to by @hiiamboris, let me confirm that I do not like in-place modification as I have said in a few issues.
- dockimbel
- 21:08> The term vector is also used, in some contexts, for tuples, which are finite sequences of numbers of a fixed length. ([source](https://en.wikipedia.org/wiki/Vector_(mathematics_and_physics))
So our vector!
datatype is misnamed as it does not fit that definition. We'll need to rename it and remove those built-in scalar operations.
- melcepstrum
- hiiamboris
- 21:16What's the difference between a vector and a tuple?
- dockimbel
- 21:18Which "vector"? A math vector or our
vector!
type?
- hiiamboris
- 21:19Math vector.21:19Perhaps, that you can't add dimensions to it, but to tuple you can.
- dockimbel
- 21:21They seems equivalent. Both are fixed-size.21:24> Since it's a megacorp, I doubt there's any real design thought there. Just typical bureaucratic madness.
"[Anders Hejlsberg](https://en.wikipedia.org/wiki/Anders_Hejlsberg) is a Danish software engineer who co-designed several programming languages and development tools. He was the original author of Turbo Pascal and the chief architect of Delphi. He currently works for Microsoft as the lead architect of C# and core developer on TypeScript."
"Since 2000, he has been the lead architect of the team developing the C# language. In 2012 Hejlsberg announced a new Microsoft project, TypeScript, a superset of JavaScript."
He surely doesn't seem like someone who knows what he's doing, right?. ;-)
- melcepstrum
- 21:38if you're going to remove those built-in scalar operations then also remove vector by vector multiplication etc.
- hiiamboris
- 21:44> He surely doesn't seem like someone who knows what he's doing, right?. ;-)
Judging by the designs, no ;)21:45Everyone can write a fancy biography. But a deeply designed language - only a few.
- cosacam1
- 08:07Hi everybody. Take a look at this code
date4calendar: none
lyoCalendar: layout [
cld: calendar with [date: date4calendar] return
button "Aceptar" [date4calendar: cld/date] button "Cerrar" [date4calendar: none]
]
view [button "get date" [view lyoCalendar print date4calendar]]
08:11When I run it and select a date and press Aceptar (Ok) it gives me this Script Error: cannot access date in path cld/date. My question: how to make calendar show a given date and how to get the date from it, the one the user selected?
- pekr
- 08:13Ah, those scandinavians :-) Our company was bought by the scandinavian group. First, there was a huge initiative to use Java Kotlin, stuff like Kafka microservices, but noone apart from the core team could undestand those things. So they've left. Nowadays, Python is promoted by the different branch of the IT group. I hope, in few years, it might be finally Red, or some kind of Red to Python ecosystem / browser integration :-) Btw - Delphi is still alive and popular amongst some devs, it has its open source Lazarus alternative ...
- cosacam1
- 08:23Has anyone used calendar?
- luce80
- cosacam1
- 08:57Of course: data, not date. Thanks luce80
- luce80
- rebolek
- 09:21I guess it's not used and it's just reserved for usage in schemes where it may make sense, same as
time!
- hiiamboris
- 09:42https://github.com/red/red/issues/3665
- gltewalt:matrix.org
- 18:35Isn't this the wrong room for design debate?
- greggirwin
- 21:18Design debate should move to red/red.
- GiuseppeChillemi
- 14:57This works in Rebol but not in Red, I get a
no catch for throw error!
f: func [
[catch]
"Try me"
arg "Any Arg"
] [
throw make error! "Oh noooo"
]
f 999
I am doing something wrong?
- greggirwin
- 16:08Red doesn't support function attributes yet.
- bubnenkoff
- 17:05
>> #("text": 123)
*** Syntax Error: (line 1) invalid word at : 123)
it's impossible to use string as key in map?
- rebolek
- greggirwin
- 17:06Too slow. Grrrr. ;^)
- rebolek
- 17:06:mouse:
- bubnenkoff
- 17:06oh! thanks!17:09But for example how to access for key if am putting string in next way:
>> a: #({"foo" "bar"} 123)
== #(
{"foo" "bar"} 123
)
>> a/{"foo" "bar"}
*** Syntax Error: (line 1) invalid path at a/{"foo" "bar"}
- ne1uno
- 17:13
a/("foo"): "bar"
- bubnenkoff
- 17:15So my question is about how to create map with key with
string!
type, or it's inpossible?
- ne1uno
- 17:16@bubnenkoff, enclose key in paren or use get instead of path17:17
a/({"foo" "bar"})
- bubnenkoff
- 17:17thanks!
- bubnenkoff
- 15:33
data: [{"aa" "bb"} {"cc" "dd"} {"ee" "ff"}]
how to write this to files with line breaks?
[
{"aa" "bb"}
{"cc" "dd"}
{"ee" "ff"}
]
I tried:
formatted-values: []
foreach el data [
append formatted-values el
append formatted-values lf
]
write %out.red form reduce formatted-values
But it remove string liters and block brackets
- hiiamboris
- bubnenkoff
- 16:06Do not understand idea how it should work together... 16:11
save %out.red new-line/all data on
output:
{"aa" "bb"}
{"cc" "dd"}
{"ee" "ff"}
I am close to result!
- hiiamboris
- 16:11:+1:16:12now study
save
refinements closer16:13oh sorry, it doesn't have that :D
- bubnenkoff
- 16:36The main idea is to write
map!
in human readable format. As it's displaying in code. Now I know to to write is block
values, but now I need to add it's key
:
data: #(
"foo" [
{"lots" "lot" "maxPrice"}
{"lots" "lot" "objects" "maxPrice"}
{"lots" "lot" "objects" "item" "maxLotPrice"}
]
)
write %out.red mold (new-line/all data/("foo") on)
16:38
write %out.red insert mold (new-line/all data/("foo") on) "foo"
do not work -- i tried to append key
name before
- hiiamboris
- 16:57new-line is destructive (modifies in place)
- ldci
- 09:47Rebol has a very complete image! datatype since images are considered as series.
To copy an image (img2) into another image (img1) at a given location (xy):
xy: 10x10
change at img1 xy img2
Is there an easy way to do the same with Red?
- hiiamboris
- 10:10
draw img1 compose [image img2 (xy)]
10:11and you've found a regression, congrats
- ldci
- 10:22@hiiamboris Thanks a lot :)
- dockimbel
- ldci
- 17:41@dockimbel That would be great. Have a look here: http://www.rebol.com/docs/image.html#section-1
- hiiamboris
- 18:22I have a doubt that OS image functions can support all that.
- GiuseppeChillemi
- 18:44It had also nice special effects for images.18:44But I don't know if we can have them in Red
- greggirwin
- 18:53In the past we talked about the value of an effects pipeline, and it's a great feature IMO. Especially with what @ldci does and exposing the convolving kernel.
- ldci
- 09:01Hi, while waiting for change function on images, a small function that makes job:
change-at: function [
img1 [image!] ;--first image
img2 [image!] ;--second image
pos [pair!] ;--starting position
][
if any [pos/x = 0 pos/y = 0] [pos: 1x1] ;--Red is 1-based
start: pos/y - 1 * img1/size/x + pos/x
line: 1
while [line <= img2/size/y][
col: 1
while [col <= img2/size/x][
img1/:start: img2/:col
col: col + 1
start: start + 1
]
start: start + img2/size/x
line: line + 1
]
]
comment [
a: make image! reduce [100x100 red]
b: make image! reduce [50x50 green]
change-at a b 25x25
view [image a]
]
- hiiamboris
- 09:25why bother if you have
image
command in Draw
- ldci
- 09:32@hiiamboris , mainly because draw can’t be used in routines:)
- hiiamboris
- 10:31I see ;)
- bubnenkoff
- 12:51I forgot why next code is add only one field to UI:
add-field: function [] [
append p/parent/pane layout/only [field]
]
view [
p: panel [
]
button "add" [add-field ]
]
I thought it should add as many fields as was clicked on add button
- dockimbel
- 13:12@bubnenkoff They are all placed at the same offset, so they are pilling up one on another. Here is a working example:
pos: 5x5
add-field: function [/extern pos] [
append p/parent/pane make-face/offset 'field pos: pos + 0x30
]
view [
p: panel []
button "add" [add-field ]
]
13:16Use make-face
when you need to create individual faces from existing styles, layout
is invoking the full VID processor which is overkill in such case.
- bubnenkoff
- 13:17thanks! Heh I did not know that
make-face
is exists
- dockimbel
- 13:21It was missing from [View docs](https://github.com/red/docs/blob/master/en/view.adoc#extra-functions), so I just added it.
- bubnenkoff
- 13:39egh... and what if I want to add two fields at one click? for example I want to display it
[] [] <- first click
[] [] <- second click
I tried to place field in block but git an error: make-face/offset does not allow block! for its style argument
- hiiamboris
- 15:51you'll figure it out, just don't let your hands do anything before your head ;)
- GiuseppeChillemi
- 16:20If I have some panels with elements inside, like button/areas, how could I add/remove elements from the panel?
- hiiamboris
- GiuseppeChillemi
- 17:37Is there a way to let
find
look at block! of block! content in one run to avoid a second run?
I mean:
my-data: [[a b] [a bbb] [b ccc] [a z]]
find/????? my-data 'a
So that it finds sub-blocks 1 2 and 4
- henrikmk
- 17:49A FIND/DEEP would be nice, but perhaps is complicated to do.
- GiuseppeChillemi
- 17:56Yes, it would be good to
find/deep
or nest another lower lever find
. Maybe one day we could provide even an R/S routine to be used by find to make a custom search at each element/row of the series.
- dockimbel
- 18:02Sure, why use Parse dialect when we can add yet another refinement to the most overloaded native...
- henrikmk
- 18:08We will not rest until FIND can brew coffee too.
- bubnenkoff
- 18:31I am trying to solve next problem.
I have data structure that I want to display and make it possible to be editable.
data: [
foo: none
bar: none
lots: [
lot: [
number: none
]
customers: [
customer: [
name: none
]
]
]
]
So I want to make UI from data and allow to save\load it from file. The number and names of blocks should be possible to change in dynamic.
So for exmaple I should be able to add node objects
inside node lot
.
I am thinking about proper ways to do it. And what types of controllers should I use.
Now I am thinking that I could try to build UI base on field
. I don't have a good idea how to organize the mapping logic with the hierarchy.
If I would generate UI kike Nenad show how can I add any node to any level?
- greggirwin
- 18:38You can use
face/extra
to hold a reference to the field in the data structure.
- bubnenkoff
- 18:46Could you give an example. I can't find nothing in search by:
face/extra
- greggirwin
- 18:50It's just a facet faces have. You can store anything there. So as you generate faces while walking your structure, you can use the current node's key and thus be able to update the data there.
- GiuseppeChillemi
- 19:09@dockimbel you are the master, I just make a wish. But before writing anything more, I will try to optimize my find-in function, even in parse, to see if at least 5x slower speed of 1 level block speed searching could be reached. See you!
- Respectech
- 00:46It sounds like someone needs to write a 'find dialect.
- GiuseppeChillemi
- 00:52I have made some speed test, the topic continues here on red/red
:point_up: [23 agosto 2022 02:14](https://gitter.im/red/red?at=63041bd772ad51741f7d910f)
- zentrog:matrix.org
- 02:26I think the first step should be to define the interface and semantics of the feature, and not worry about performance until the very end
- greggirwin
- 03:28Agreed @dander.
- GiuseppeChillemi
- 06:51@zentrog:matrix.org I have made the speed tests to see if there could be advantages into going native with the /deep refinement.
Here is the answer:
Nested-find: 0:00:00.116017
Nested+chk: 0:00:00.224215
;with -if all [block? column find column value]...-- check
Find/Skip: 0:00:00.0029983 99999
If I have calculated it correctly, a native find/skip
over a test made with 2 nested find and a datatype checks is about 30x faster. In these tests, the first find
searches for a record located at the penultimate position over 100K; then it searches inside a block with just *one* element, so I can say that a simple datatype check and a second native find on a small block, would not not add so much on that 0:00:00.0029983
. That 20/30x speed gain, gives motivation for a find/deep
- cosacam1
- 13:24Hi. I made a data structrure similar to Dmitri's example, a block of blocks,i.e13:30a tree. I want to save it to a json file using Santilli's to-json. It gaves me no error msg but it does not creates any file
- rebolek
- 13:31what does
save/as %output.json your-data 'json
do?
- cosacam1
- 13:37I use probe before saving to check my data and it is ok. Any idea why is it not saved?
- rebolek
- 13:46It's hard to tell without seeing the code you are using.
- hiiamboris
- 14:01maybe you're just looking for the saved file in the wrong place?
- cosacam1
- 15:02@hiiamboris Actually I'm using an absolute path %/E/folder/subfolder/test.json15:11@rebolek Code is not relevant. Data is ok, just a tree in a nested block fashion like Dmitri example above (sorry I cant give you my own but I cant use my laptop right now, I'm using my phone) For same reason I havent tested your suggestion save/as ... json
- rebolek
- 15:27@cosacam1 OK, so try my suggestion when you're at your computer and let me know.
- cosacam1
- 16:16@rebolek Yes, it works! And load/as ... 'json too. Why do I often take the longest path? Nevermind. Thank you.
- rebolek
- 16:20:)
- greggirwin
- 18:21> Code is not relevant.
As a note to everyone, as many lurk here, actual code is almost always relevant, since it shows the problem. Without it, others can only guess and make simple suggestions.
- zentrog:matrix.org
- 22:01@GiuseppeChillemi: I would argue that speed gain is not relevant until you actually need it. The important thing about defining new functions/features is how useful they are and whether they make your code cleaner and more maintainable. If modifying the language, then you must be certain to make it unnecessarily more complex. If you later discover that this particular operation is very expensive _in an important way_ in your code, then going down to red/system would almost certainly help. At that point, the design is fixed though, and improving performance is an implementation detail. It doesn't have to be piggy-backing on an existing function to do that.
- GiuseppeChillemi
- 22:27As Nenad has said, we can add it to
Find
, even if it is the most overloaded native, and he would accept any proposal I will make!22:28I am joking, let's see where this road ends.22:43Thinking out aloud: what seems clear is that very strict nested loops gain a lot from having native R/S code. So, even if find/deep
or find/into
would not be implemented, we should create and use specialized R/S functions in such scenarios.
- greggirwin
- 22:49R/S wins big when it can access the underlying data in raw form, e.g. bytes or chars. Once you start dealing with things at the Red runtime level, e.g. rich types, the gains are much less.
- cosacam1
- 03:03Sorry Gregg, I was referring only to that specific case. Besides, I couldn't send my code because I was in a blackout... you don't wanna know how often they are! ... And I could not send this... because of another one 6 hours long!!!
- pekr
- 03:09@GiuseppeChillemi I do remember some very old discussion about
find
working upon a nested structure, apart from /deep
, the alternative name was /flat
IIRC. But it never materialised ....
- cosacam1
- 03:59On July 1 Gregg answered to me:
The tiger demo is 100% real, and still runs on my Android phone, and you may be able to build things, but that branch is terribly out of date, so no guarantees.
Now I try to compile it with no avail. I wrote this little program too
`
Red [
Title: "Trying to make an apk"
Author: "cosacam"
File: %test-apk.red
; Config: [type: 'dll libRed?: no libRedRT?: yes export-ABI: 'cdecl]
Tabs: 4
Needs: 'View
]
#include %/E/cosacam_data/bz/distrib_bz/programacion/red/red-master/bridges/java/JNI.reds
view [
text "Name" n: field 100
button "Backwards" [r/text: reverse n/text]
r: text "---"
]04:07I couldn't compile it either by red.exe -t Android E:\cosacam_data\bz\distrib_bz\programacion\red\red-master\bridges\java\bridge.red. So, no Android compiling yet?
- bubnenkoff
- 11:58@cosacam1 could you share your code please. I am still frustrating about idea how to write such tree
- cosacam1
- 13:43Asap. Blackout
- greggirwin
- 16:55Given that Android is now set to come after 1.0, don't expect any fixes to it before that.
- GiuseppeChillemi
- 20:13@greggirwin It would be good to create a group of volunteers to put the Android version on par with the current release. The work is in an advanced state and we could have one more instrument to the community. But... we have no human resources capable of this work! Or at least, I see just a couple of people and nothing more.
- greggirwin
- 20:20Someone from the community was going to, but we never built momentum. @dockimbel has a high bar for contributions and this work requires deep skills, which I doubt will be met by self-organized volunteers. Combined with the current codebase being frozen in the near future, given the new roadmap, changes may make any effort there wasted.
- GaryMiller
- 20:36Is there a link to the new roadmap?
- GiuseppeChillemi
- 20:37@GaryMiller The second message in the Red main site.20:44@greggirwin You can have an unofficial, not-so-perfect solution and then the coders could move their codebases to the new Red Team which follows Doc standards. The advantage of this path is the creation of a codebase and applications that will be the ground for the official android one.
- greggirwin
- 20:46I don't think it's feasible, or a good use of people's time right now, but people can work on anything they want. @dockimbel would have to say if he supports any specific initiative.
- qtxie
- 22:50@GiuseppeChillemi Don't expect there are any volunteers to do it at the current scale of Red community. Even no volunteers to fix some simple issues which way easier than Android support.
As Gregg said, people can work on anything they want. It's opensource, feel free to modify it to fit your needs. ;)
- GiuseppeChillemi
- 23:25Thank you for the answer, I already knew it but I have asked, just in
a case... Expressing your dreams is free, realizing them is much more difficult! ;)
- qtxie
- 23:32> Combined with the current codebase being frozen in the near future, given the new roadmap, changes may make any effort there wasted.
According to the blog article [The Road To 1.0](https://www.red-lang.org/2022/07/the-road-to-10.html), IIUC, the current codebase won't be frozen. Only the Rebol 2 code (compiler, linker and encapper) will be discarded. It will be replaced by a Red one. The R/S runtime codebase will continue to be updated. So changes in the runtime won't be wasted.
- greggirwin
- 00:16"Frozen" is perhaps too strong a term, yes. But any work done in 32-bit now, e.g. in the Android back end, will have to be updated for 64-bit when the time comes. And once the deep core team is focused on the new work, there will likely be very few updates. @dockimbel can clarify, but building momentum on the new work is paramount, and avoiding distractions is key.00:18That's how I read his final line in the blog post anyway.
- qtxie
- 01:48> But any work done in 32-bit now, e.g. in the Android back end, will have to be updated for 64-bit when the time comes.
For Red code, no wrong. For R/S code, if you don't use pointer as 32-bit integer, then it should just works fine on 64-bit.
- greggirwin
- 03:03But Android work will be R/S, correct, so may be affected.
- bubnenkoff
- 07:55it's very interesting why on short strings is adding double quotes but longer strings is wrapping by
{}
>> x: []
== []
>>
>> append x "aaaaaaaaaaaaaa aaaaaaaaa aaaaaaaaa"
== ["aaaaaaaaaaaaaa aaaaaaaaa aaaaaaaaa"]
>>
>> append x "aaaaaaaaaaaaaa aaaaaaaaa aaaaaaaaa aaaaaaa aaaaaaaaaaaaaaaa"
== ["aaaaaaaaaaaaaa aaaaaaaaa aaaaaaaaa" {aaaaaaaaaaaaaa aaaaaaaaa aaaaaaaaa aaaaaaa aaaaaaaaaaaaaaaa}]
; ^--- see ^--- and here
- rebolek
- 07:56they're equivalent, there's just a limit in
mold
when to switch from "
to {}
, otherwise there's no difference
- bubnenkoff
- 08:31But what is the logic? Why such design?
- rebolek
- 08:33Have you read the documentation? For example http://www.rebol.com/docs/core23/rebolcore-3.html#section-2.6
- hiiamboris
- 08:43I guess logic is to choose between
""
and {}
without scanning the string for new-line markers (for speed). Limit just works in the majority of cases (single line strings are usually short, multi-line ones are usually long).
- dockimbel
- 09:06> Only the Rebol 2 code (compiler, linker and encapper) will be discarded. It will be replaced by a Red one.
As we'll be rebuilding the new toolchain in Red, we'll need to make fixes and improvements to the current runtime, to sustain that work. That's also the reason why we need to pass some long-time planned changes/improvements to the Red runtime library before we start the work on the new toolchain.
- greggirwin
- 17:00Thanks for clarifying @dockimbel.
- bubnenkoff
- 18:53Hey! After some frustration I found example of using
extrra
(I used it in the past but forgot how to work with it) and wrote next prototype:
data: [
foo: none
bar: none
lots: [
lot: [
number: none
]
customers: [
customer: [
name: none
]
]
]
]
foo: function [] [
level: 0
ui: copy []
walk: func [ data ] [
foreach [key value] data [
either block? value [
level: level + 1
append ui compose [pad (1x0 * level * 15) button (to-string key) extra (to-string key) return ] ; first (to-string key) for name, second for saving it's position
walk value
] [
append ui compose [pad (1x0 * level * 15) button (to-string key) extra (to-string key) return ] ; first (to-string key) for name, second for saving it's position
]
]
level: level - 1
]
walk data
return ui
]
view foo
It's works!
- hiiamboris
- bubnenkoff
- 19:14How I can increase only first element in
pairs
like 0x0
. + 10
add 10 both, but I need to add only to one. I can't use + 10x0
because 10
is value from word.
- hiiamboris
- 19:21multiply
10
by something before adding
- greggirwin
- 20:43Sometimes I just can't resist playing. Inspired by @bubnenkoff's example, here's a hack on it.20:44
data: [
foo: none
bar: none
lots: [
lot: [
number: none
]
customers: [
customer: [
name: none
]
]
]
]
foo: function [] [
level: 0
ui: copy []
key-path: make path! [] ; this looks empty, but it's like an invisible empty block
add-ctl: func [key][
; first key use is for name, second for saving its key
append ui compose/deep/only [
pad (1x0 * level * 15)
button (form key) extra [key (key) path (copy key-path)] [
print ["Current value:" mold get face/extra/path]
either block? get face/extra/path [
print "Don't set containers!"
][
set face/extra/path random "abcdefg"
]
]
return
]
]
walk: func [
data [block!]
/with root-key ; quick hack to avoid lit-arg design for now
][
if with [append key-path root-key]
foreach [key value] data [
append key-path to word! key ; can't have set-words in a path
add-ctl key
either block? value [
level: level + 1
walk value ; recurse into nested block
][
; We aren't recursing, so drop the last key in the path
take/last key-path
]
]
take/last key-path
level: level - 1
]
walk/with data 'data
probe ui
]
view foo
print ["Data is now:" mold data]
- cosacam1
- 23:34@bubnenkoff
`
- greggirwin
- 23:38Another blackout? ;^)
- cosacam1
- 23:42@bubnenkoff You asked me for my code for 23:58@bubnenkoff You asked my code for creating a tree. I've been working today on it however it's not for visually creating the tree but for getting some data from user then saving it as a tree (nested blocks) in a json file. The key is to use
append/only compose/deep user-data
. Only refinement is for keeping the sqare brackets. Compose is for evaluating field/text between parens. Deep refinement is for compose to work inside sub-blocks too. Unluckly I'm in a blackout again so I can't send you my program now.
- cosacam1
- 00:00@bubnenkoff I see you de00:02@bubnenkoff I see you developed a solution and gregg made a variation of it. I will study both when I have electrticity again.
- qtxie
- 03:27@ldci Added CHANGE action for image!03:27
a: make image! reduce [100x100 red]
b: make image! reduce [50x50 green]
change at a 25x25 b
view [image a]
- ldci
- 06:12@qtxie Thanks a lot:)
- bubnenkoff
- 07:26@cosacam1 thanks!
@greggirwin what random
do here? set face/extra/path random "abcdefg"
? Why it's needed?
- qtxie
- 08:26@ldci It's much faster than the pure Red version.
>> (dt [loop 1000 [change-at a b 25x25]]) / (dt [loop 1000 [change at a 25x25 b]])
== 419.1689133726497
- ldci
- 08:34@qtxie A new Red version:
change-at: function [
img1 [image!] ;--first image
pos [pair!] ;--offseting position
img2 [image!] ;--second image
][
nRows: img2/size/x
nLines: img2/size/y
if any [pos/x = 0 pos/y = 0] [pos: 1x1] ;--Red is 1-based
;--image 2 must be contained in image 1: we ignore extra pixels
if (pos/x + img2/size/x) > img1/size/x [nRows: img1/size/x - pos/x + 1]
if (pos/y + img2/size/y) > img1/size/y [nLines: img1/size/y - pos/y + 1]
line: 1
offset: (pos/y - 1 * img1/size/x) + pos/x
until [
row: 1
;print offset
while [row <= nRows][
img1/(offset): img2/(row)
row: row + 1
offset: offset + 1
]
offset: pos/y - 1 + line
offset: offset * img1/size/x + pos/x
line: line + 1
any [line = (nLines + 1) offset > (img1/size/x * img1/size/y)]
]
]
- greggirwin
- 18:43> what random do here? set face/extra/path random "abcdefg"? Why it's needed?
To show that it can update the data based on the key-path the face holds.
- bubnenkoff
- 08:04is it possible to fully change panel to another like:
view [
p1: panel red [
button return
button return
button
]
button "change panel" [
p1: panel green [ ; panel with new content
field return
field return
field
]
]
]
- hiiamboris
- 08:12by modifying
window/pane
- bubnenkoff
- 08:27
view [
p: panel red [
button return
button
]
button [
append window/pane [button]
]
]
> Script Error: window is unset in path window/pane
- hiiamboris
- 08:32window is the face where panel is located08:32how can you access it?
- bubnenkoff
- 08:40Than I am not understanding how to access to change it. I have ideas only like:
win: [
button [ append face/pane [button "test"] ]
]
view win
But it also do not work
- hiiamboris
- 08:41you may have read in the docs that there's a tree of faces, right?08:43how do you get a level up on that tree?
- bubnenkoff
- 08:48parent level is
face
, so accessing from body of layout
should be to window
if I right understand how all works
- hiiamboris
- bubnenkoff
- 13:15Do not understand docs. It's saying:
parent - Back-reference to parent face (if any).
. But face do same.
So face/parent is parent of parent face or what?13:51Also I can't find in VIS docs with
I seeing that this word is using quite 14:10I am not fully understand how with
and react/later
works in next code:
view/flags [
p: panel red with [ react/later [ size: parent/size - (self/offset * 2) ] ] [
a: area with [ react/later [ size: parent/size - (self/offset * 2) ] ]
]
] [resize]
15:00I have done example of panel that that have dynamic with and fixed height:
view/flags [
p: panel red with [ react/later [ width: (first parent/size * 20%) height: 100 size: as-pair width height ] ] [
]
] [resize]
- hiiamboris
- 15:24> Also I can't find in VIS docs
with
I seeing that this word is using quite
https://github.com/red/docs/blob/master/en/vid.adoc#with15:28> have done example of panel that that have dynamic with and fixed height
Good. That's a start ;)
- bubnenkoff
- 15:30Is there any good way to do resizable UI. Here button do not change it's position when UI is resizing:
view/flags [
field with [ react/later [ width: (first parent/size * 80%) height: 25 size: as-pair width height ] ]
button "ok"
] [resize]
Should I also calculate pad for it? Or there is better way?
- hiiamboris
- 15:32Yes, you'll have to change it's offset. How would button know what it should do unless you tell it?15:33Here's a simpler way: https://gitlab.com/hiiamboris/red-elastic-ui but perhaps you wanna learn how to do it yourself..
- bubnenkoff
- 15:37hm... maybe I should put field in come kind of container and button will take all remain space from the right of it?
- hiiamboris
- 15:40No, View just doesn't do that. Elastic UI does:
view/flags elastic [field #fill-x button "ok" #fix-x] 'resize

- bubnenkoff
- 15:43So impossible to do like (UI elements are not showing):
view/flags [
p: box with [ react/later [ width: (first parent/size * 80%) height: 110 size: as-pair width height ] ] [
field with [ react/later [ size: parent/size * 100% ] ]
button "ok"
]
] [resize]
- hiiamboris
- 15:51In Spaces it's automatic:

- bubnenkoff
- 15:54Ok! Thanks! 15:55I will wait at least beta stage
- hiiamboris
- 15:56You know that View is not going to be changed until the core is finished, yes? That is, no less than a year from now.
- bubnenkoff
- 16:00Yes, I think I will try to use
view
as it is and hope to rewrite UI someday in future to Spaces.
need only figure out how to change panels ) I still did not understand how to access to window
- hiiamboris
- bubnenkoff
- 16:07
view [
p: panel red [
button return
button
]
button [
append parent/pane [button]
]
]
heh:
*** Script Error: parent is unset in path parent/pane
- hiiamboris
- 16:09Unset indeed. Actor code is not bound to the face.16:09How do you access it from the actor?
- bubnenkoff
- hiiamboris
- 16:11Almost there.16:12Inspect
face/parent/pane
. Values of what datatype are inside it?
- bubnenkoff
- 16:12Almost -- you mean I need to reduce [button] ? I tried it too:
button has no value
- hiiamboris
- 16:13Don't do random things. Follow my questions ;)16:13As you progress, you will learn.
- bubnenkoff
- 16:14There objects. So I need to add button as object. Yes?
- hiiamboris
- 16:14Objects! True! So how do you *usually* turn word
button
into a button object?16:15(obviously the object has to be created by something)
- bubnenkoff
- 16:16I know only one long way - describe it's as object
make object! ....
(do not remember full syntax)
- hiiamboris
- 16:16Well, one tip:
view [stuff]
is equivalent to view layout [stuff]
because view
internally calls layout
.16:17There's also make-face
, but probably not needed here.
- bubnenkoff
- 16:17Oh! That's work:
view [
p: panel red [
button return
button
]
button [
append face/parent/pane layout/only [button]
]
]
16:18thanks!
- hiiamboris
- 16:18:clap:
- bubnenkoff
- 16:18So in this way I could hide panel and show on it place panel with another content?
- hiiamboris
- 16:19Also mind that you may have to adjust /offset of the button you've created (it will always be at 10x10 otherwise)16:19> So in this way I could hide panel and show on it place panel with another content?
Yes. But also you could have declared a few panels with hidden
flag and one visible, and then just changed the /visible?
facet when you need it.
- bubnenkoff
- 16:21on same place? Just to switch between them?
- hiiamboris
- 16:21Yeah
- bubnenkoff
- 16:22perfect! Thanks!
- hiiamboris
- 16:22You're welcome
- bubnenkoff
- 18:44I remember I have asked about getting selected text from area, but is it hard to get from rich-text?
- greggirwin
- 18:46https://github.com/red/docs/blob/master/en/rtd.adoc
- hiiamboris
- 18:48Rich-text is not interactive.
- greggirwin
- 18:51You can track selection though.18:52It just doesn't do it automatically.
- luce80
- 17:38@bubnenkoff About a resizable UI, if you have a simple UI where the styles simply "follow" the borders you can do as I did in the bottom part of [this useful script](https://gist.github.com/luce80/bfa8b54ca8c7e726723072786cad56fa)
- bubnenkoff
- 18:29@luce80 big thanks! look good! But do you have mode docs? It's not very clear how to add it to exist code
- cosacam1
- 19:10Hi there. Is there an on-close (or something) event to take some action before a window is closed, even to avoid it to be closed? thanks
- hiiamboris
- 19:13Exactly.
on-close
:)19:16This chapter explains how to intercept events https://github.com/red/docs/blob/master/en/view.adoc#114-event-flow
- cosacam1
- 19:17However
`
view [button [unview]] on-close [print "so long!"]
*** Script Error: on-close has no value
*** Where: catch
*** Near : on-close [print "so long!"]
*** Stack:
- hiiamboris
- 19:18use /options facet19:19or put your actors at the beginning of view block (but it's not by design ;)
- cosacam1
- 19:24view/options [button [unview]] [on-close: [print "so long!"]] doesn't show error but prints nothing either
- gurzgri
- 19:28It's
view [on-close [print "so long!"] button [unview]]
.
- hiiamboris
- 19:29/options is not a dialect, just Red code
- cosacam1
- 19:32@gurzgri Thanks but it does not print message
- gurzgri
- 19:32> or put your actors at the beginning of view block (but it's not by design ;)
At least it's [documented](https://github.com/red/docs/blob/master/en/vid.adoc#34-actors-definition) I think.
- hiiamboris
- 19:35Oh great then. I just remember it caused some troubles..
- gurzgri
- 19:36@cosacam1
on-close
actor is triggered on closing the window with the close icon in the tile bar. If you wan't the button to result in that action too, then do something like
view [on-close [print "so long!"] button [do-actor face/parent none 'close unview]]
- cosacam1
- 19:40Yes, @gurzgri I 've just noticed that with example given in Helpin' Red. Thanks. And what about to avoid closing?
- greggirwin
- 19:45
view/options [
title "Closed window"
size 500x600
][
actors: object [
on-close: function [face event][
view/flags layout [
text "Do you want to close? <yes> <No>"
style b: button
b "Yes" [ret: 'done unview]
b "No" [ret: 'continue unview]
][modal popup]
ret
]
]
]
- hiiamboris
- 19:53click "X" twice ;)
- cosacam1
- 19:54So
continue
is another return value for the event. I knew about 'done and 'stop, now 'continue. Anything else? Any document about it? Thanks hiiamboris, christian and gregg.
- gurzgri
- 19:56[Global event handlers](https://github.com/red/docs/blob/master/en/view.adoc#115-global-event-handlers)19:57
'continue
you've just made up I guess, @greggirwin, to contrast the return value with 'done
, didn't you?20:03And 'done
doesn't seem to prevent the window from being closed when returned in the containers on-close
as in
view window: layout [on-close [print "You'd better stay!" 'done] text "Stay for good"]
(but atm I'm not on the very latest red-latest)
- hiiamboris
- 20:05
continue
seems undocumented (no other token seems to work)20:06also this breaks the general capturing/bubbling design, where for other events you have to capture them to intercept20:09@dockimbel
- cosacam1
- 20:12Yeap, undocumented, the link given by Christian only mentions 'done, 'stop and none. Ok, I'm learning from you guys. Thanks20:17Guys. I'm embarrased. There's no way I can format properly my code in the black box like everybody else. I'm typing in my laptop now but most the times I chat with you using my phone. I use the triple apostrohes (the one located above Tab in my laptop keyboard) however I cannot do it right. Sorry if I bother you20:21@bubnenkoff I finished the sample program for creating a json file from my tree-like data. If you're still interested...20:22It is 215 lines long
- gurzgri
- 20:28Not triple apostrophes but [triple backticks followed by
Red
word](https://docs.github.com/en/get-started/writing-on-github/working-with-advanced-formatting/creating-and-highlighting-code-blocks) for Red code blocks. And blank lines before an after backtick blocks are suggested. Single backticks for inlining code.
- greggirwin
- 21:07I remember these events being a little tricky when I used them long ago.21:07That is, I couldn't just remember them and get them right.
- bubnenkoff
- 12:18>
> data: [
> foo: none
> bar: none
> lots: [
> lot: [
> number: none
> ]
> customers: [
> customer: [
> name: none
> ]
> ]
> ]
> ]
>
> foo: function [] [
> level: 0
> ui: copy []
> key-path: make path! [] ; this looks empty, but it's like an invisible empty block
>
> add-ctl: func [key][
> ; first key use is for name, second for saving its key
> append ui compose/deep/only [
> pad (1x0 * level * 15)
> button (form key) extra [key (key) path (copy key-path)] [
> print ["Current value:" mold get face/extra/path]
> either block? get face/extra/path [
> print "Don't set containers!"
> ][
> set face/extra/path random "abcdefg"
> ]
> ]
> return
> ]
> ]
>
> walk: func [
> data [block!]
> /with root-key ; quick hack to avoid lit-arg design for now
> ][
> if with [append key-path root-key]
> foreach [key value] data [
> append key-path to word! key ; can't have set-words in a path
> add-ctl key
> either block? value [
> level: level + 1
> walk value ; recurse into nested block
> ][
> ; We aren't recursing, so drop the last key in the path
> take/last key-path
> ]
> ]
> take/last key-path
> level: level - 1
> ]
>
> walk/with data 'data
>
> probe ui
> ]
>
> view foo
> print ["Data is now:" mold data]
>
I went back to study an example. It's not still clear for me what path
is
button (form key) extra [key (key) path (copy key-path)]
I tried to inspect button object but did not see no properties named path
:
>> view [b: button]
>> probe :b
- hiiamboris
- 12:23look in
extra
- bubnenkoff
- 07:17
/with root-key ; quick hack to avoid lit-arg design for now
Did not understand about lit-arg design
09:26Also I can't understand how compose/deep/only
works:
>> compose/only [ [(2 + 2)] ]
== [[(2 + 2)]]
>>
>> compose/deep/only [ [(2 + 2)] ]
== [[4]]
>>
>> compose/deep [ [(2 + 2)] ]
== [[4]]
>> compose/deep [ 1 2 3 [(2 + 2)] ]
== [1 2 3 [4]]
>>
>> compose/deep/only [ 1 2 3 [(2 + 2)] ]
== [1 2 3 [4]]
- hiiamboris
- 10:33What does /only docstring say?10:33And /deep
- bubnenkoff
- hiiamboris
- 10:40Well, try it with blocks, not just 2 + 2
- bubnenkoff
- 10:45@hiiamboris How stable Spaces stable now? I have a task to build complex UI and I have some problems that VID is not perfect for it, and I see that Spaces is much more powerful, so is it's time to start or you will do some breaking changes?
- hiiamboris
- 11:39No breaking changes, you can use it.
- bubnenkoff
- 11:55Oh! I understood!13:16@greggirwin big thanks for your example! I learned a lot from it. But now I decided to continue mine code, because I understand it's better.
Just to show what I am trying to reach (there is a lot of work) but mode complex example:
data: [
foo: 1
bar: none
lots: [
lot: [
number: none
price: none
date: none
]
customers: [
customer: [
name: none
]
]
]
]
foo: function [] [
level: 0
add-button-added?: false
words-added?: false
parent-name: none
if (level = 0) [parent-name: 'data] ; for root parent always data
ui: copy [
panel red []
panel blue []
]
walk: func [ data ] [
foreach [key value] data [
either block? value [
if (level = 0) [
append ui/3 compose/deep [pad (1x0 * level * 15) button "add block" button ( rejoin ["add field " parent-name ] ) extra (to-string key) pad 0x-10 return ]
add-button-added?: true
]
level: level + 1
append ui/3 compose/deep [pad (1x0 * level * 15) field data [(key)] button "add block" button "add field" extra (to-string key) pad 0x-10 return ] ; first (to-string key) for name, second for saving it's position
parent-name: key ; save parent name
walk value
] [
append ui/3 compose/deep [pad (1x0 * level * 15) field data [(key)] pad -10x0 field data [(value)] extra (to-string key) pad 0x-10 return ] ; first (to-string key) for name, second for saving it's position
]
]
level: level - 1
]
walk data
return ui
]
view foo
- greggirwin
- 17:48Keep making progress. :^)
- bubnenkoff
- 08:43> I forgot why next code is add only one field to UI:
>
> add-field: function [] [
> append p/parent/pane layout/only [field]
> ]
>
> view [
> p: panel [
> ]
> button "add" [add-field ]
> ]
>
> I thought it should add as many fields as was clicked on add button
>
Code above work. What I am missing here?
add-field: function [] [
append ui/parent/pane layout/only [field]
]
ui: [
button "add" [add-field ]
]
view ui
error: *** Script Error: path ui/parent/pane is not valid for none! type
- hiiamboris
- 09:12what is
ui
?
- bubnenkoff
- 09:13
block!
- hiiamboris
- 09:26indeed, and do you see
parent
in that block?
- bubnenkoff
- hiiamboris
- 09:27you should use
face
available to every actor
- bubnenkoff
- 09:29
add-field: function [] [
append face/parent/pane layout/only [field]
]
ui: [
button "add" [add-field ]
]
view ui
Script Error: face is unset in path face/parent/pane
- hiiamboris
- 09:29I said to every actor, not to every function09:30where is the actor in your code?
- bubnenkoff
- hiiamboris
- 09:32no,
button
is a face09:32actor is something that *acts* upon events
- bubnenkoff
- 09:32on click event. So
[add-field ]
is actor?
- hiiamboris
- 09:32exactly
- bubnenkoff
- 09:38Ok. Your are saying:
you should use face
available to every actor
and [add-field ]
is actor
So I can't imagine how it should look like...
- hiiamboris
- bubnenkoff
- 09:48Wow! Did not think that it's possible!
add-field: function [face] [
append face/parent/pane layout/only [field]
]
ui: [
button "add" [add-field face]
]
view ui
yes it's works!
- hiiamboris
- 09:50:clap:
- gurzgri
- 13:11@bubnenkoff Just have a look into what happens with an actor defined in VID:
>> layout [btn: button [do something]] probe btn/actors
make object! [
on-click: func [[trace] face [object!] event [event! none!]][do something]
]
The actor block is used to create a function having args face
and event
, both of which you can use in it's body without them being declared somehow in the VID dialect.13:16When a face recieves an click
event, the View system calls the face's on-click
actor function as in do-actor face event 'click
to process it. That's why face
in the actor body can be used.
- hiiamboris
- 13:20And it's [documented](https://github.com/red/docs/blob/master/en/vid.adoc#actors) ;)
- bubnenkoff
- 17:56why binding with offset do not work?
view [ size 300x300 f: field with [offset: 50x30] ]
I am seeing field on same position every time
- gurzgri
- 18:21
view
calls layout
which lays out the window's pane sub-faces, offsetting them according to VID rules. Use e.g. at
.
- bubnenkoff
- 18:35ah! thanks!18:38@gurzgri so it would work inside
panel
?
- hiiamboris
- 18:41after or during faces creation
- bubnenkoff
- hiiamboris
- 18:45what exactly do you want to achieve? maybe there's a better way
- bubnenkoff
- 18:51@hiiamboris I am still continue experiments with generation complex tree that refresh UI. But small example is look like:
add-field: function [face] [
append face/parent/pane layout/only [field at 0x30] ; I need way to put field in custom position
]
ui: [
button "add" [add-field face]
]
view ui
So I want to add some offset
- hiiamboris
- 18:55you're misusing
at
keyword18:55re-read the docs
- bubnenkoff
- 19:00you are right again)
- hiiamboris
- GiuseppeChillemi
- 20:45I would like to learn how to use
assert
, do we have some documentation?
- hiiamboris
- 20:47https://static.red-lang.org/red-system-specs.html#section-12.120:47https://codeberg.org/hiiamboris/red-common/src/branch/master/assert.md
- bubnenkoff
- 17:22I know that it should be better place it's in docs, but maybe someone will look in search removing element from a face. Example:
view [p: panel [ button] button "remove" [ p/pane: [] ] ]
it's clear panel and remove button from it
- cosacam1
- 21:03well it works, my code is formatted properly here in a black box, but I needed to type shift+enter instead of enter. How to do it if I were typing from a phone? Or how to copy&paste a piece of code where I typed Enter all the time?
- hiiamboris
- 21:16Phone app usually does not send the message until it sees one of
.!?
21:17But if it's not working you can always access this chat [from matrix](https://matrix.to/#/#red_help:gitter.im?utm_source=gitter)
- cosacam1
- 21:17should I put here an example program I made to show how to manipulate a little database in json? Or should I put it in some other place? In that case, where?
- hiiamboris
- 21:18https://gist.github.com
- cosacam1
- 21:26OK, here it is https://gist.github.com/cosacam1/0e5702505c92a5e1f34e69e94f264d7e21:28Thanks hiiamboris, but my question is: Do I need to type shift+enter in every line instead of plain enter?21:28Let me try:21:39
Red
Red [needs: view]
view [
tab-panel [
"One" [
field
button "Ok"
]
"Two" [
box blue loose
]
]
]
No, it does not work without shift+enter
21:40Yes it does! I must finish my message with Ctrl+Enter21:57Thanks, guys
- hiiamboris
- 12:28
*** Script Error: reset-start-pos has no value
- bubnenkoff
- 12:32I forgot to remove it. one moment12:33
data: [
foo: 1
bar: none
]
clear-panel: func[] [
print "clear-panel"
ppp/pane: []
row-added-count: 0
]
row-added-count: 0
level-vertical-offset: function[/extern row-added-count] [
return to-pair compose [0 ( row-added-count * 30)]
]
ui: copy [
size 520x700
ppp: panel red 340x690 [
]
button "start" [foo face]
button "clear panel" [clear-panel]
]
foo: func [face] [
print "foo"
walk: func [ data ] [
foreach [key value] data [
append ppp/pane layout/only compose/deep [at ( level-vertical-offset ) field ] ; first (to-string key) for name, second for saving it's position
row-added-count: row-added-count + 1
]
]
walk data
]
view ui
I can't understand why removing stop works after few: add control, remove, again add and agai remove
- hiiamboris
- 12:36we're back to https://github.com/red/red/wiki/[DOC]-Why-you-have-to-copy-series-values
- bubnenkoff
- 12:45Heh, this article is hard even for people that have some experience. Honestly I do not see place in my code where could be issue with copy
- hiiamboris
- 12:47in the piece that doesn't work ;)12:50> hard even for people that have some experience
ok let me try: *every time you write a **literal** series in your code, you have to ask yourself: am I not modifying it?*12:51I've counted 27 literal series in the above code.
- bubnenkoff
- 12:53I found issue:
clear ppp/pane ; that's work
But should create new empty series that remove old data
ppp/pane: []
- hiiamboris
- 13:00@bubnenkoff you count now. How many series do you see in your code?13:01(I made a mistake since I'm bad at counting ;)
- bubnenkoff
- 13:03I counted 713:06I am not sure if function args is series, possible they are so I need plus them
- hiiamboris
- 13:28Wrong ;)13:28
>> ? series!
SERIES! is a typeset! value: [block! paren! string! file! url! path! lit-path! set-path! get-path! vector! hash! binary! tag! email! ref! image!]
13:29Reminder for you
- bubnenkoff
- 14:31oh... but I still do not understand issue with copy
>> foo: [a b c]
== [a b c]
>> foo: [] ; not it become empty
== []
>> probe foo
[]
== []
>>
- hiiamboris
- bubnenkoff
- hiiamboris
- 14:48what type is
f:
?
- bubnenkoff
- 14:48
set-word!
- hiiamboris
- 14:48is
set-word!
a series?
- bubnenkoff
- 14:49It seems that
set-word!
is exception from list above, there is set-path! but no set-word!
- hiiamboris
- 14:50Indeed. All paths are there if you look closely, but no words.14:50So
f:
is not a series. But you've missed some, find more.
- bubnenkoff
- hiiamboris
- 14:52Yes. So that makes 4?
- bubnenkoff
- 14:52yes
- hiiamboris
- 14:52And is this function
f
working or buggy?
- bubnenkoff
- 14:53oh! it's buggy!
- hiiamboris
- 14:53Indeed! And why?
- bubnenkoff
- 14:55I do not understand where it's do appending, it seems that it append to block! itself but I do not understand why it do so.
I need away from PC, brb late
- hiiamboris
- 14:55Sure. Think on it while you're away.
- greggirwin
- 17:53Also, it is *critical* to understand that playing in the console and running scripts will not show the same behavior, as many people expect it will. If you paste your code into a console, then you can see how the interpreter sees it more than how you do as a human. e.g. every line you type is like a new line in a script.
- hiiamboris
- 19:01I'm facing a challenge. How can I define a
#macro1
that enables #macro2
until the end of the block it appears in, but not after leaving it?19:20My only idea is to parse
the rest of the block myself, but then I will have to assume independence of #macro2
from any other macros defined. If some macro leaves #macro2
after itself, I won't know because I'm processing everything ahead of the preprocessor.
- greggirwin
- 19:27But that comes back to finding the end of the block again. 19:28It seems like a tricky pattern in any case, because you're already inside the block, correct? So you'd have to back up and find the start of the block you're in.
- hiiamboris
- 19:29Bingo! I can make
#macro1
leave a #macro3
marker before the tail that will turn #macro2
off. Thanks.19:30No need to find the start though. From the #macro1
location it will be fine.19:31Will need some kind of stack though, for nested blocks.
- greggirwin
- 19:31Even if more blocks come before the end of the one you're in? In any case, it's clever to use another macro for it, which I hadn't thought about.
- hiiamboris
- 19:32Yes, that's why stack will be needed.
- greggirwin
- 19:32I was writing while you were. :^)
- hiiamboris
- greggirwin
- 19:33So now you have
#stackro
handling to create. :^)
- dockimbel
- 20:48@hiiamboris This feature might help: https://github.com/red/docs/blob/master/en/preprocessor.adoc#local
- hiiamboris
- 21:07Hmm. Then I will have to define new macro in every block. I guess it's an option, but seems more work.
- bgrossot
- 21:13Hello, I have not find in doc what return the stats function. Any idea ?
- hiiamboris
- 21:17Number of bytes allocated.21:31I figured how to write
#macro1
without #macro3
and without even affecting nested blocks. I just need to list all blocks #macro1
appears in in some list, and check the blocks #macro2
appears in for presence in that list.21:33Can even do parse-time checking in the macro pattern.
- bubnenkoff
- 09:05
f: func [] [print append "hello " "world"]
I have only idea that it works in next way:
hello and every series!
point to it's container. That now block!
and we bind it with block!
and than we continue to append "word"
to it
- hiiamboris
- 09:07no, no need to involve container at all
- bubnenkoff
- 09:19ah... it seems that I am begin to understand.
first hello
is series and we begin add to add data to it again and again because it's binded to with it in memory
- hiiamboris
- 09:21yes,
append
receives a series which it modifies *in place*09:21it adds *directly* to "hello "
we see09:21we didn't copy it, so it grows09:22so it will be modified
- bubnenkoff
- 09:36oh. Thanks! Now I understand the situation much better, but why first removing controls in my example works?
- hiiamboris
- 09:39because
pane
was assigned a block internally, then you appended to that block
then you assigned your own block []
so the other one got lost together with it's faces
but later you assigned the *same your* block again, you didn't change it, so you keep appending to it
- bubnenkoff
- 09:47Oh! Big thanks for explanation! It's hard to keep in mind specific of
copy
11:24How to get coloring work immediately after adding control? on-change event to not handle default value:
foo: function [] [
append ppp/pane layout/only compose/deep [ field data ["none"] on-change [either face/text == "none" [face/color: red] [face/color: none] ] ]
]
view [ ppp: panel [ ] button [foo] ]
- hiiamboris
- 11:26modify them
- bubnenkoff
- 11:39some point = button click event?
- hiiamboris
- 11:43that is an exercise for you
- bubnenkoff
- 11:44I remember that I can pass face to function, but I can't understand is it this case?
- hiiamboris
- 11:45you remember what kind of data is in pane?
- bubnenkoff
- 11:46pane with block that contain faces I think
- hiiamboris
- 11:47right11:47you get these faces from somewhere11:47modify them before appending
- bubnenkoff
- 11:56You mean this?
foo: function [face] [
append ppp/pane layout/only compose/deep [ field with [color: red] data ["none"] on-change [either face/text == "none" [face/color: red] [face/color: none] ] ]
]
view [ ppp: panel [ ] button [foo face] ]
to bind it's with default color?11:58or what kind of modifications I can do...
- hiiamboris
- 12:02sorry, I gave you too many hints already ;)12:02it's up to you now to work it out
- bubnenkoff
- 12:02ok) thanks)
- hiiamboris
- 12:04I can only say it's sooo much simpler than what you're doing ;)12:07@bubnenkoff maybe I don't get what you're trying to do though12:08you already colored it, what's wrong with that?
- bubnenkoff
- 12:11I tried to get colorizing work without
on-change
event. Binding with color: red
~~is solve my problem~~, but I thought that there is any other way to do it
- hiiamboris
- 12:13there's always another way..
- bubnenkoff
- 12:14I was wrong that it solve problem)
- hiiamboris
- 12:15why not? :)
- bubnenkoff
- 12:15Because blank fields become red by default)12:16[](https://files.gitter.im/5780ef02c2f0db084a2231b0/CKjl/izobrazhenie.png)
- hiiamboris
- 12:17when they *should* be red?
- bubnenkoff
- 12:19I need to colorize to red only
none
values at moment of it's adding
- hiiamboris
- 12:21try [reactivity](https://github.com/red/docs/blob/master/en/reactivity.adoc)
- bubnenkoff
- 12:49
bar: function [face] [
either (face/text = "none") [red] [none]
]
foo: function [face] [
append ppp/pane layout/only compose/deep [ field data ["none"] react [ face/color: bar face ] ]
]
view [ ppp: panel [ ] button [foo face] ]
Do not work at all....
- hiiamboris
- 12:50try inlining
bar
12:51or, hackish way: react [ [face/text] face/color: bar face ]
- bubnenkoff
- 12:53one moment12:55
foo: function [face] [
append ppp/pane layout/only [ field data ["none"] react [ face/color: either (face/text = "none") [red] [none] ] ]
]
view [ ppp: panel [ ] button [foo face] ]
is it right inline version?
- hiiamboris
- 12:55should be
- bubnenkoff
- 12:56But it's do not work :(
- hiiamboris
- 12:56works for me
- bubnenkoff
- 12:57And if you are changing value from
none
to any other it's work? and change color?
- hiiamboris
- 12:5812:58
Red 0.6.4 for Windows built 3-Sep-2022/17:53:01+03:00 commit #cb83eca
- bubnenkoff
- 13:00wow! Cool! I will try to upgrade. My version is seems out of date:
Red 0.6.4 for Windows built 3-Feb-2022/20:16:35+03:00 commit #fbdf84d
- hiiamboris
- 13:01https://github.com/red/red/issues/5103 was fixed recently, probably the case
- bubnenkoff
- 13:03yes, now it's works for me to13:03thanks!
- hiiamboris
- 18:49@bubnenkoff try reading this please https://github.com/red/red/wiki/%5BDOC%5D-Why-you-have-to-copy-series-values#explanation-for-totally-hopeless-dummies
Let me know if my explanation is clear enough for you or some parts need work.
- bubnenkoff
- 19:12Yes, I will read it now. It seems that I faced again with this problem. I really not understand how I am reach it %)
pos: 70x0
data: [
foo: []
bar: []
]
add-item: func [face] [
; clear ppp/pane
ppp/pane: copy []
append data [ test: [] ]
foo face
]
foo: func [face] [
print "foo"
walk: func [ data ] [
foreach [key value] data [
append face/parent/pane layout/only compose [at (pos: pos + 0x30) button (to-string key) [(add-item face)] ]
]
]
walk data
]
ui: [
size 300x500
button "add" [foo face]
ppp: panel [ ]
]
view ui
The idea of code is next. First button is adding controls to face and by clicking of any control control add new controls to face (every added control should do same as first button). But they begin to multiply. I discovered :ppp
and I am seeing that they are not removing, so it's issue with copy but I am doing: ppp/pane: copy []
- hiiamboris
- 19:20you're not adding to
ppp
- bubnenkoff
- 19:27> @bubnenkoff try reading this please https://github.com/red/red/wiki/%5BDOC%5D-Why-you-have-to-copy-series-values#explanation-for-totally-hopeless-dummies
> Let me know if my explanation is clear enough for you or some parts need work.
Yes, now it's much better. At least now I am understanding base idea. Maybe you should add some diagram like:
`[ ]` <-- block is located in memory and can contain data. Every data with type series! Is binding with this memory block.
`copy` is indicate that we should create new block in memory and use it instead old
I am not sure if what I wrote is right, but it's my current vision %)
- hiiamboris
- 19:29Thanks for your feedback
- bubnenkoff
- 19:34I can't to do short example of the bug, because short version works fine. But in long version https://gist.github.com/bubnenkoff/4f9c10b03086a0a3dbbc5f5ee84a2be4
I am getting stackoverflow error19:36to reproduce you need to add block and click to added block button add block
.
Test block is named test
so clicking on add block
is cause an error19:39[](https://files.gitter.im/5780ef02c2f0db084a2231b0/PZro/izobrazhenie.png)
- hiiamboris
- 19:47I'm only getting:
*** Script Error: append does not allow none! for its series argument
*** Where: append
*** Near : path-to-append [test: []]
*** Stack: view do-events do-actor do-safe add-item
- bubnenkoff
- 19:49on gist above?? How it's possible?
- hiiamboris
- 19:50restart your console maybe
- bubnenkoff
- 19:50could you run it on fresh console with copy paste then:
1. click start
2. on customer click add block
3. on appeared test
click add block
- hiiamboris
- 19:51oh reproduced19:54It's as I thought... try
?? data
after the error19:55see anything wrong with it?
- bubnenkoff
- 19:56Yes, I am seeing. it seems I am doing append at wrong place20:00But why it getting at recursion? I do not seeing place where is happens. I should be able to add
test
inside test
- hiiamboris
- 20:01that means you appended something *to itself*
- bubnenkoff
- 20:02yes20:03but why it begin to do it infinity? It should to do it only one time per click 20:11Oh, oh! It's seems I realized problem!20:13I am finding path to append by block name, and here block name is same -- every time it's
test
. It's look like it's root of issue
- hiiamboris
- 20:16well if series is infinitely nested, stack overflow is expected when traversing it
- gurzgri
- 21:52@bubnenkoff Just for the fun of it, here's another
parse
based take on your find-path-to-node
/walk
approach, which gives equivalent results (probably minus the effects on extern words which you might rely on in other places):
find-path-to-node: function [data node] [
path: copy []
parse data content: [any [
set step set-word! ahead block!
( append path to word! step)
( if equal? node step [return new-line/all path off])
into content
( take/last path)
| 2 skip
]]
none
]
- jasongrossman:matrix.org
- 04:57I'm using red on NixOS (which currently only has one version packaged, namely red 0.64 cli). Can someone please tell me where to see the command-line options of the red command? ty!
- riprwwa
- 05:33Have a look at the readme file in the root of the repo: https://github.com/red/red/blob/master/README.md
Read below "The full command-line syntax is:"
- jasongrossman:matrix.org
- 05:47Thank you!
- bubnenkoff
- 07:33> @bubnenkoff Just for the fun of it, here's another
parse
based take on your find-path-to-node
/walk
approach, which gives equivalent results (probably minus the effects on extern words which you might rely on in other places):
>
>
Red
> find-path-to-node: function [data node] [
> path: copy []
> parse data content: [any [
> set step set-word! ahead block!
> ( append path to word! step)
> ( if equal? node step [return new-line/all path off])
> into content
> ( take/last path)
> | 2 skip
> ]]
> none
> ]
>
Perfect! Thanks!08:22Yesterday I thought that I have problem with recursion because I am trying to insert nodes with same name. But I was wrong.
https://gist.github.com/bubnenkoff/67026416635b3c62f6ddcfd08ab419b2
I made node name unique but I am still getting infinity loop and stack overflow. And I can't understand why.
Yes, I tried to dump data
but I can't understand how it possible in my code. I do not see nothing that can trigger infinity adding.
Steps to reproduce:
1 click start
2 on customer
click add block
3 on appeared random name click add block
- hiiamboris
- 08:39I won't be able to tell a thing in such a big script ;)08:40I suggest removing irrelevant stuff until it becomes small enough to understand08:41For example, you don't need any View-related stuff if it's the
data
you can't get right. Work on data
first.
- bubnenkoff
- 09:01
if block [
append reduce to-path path-to-append compose [ (wrd-name) [] ] ; triggering stackoverflow
; append reduce to-path [data lots lot] compose [ (wrd-name) [] ] ; works
]
I do not see principal differene between hardcoded path and auto generated path like: [lots customers fbgadec]
.
What I can try to do else?
- hiiamboris
- 09:04perhaps latter keeps growing?
- bubnenkoff
- 09:13
prin "we will appeded to: " probe path-to-append
wrd-name: to-set-word random "abcdefg"
if block [
append reduce to-path path-to-append compose [ (wrd-name) [] ] ; triggering stackoverflow
; append reduce to-path [data lots customers customer] compose [ (wrd-name) [] ] ; works
]
click on cuctomer
:
we will appeded to: [data lots customers customer]
click on new added to customer
block named efdbcga
:
we will appeded to: [data lots customers customer efdbcga]
and then crush
it's look like correct.
09:15after first click on customer
data become:
...
customers: [
customer: [
name: none
efdbcga: [] ; it's looks right
]
]
- hiiamboris
- 09:19find the point when
data
becomes cyclic
- bubnenkoff
- 09:32hm... I have filling that it's issue with
copy
. I can't explain exactly but:
append reduce to-path path-to-append compose [ (wrd-name) [] ] ; possible I should copy [] here
- hiiamboris
- 09:33try it
- bubnenkoff
- 09:42Yes! I was right! But I do not understand why I should use copy here((
append reduce to-path path-to-append reduce [ wrd-name copy [] ] ; works
- gurzgri
- 10:38That's because according to
first spec-of :reduce ;== {Returns a copy of a block, evaluating all expressions}
reduce
only returns a copy of the one outer block, it doesn't copy all series in that block.
- bubnenkoff
- 12:32Eght... tiny example with inline reactivity works fine:
foo: function [face] [
append ppp/pane layout/only [ field data ["none"] react [ face/color: either any [(face/text = "none") ((length? face/text) < 2 )] [red] [none] ] ]
]
view [ ppp: panel [ ] button [foo face] ]
But same condition do not work at bigger project:
https://gist.github.com/bubnenkoff/f6d01055c91d2c3a4a319993a81bf035#file-app-red-L176
Nothing do not colorize on none
and length < 2
- hiiamboris
- 12:35that snippet doesn't work at all
- bubnenkoff
- 12:36[](https://files.gitter.im/5780ef02c2f0db084a2231b0/UX5Z/izobrazhenie.png)12:36fresh console
- hiiamboris
- 12:39
*** Syntax Error: (line 149) missing [ at ]
*** Where: transcode
*** Near : https://gist.githubusercontent.com/bubne
*** Stack: load
12:39the big one
- bubnenkoff
- 12:39Ah, one moment I will recheck it12:41I tried to open fresh console. than did copy-paste from raw gist to console and I do not see any errors
- hiiamboris
- 12:44well, why can't I?12:44ohh12:45that's so weird
- bubnenkoff
- 12:45get it work?
- hiiamboris
- 12:45wtf12:47I get it12:47console simply ignores extra
]
you put on the line
- bubnenkoff
- 12:48Does colorize work for you?
- hiiamboris
- 12:49nope12:51you're composing it all out12:51check the
layout
spec after composing
- bubnenkoff
- 12:53> Eght... tiny example with inline reactivity works fine:
>
> foo: function [face] [
> append ppp/pane layout/only [ field data ["none"] react [ face/color: either any [(face/text = "none") ((length? face/text) < 2 )] [red] [none] ] ]
> ]
> view [ ppp: panel [ ] button [foo face] ]
>
>
> But same condition do not work at bigger project:
> https://gist.github.com/bubnenkoff/f6d01055c91d2c3a4a319993a81bf035#file-app-red-L176
>
> Nothing do not colorize on none
and length < 2
>
>
So you are seeing difference in layout
in this tiny example and in big code?
- hiiamboris
- 12:55I didn't check TBH but I spotted compose/deep and parens ;)12:56
compose
is quite evil design
- bubnenkoff
- 12:58yes) I understood)15:42Heh) is it possible to write next code without round brackets?
if ((length? "asd") < 4) [print "less"]
- hiiamboris
- 15:43
if 4 > length? "asd"
15:43if lesser? length? "asd" 4
- bubnenkoff
- 15:48oh! Cool! Thanks!
- greggirwin
- 17:36>
compose
is quite evil design
I've never felt that way. Some patterns aren't a good fit for it, hence Ladislav's build
dialect idea and others. e.g. [my inject experiment](https://gist.github.com/greggirwin/29836d25de0c68eaba0e6dbd268a20f5), but that doesn't make it evil.
- hiiamboris
- 17:37It's evil because it keeps biting you from time to time when you least expect it.17:38It's fine for single-line of code composition, even a few short ones, but we are actually promoting it's use even on View layouts. For that it's a very bad design.17:39I can't count times when I was writing parens totally forgetting that I'm writing them inside some big compose/deep scope.
- greggirwin
- 17:46That's funny reasoning.
- hiiamboris
- 17:59Why? ;)
- gurzgri
- 18:03> forgetting that I'm writing them inside some big compose/deep scope
compose
and I are best friends since the beginning, but whenever compose
was in involved in bugs in my code, it was for this very /deep
reason.
- hiiamboris
- 18:04exactly
- gurzgri
- 18:11@bubnenkoff
> Perfect! Thanks!
You're welcome! But that find-path-to-node
version comes with a special restrictive license attached: You're only allowed to use it in your code if you can credibly assure that you've processed and digested it and understand how and why it is working :wink:
- bubnenkoff
- 18:26Is it possible to remove
foo: []
at one step?
data: [ foo: [] bar: [] ]
remove data 'foo ; the block will stay
- hiiamboris
- 18:27
? remove
- bubnenkoff
- 18:27@gurzgri yes, I understand this problem) So often prefer write my own code even if there is some shorter alternative, because at least I can fix my own
- greggirwin
- 18:29@hiiamboris wouldn't that line of thinking make a *lot* of constructs "evil"? You say it's bitten you, and your own coding patterns or style don't fit well with it. That doesn't make it evil, or a bad design. That's on you. :^) Saying it's a bad design also implies that there's a better one, would you agree? If so, where is it?
- bubnenkoff
- 18:29@hiiamboris yes I did it. but
remove/part
is require to know position of removing element
- hiiamboris
- 18:31@greggirwin It's bitten me, Christian, Dmitry, Giuseppe, Ladislav - at least these are who testified.18:31> Saying it's a bad design also implies that there's a better one, would you agree? If so, where is it?
https://codeberg.org/hiiamboris/red-common/src/branch/master/reshape.md
18:32(but really, just using a not so common marker would both kill /only and get rid of bugs)18:34(some parts in reshape design require it to walk backwards, which is powerful but also slower, so those parts are not for max juice)18:36(optional /deep in compose is also a performance thing)18:41> @hiiamboris yes I did it. but remove/part
is require to know position of removing element
re-read it @bubnenkoff
- bubnenkoff
- 18:49> > @hiiamboris yes I did it. but
remove/part
is require to know position of removing element
>
> re-read it @bubnenkoff
data: [ foo: [] bar: [] baz: [] ]
remove/part data 2 'bar
probe data
== [bar: [] baz: []]
/part => Removes a number of values, or values up to the given series index.
So I need to know index
- hiiamboris
- 18:52> Removes **a number of** values18:53anyway, you *always* know the index, if you wanna do it the hard way ;)
- greggirwin
- 18:57I remember
reshape
now @hiiamboris. Our own design tastes can be quite distinct. I know mine can. So when I say that reshape
is a massively more complex design and interface that doesn't make sense to me, that's my opinion. I'm happy for others to try it and weigh in, but it's certainly not *better* than compose
IMO. Like the mutability question, compose
is very simple to reason about, with a few limitations that we run up against sometimes. Omitting values is a big one.
As far as complaints against compose
, I don't remember a lot through the years, compared to how much it is used.
- hiiamboris
- 18:59you're ignoring my point:
> (but really, just using a not so common marker would both kill /only and get rid of bugs)
- greggirwin
- 19:05So let's focus on that and try it out. 19:07Which I think was Ladislav's goal, and also mine when I updated his ideas to play.
- gurzgri
- 20:51I second that motion, neither
compose
nor compose/deep
are bad by themself and I wouldn't want to do without them. They are just not the best solution especially for cases where compose/deep
and the paren markers are far away from each other — not so much when you write *new* code but modify/refactor *old* code. An easy oversight then, with a better aka "safer" solution yet to be proposed (at least I know of none which over time I preferred over the occasional bug hunting session).
- hiiamboris
- 21:13> a better aka "safer" solution yet to be proposed
There are many ways you can make parens unique, from a sigil like @() !() ~() &()
to refinements /splice () /single () /only () /mixin () /the () /just () /inline ()
, to tags () ...
, to issues #splice () ...
, to prefix(es) of your own choice on a per-call basis.21:15Anyway, I'm using reshape
in non-critical code all the time. If !()
and @()
are too hard to grok for someone, it's not my trouble ;)
- cosacam1
- 02:09@bubnenkoff make data point to foo ie., make foo the first elememt in data. Then
loop 2 [remove data]
That removes both foo and the block.02:12BTW did you see the application I put in gist ?
- jasongrossman:matrix.org
- 02:59It seems that the syntax for extending objects is not working, unless I'm misunderstanding something:
a: make object! []
extend a [newfield 99]
*** Internal Error: reserved for future use (or not yet implemented)
*** Where: extend
*** Stack:
I can extend objects like this instead - is the best way to do it?
a: make a object [newfield: 99]
Thank you!
- greggirwin
- 03:04Yes, extending objects is TBD, so you have to make a new one right now.03:05But you can make the new one using just a spec block as well:
>> o: object [a: 1]
== make object! [
a: 1
]
>> make o [b: 2]
== make object! [
a: 1
b: 2
]
- jasongrossman:matrix.org
- 03:07Awesome. Thanks!03:28I'm missing something basic about Red data structures :-(
I'd like to make a bidirectional mapping between one set of paths and another set of paths. If I use a map!, I can't see how to search both the keys and the values. Probably I'm just being blind to the right bit of documentation - sorry.
I can see how to search nicely in objects, but a path is not a word so it can't be a key in an object, right?03:31dockimbel (Nenad Rakocevic) recently said "The real challenge is the bijective text<=>values mapping", but that was in a different context ... I hope!
- hiiamboris
- 06:45Use a block or hash.
- bubnenkoff
- 07:03@cosacam1 could you give link again, it seems that I missed something...
Very soon I will public my code. I almost get it work.
09:05[](https://files.gitter.im/5780ef02c2f0db084a2231b0/wutl/izobrazhenie.png)09:05I did it! I get it work. Full code (need some cleanup)
https://gist.github.com/bubnenkoff/5fc06bdab712130108c9b2041a845b8d
For those who do not want to run it how it's look like:
- dockimbel
- 10:16@bubnenkoff Congrats! :+1:
- bubnenkoff
- 12:07Is there any simple way to add scroller to main app window if content is not feat in it?
view [
size 150x150
button "aa" return
button "bb" return
button "cc" return
button "dd" return
button "ee" return
button "ff" return
button "gg"
below
scroller [
]
]
(code not works)
I looked at examples here and all of them with calculation of elements size manually
- hiiamboris
- 12:14https://codeberg.org/hiiamboris/red-common/src/branch/master/scrollpanel.md12:15As far as simple goes...
- bubnenkoff
- 12:20I'd prefer native solution even if it would not so accurate.
I am not fully understand how scroller works. It's face, but if I am typing it in console it look like data type:
>> ? scroller!
SCROLLER! is an object! with the following words and values:
position none! none
page-size none! none
min-size integer! 1
max-size none! none
visible? logic! true
vertical? logic! true
parent none! none
on-change* function! [word old new]
- hiiamboris
- 12:31It's half baked so good luck ;)12:35Use
scroller
VID style.12:35But beware: 2D scrolling panel is one of the trickiest widgets to get right ;)12:37If you only need vertical scroller IIRC there's some hack to get it to show for a base
face (which can also act as a panel IIRC), using get-scroller
func12:39I have some examples stashed, probably from Toomas:
view [
size 390x220
across space 0x0
panel 350x200 [
origin 0x0 space 0x0
p: panel 350x800 [
origin 0x0 space 0x0
below
area "A" 350x200
area "B" 350x200
area "C" 350x200
area "D" 350x200
]
]
scroller 16x200 [
face/data: min .75 face/data
p/offset/y: to integer! negate 800 * face/data
]
on-created [face/selected: 25%]
]
12:39
view [
size 390x220
across space 0x0
base 367x200 with [
flags: 'scrollable
pane: layout/only [
origin 0x0 space 0x0
p: panel 350x800 [
origin 0x0 space 0x0
below
area "A" 350x200
area "B" 350x200
area "C" 350x200
area "D" 350x200
]
]
]
on-created [
put get-scroller face 'horizontal 'visible? no
sc: get-scroller face 'vertical
sc/position: 0
sc/page-size: 200
sc/max-size: 800
]
on-scroll [
sc/position: max 0 min 600 switch event/key [
down [sc/position + 20]
up [sc/position - 20]
page-down [sc/position + sc/page-size]
page-up [sc/position - sc/page-size]
track [event/picked - 1]
end [sc/position]
]
p/offset: as-pair 0 negate sc/position
]
]
12:41But base
as panel probably doesn't work since D2D merge.
- bubnenkoff
- 12:42Ogh..)) new challenge) 12:42Does this problem solved in Spaces?
- hiiamboris
- 12:43Indeed, but you can't use View faces inside Spaces.
- bubnenkoff
- 12:43> Use
scroller
VID style.
Examples above not about it? Could you show what is scroller
VID style.
- hiiamboris
- 12:43First is
- dockimbel
- 14:30@bubnenkoff You can use the built-in
scroller
widget, it's not that hard, even if it's currently limited:
https://gist.github.com/dockimbel/8a5bcf3acb470d0dd9f4dd0a07da7817
- greggirwin
- 18:30> I'd like to make a bidirectional mapping between one set of paths and another set of paths.
@jasongrossman:matrix.org do you have an example in another lang that shows how you do it? As @hiiamboris said you can use a block or hash, but path *notation* is always "forward looking" i.e., select
the next value in the path after the key. So if you do a key-val block, you'll need helpers to step backwards from the value. Whether your keys and values are guaranteed to be unique also comes into play.
You can also do fun things, like this:
blk: [k1 v1 k1 k2 v2 k2 k3 v3 k3]
blk/k1
blk/v2
blk/k3
blk/v3
Paste that into a Red console and see if you understand what it's doing. And does it work with select
? Does it work if the keys or values are not unique?
- cosacam1
- 19:47@bubnenkoff here is my link19:51https://gist.github.com/cosacam1/0e5702505c92a5e1f34e69e94f264d7e
- jasongrossman:matrix.org
- 22:23@greggirwin (Gregg Irwin) Thank you! That gives me a lot to think about. I think you've already answered my main question, which is what is idiomatic in Red. I love the blk: [k1 v1 k1 k2 v2 k2 k3 v3 k3] example.
22:26As for examples in other languages: in many other languages, maps can have any datatype as their keys. In some other languages (e.g. Smalltalk, Self, Io), even objects can have any datatype as their field names. In Red I can't have paths (or strings) as keys in maps or as field names in objects, right? But I can have them in blocks. So I think I now have enough to go on. Thank you!22:30My subsidiary question was about whether I could search for values in maps the way I can in objects ... but now I think I should give up on maps (because they can't have paths, or even strings, as keys). That leaves blocks, and I think I understand searching in blocks. Your points will help me check that I do.
- greggirwin
- 22:41Strings as keys work just fine.
>> m-1: #("A" 1 "B" 2)
== #(
"A" 1
"B" 2
)
>> m-1/"A"
== 1
>> m-1/"B"
== 2
Finding works on values-of
, but maps are unordered, so you can really only tell if a value exists, not which key it maps to. At least there are no guarantees, but for now you can use index?
to check the position against keys-of
.
You're correct that you can't use block types (of which paths are one) as map keys.
- jasongrossman:matrix.org
- 22:42Oh!22:42Can't think why I thought otherwise - I may have experimentad and made a typo. 22:42Thank you!
- greggirwin
- 22:42Happens to us all. :^)
- jasongrossman:matrix.org
- 22:43And as it happens, for my current use-case, finding which values exist is useful even without knowing their positions \o/22:43But in general it would probably be more idiomatic to use blocks, right, if that's not too vague a question?
- greggirwin
- 22:46Blocks are the most idiomatic compound type/data structure in Red, yes. But the others offer advantages and features of their own. It's all about matching them to the need. Start small and try with each type, see where you run into issues, and ask questions here with your use case as a backdrop. We call it "The Great Red Optimizer" and you'll get lots of wacky ideas sometimes.
- jasongrossman:matrix.org
- 22:47That makes complete sense. Thank you very much!
- ldci
- 05:55@jasongrossman:matrix.org . For map datatype, some examples here: https://github.com/ldci/Red-System/tree/main/Map
- jasongrossman:matrix.org
- 05:59Ooh thank you
- ldci
- 06:09@jasongrossman:matrix.org You’re welcome
- bubnenkoff
- cosacam1
- 12:59@bubnenkoff I solved the scroller problem this way:
In the view, I put a background panel (pnlBg) with a foreground panel (pnlFg) inside it.
pnlFg might be vertically smaller, larger or equal than pnlBg.
I also have a vertical scroller (scr) the same height as pnlBg.
pnlFg/pane contains the widgets (fields, buttons, whatever)
Then scr/extra will have the difference in size between both panels.
scr/extra: pnlBg/size/y - pnlFg/size/x
The difference will be negative when pnlFg is larger than pnlBg, that is how much of pnlFg is beyond pnlBg.
(Negative to make easier the math in scroll function below)
Make scroller visible only in that case because it is then when scroller is only needed
scr/visible?: scr/extra < 0
Then I put this scroll function. It moves pnlFg (and all the widgets in it) vertically because the x remains the same.
How much do we move it?
Well, the part of pnlFg that is not visible originally, affected by scroller's data.
When that data is 0.0, pnlFg's top will be aligned to pnlBg's top.
When scroller's data is 1.0 then pnlFg's bottom will be aligned to pnlBg's bottom.
Other values show pnlFg partially.
By the way, I have noticed that if I drag the scroller's thumb (or click the scoller's down arrow) to it's bottom,
scroller's data never gets to 1.0 but 0.91
(I think is Red's bug, sorry I never reported before)
So I force it to 1.0. That behaviour is not present if I scroll using mouse wheel.
So let's try it:
13:01
Red [needs 'view]
scroll: does [
if scr/data > 0.91 [scr/data: 1.0]
pnlFg/offset: as-pair pnlFg/offset/x (scr/extra * scr/data)
]
clamp: func [lo value hi] [min max lo value hi] ; a function to keep a value between boundaries
system/view/auto-sync?: yes ; to avoid flickering
view [
pnlBg: panel blue 200x100 [
at 10x0
pnlFg: panel yellow 180x250 [ ; I make pnlFg larger than pnlBg on purpose, and narrower too
below
check "Hi"
field hint "type here"
b: box red
button "Press here" [b/color: random 255.255.255]
]
on-wheel [
if scr/visible? [
;system/view/auto-sync?: yes uncomment this in case your code disables sync at any time
; next 0.91 is because of the bug (if any)
; I force it to 1.0 in scroll function but then,
; when scrolling via mouse wheel towards the top, it does not scroll
; so I force it back to 1.0 to make it work
scr/data: clamp 0.0 ((min 0.91 scr/data) + (scr/steps * negate event/picked)) 1.0
scroll
]
]
]
space 0x0 ; may the scroller be adyacent to pnlBg
scr: scroller 20x100 [system/view/auto-sync?: yes scroll] ; about sync, same as above
do [scr/extra: pnlBg/size/y - pnlFg/size/y scr/visible?: scr/extra < 0]
]
13:24@hiiamboris I tried both of your solutions for scrolling. The second one doesn't show the areas. I can't see why13:42About Red's bug on scrolling, I said before if I drag the scroller's thumb (or click the scoller's down arrow) to it's bottom,
scroller's data never gets to 1.0 but 0.91
Well, actually it is only when dragging the thumb. See next example and try to drag the thumb to the right end view [t: text scroller [t/text: to-string face/data]]
- hiiamboris
- 14:26> @hiiamboris I tried both of your solutions for scrolling. The second one doesn't show the areas. I can't see why
@cosacam1
> But base
as panel probably doesn't work since D2D merge.
(i.e. it was a dirty hack and not supported anymore)
- bubnenkoff
- 14:35I need to change one
set-word!
to another inside block. I know only it's index. It I tried:
x: [foo: none bar: none baz: none] ; need get: [test: none bar: none baz: none]
change/part x 1 (to-set-word 'test)
probe x
But got an error: *** Script Error: change/part does not allow set-word! for its range argument
- gurzgri
- 14:36> It's data + page-size that equals 1
And therefore scroller
shouldn't be confused with slider
, with the latter going up to 1 as in view [t: text slider [t/text: to-string face/data]]
- bubnenkoff
- 14:37it seems that it's work:
x: [foo: none bar: none baz: none]
change at x 1 (to-set-word 'test)
probe x
== [test: none bar: none baz: none]
- gurzgri
- 14:37
poke x 1 to set-word! 'test
14:39Think of poke
complementing pick
, setting a value at given index instead of getting it from there.
- bubnenkoff
- 14:39thanks!
- gurzgri
- 14:40The difference between your
change at
and poke
isn't that big and change at
reads nicely, too. But it's two funtions instead of one.
- cosacam1
- 14:43Oh, I see the point. Not the same scroller asslider. However a little confusing. I think data = 1.0 is expected when reaching the bottom. Ok, I can live with that. Thanks both.
- hiiamboris
- 14:44@cosacam1 I've stumbled upon that myself before ;)
- toomasv
- 14:45> (i.e. it was a dirty hack and not supported anymore)
Only second half of this is true. [Docs](https://github.com/red/docs/blob/master/en/view.adoc#base):
> This face type should be used for any custom graphic component implementation.
- hiiamboris
- 14:45I think that means using Draw, not native faces14:46Found https://github.com/red/red/issues/505114:46It can show other bases
- toomasv
- 14:51You mean only Draw is *graphic component*?
- hiiamboris
- 14:52I mean using Draw to create graphic components, like what Spaces are doing (or your table ;).
- toomasv
- 14:58I guess general understanding is that any face in *view* is *graphic*, i.e. has graphic aspect about it, is graphically presented. To narrow this to *drawn base faces* only is really stretching the meaning of *graphic*, IMO. Although in practice you are right and docs are wrong. :)
- hiiamboris
- 15:05I understand the docs as base is used to implement graphic components, but that does not imply that other graphic components can be grouped together in a base for that ;)15:06Good idea to use pane for caret face by the way.15:08Although.. maybe not as it could steal focus when clicked.
- cosacam1
- 17:00I've just downloaded Red 0.6.4 of today Sep 9, 2022. How can I know the differences from a previous version?
- hiiamboris
- 17:13https://github.com/red/red/commits/master
- cosacam1
- 17:58so there is where we can see how hard you guys work! congrats!
- hiiamboris
- 18:23(;
- cosacam1
- 20:53My IDE is RedEditor-11 (Notepad++) I always run (interpret) my program with the blue play button, and only when it's already tested I compile it with the other button (the one with a gear). However, I installed today the most recent version of Red and when I use the play button to interpret the code it shows a window telling me that the Console process is still running. I click the Kill button and the message closes. When I press run again, it happens the same. It didn't happen with my previous Red version which was 0.6.4 July 25. Any idea?
- hiiamboris
- 21:03run it from the terminal and look at the output
- cosacam1
- 21:17it runs fine from the console. The question is how do I make Notepad++ to use the previous version of Red?
- hiiamboris
- 21:21maybe some notepad++ users will read this chat
- cosacam1
- 21:22Ok, I gotta go. I will try next week. Have a happy week-end everybody.
- greggirwin
- 22:20@cosacam1 I haven't looked at my NP++ config here, as I rarely fire it up. I did have to reprogram everything in UltraEdit with the change in the Red exes.
- koba-yu
- 05:51Hi, are there any defined / conventional methods to check the code is running under console or compiled executable? I guess I saw some before but cannot remember now...06:01Ah,
system/state/interpreted?
maybe?
- hiiamboris
- 06:43@dockimbel should know a proper way ;)
- koba-yu
- 06:46@hiiamboris
Thank you. system/state/interpred?
seems working so far. I'll keep in mind the way you taught too.
- hiiamboris
- koba-yu
- 08:16I have pushed a new repo to GitHub. I appreciate if you have some coding advice or something like that. I want to write another personal blog post for this later.
https://github.com/koba-yu/red-image-viewer
- hiiamboris
- 08:25instead of interpreted, check for
attempt [system/console/gui?]
for your case08:25I also suggest scaling the image so it fits the window08:27also after a few images it stopped updating the display, apparently got some decoding error and stalled on it (make it recover from errors ;)08:29also it just crashed my console ;) but this I will deal with myself... interesting, as well as that decoding error
- koba-yu
- 09:00@hiiamboris Thank you, Il’ll check👍
- hiiamboris
- 09:22okay it's an out of memory related crash09:23basically 5-7 photos is the limit before it reaches 2.2GB ;)09:35@koba-yu I think that's because you reload all images on every
next
click09:36(even though a single image doesn't fit the screen)
- koba-yu
- 09:40@hiiamboris
Thank you, actually I made this app for viewing many small images for my AI related work. So the program not considered deeply to process big image at current commit 😅
I would keep improving!
- hiiamboris
- 09:45:+1:
- bubnenkoff
- 08:39
foo: function[name /extern name] [
name: to-word name
prin "inside function:" probe name
]
foo 'fooo
probe name
Should name become available outside foo? I am getting an error: *** Script Error: name has no value
- hiiamboris
- 08:40I think this should raise an invalid spec error. @dockimbel ?
- bubnenkoff
- 08:52How it's correct to say: "word do not become global available" or "word do not binded to global context"?
- hiiamboris
- 08:55"is not bound to the global context" is more to the point, but we'll understand either way
- rebolek
- 09:00Agreed,
[name /extern name]
should raise an error.
- bubnenkoff
- 09:25I have got a question about my code:
https://gist.github.com/bubnenkoff/8b6e3846f56c8060dc2a9acb3b23dd61
Even on this tiny example I am getting blinking on operation on data adding\removing (copy-paste to red and push add buttons). On bigger data structure the blinking become more annoying and time delays become bigger.
it's error in architecture? and it possible to do it fast, or it's feature of VID? And it's not possible to solve it?
- gurzgri
- 09:26@bubnenkoff Anyways, do yourself a favour and try harder to do without
/extern
words in functions. Your future debugging self will be grateful … ;^)
- bubnenkoff
- 09:29> @bubnenkoff Anyways, do yourself a favour and try harder to do without
/extern
words in functions. Your future debugging self will be grateful … ;^)
You mean that I should to prefer func
when I there is no any other reason to make all data local?
- gurzgri
- 09:34Re: blinking - Sounds like you‘re relayouting the whole layout instead of adding/modifying/removing only the faces with actual changes.09:41Re: No, the other way around. Try harder to let functions only work on the „outer world“ thru passed arguments and return values only instead of modifying words from outer contexts in functions. Way harder to avoid unwanted side effects if functions modify „random“ things, and harder to test too. You can not easily test a sinhle function that way and can‘t depend that the outcome of a function is dependend on the arguments only instead of random other application state.09:43*sinhle = single, *can‘t depend … = can‘t rely on the outcome of s function being dependend …
- bubnenkoff
- 09:46
Re: blinking - Sounds like you‘re relayouting the whole layout instead of adding/modifying/removing only the faces with actual changes.
But in code I am updating data (removing and adding) only to panel (ppp
).>
- hiiamboris
- 09:48I suggest instead of assigning a new
pane
, modify the old one.
- gurzgri
- 10:00This. Another obvious improvement would be having each nesting level in a
panel
of it's own. That way you can easily get indention for free and have finer control on what is changed / needs to be redrawn. And a panels vertical offset and size could easily be calculated using reactivity then, depending on offset. But the key point really is not creating everything for every change. 10:04append ppp/pane layout/only
is the culprit. It re-creates each and every face on every change. You'd be better off creating faces manually with make-face
instead of creating a full VID layout spec of the entirety of faces each time something gets added/removed.
- hiiamboris
- 10:06also this
ppp/pane: copy []
;)10:14on panels, it's a good advice to simplify code management, but changing offsets does seem to cause any flicker: view compose/deep [panel 300x300 [(loop 50 [append [] compose [at (random 270x270) field (random white) 30x30 rate 70 on-time [face/offset: max 0x0 min 270x270 face/offset - 2 + random 3x3]]])]]
- gurzgri
- 10:38No one *said* re-offsetting faces causes the flicker ;)
- hiiamboris
- 10:41sure, just clarifying :)
- Boum69
- 17:09Is it possible to use on Windows a non installed font with VID ? Same question with Rebol please. 😉
- hiiamboris
- 18:01@qtxie might know
- rebolek
- 18:06AFAIK it's not possible
- bubnenkoff
- hiiamboris
- 18:07convert to block
- greggirwin
- 18:08Native widgets require installed fonts. I think even under R2 they had to be installed in the system, because Rebol still used the OS for drawing, just selecting them into a DC I imagine.
- Boum69
- 18:19Ok , thanks all of you. I've spent a few hours to find a solution. Now, I know I is not possible for the moment unless @qtxie had a solution ?
- gurzgri
- 21:30@bubnenkoff I have put something together along the lines of your key:value editor, see the code at https://gist.github.com/gurzgri/895e8f3f5fe1caf16279725138567389
* using panels there for easier implementation of nesting levels / indention
* dynamically created faces with make-face
* still some flickering, but limited to the tree level just edited (probably related to using OS widgets)
* added vertical / horizontal scrolling with scrollers and by mouse wheel
* added a load-from block / save-into block mechanism
Have fun studying (for more improvements probably ask @hiiamboris)!
- hiiamboris
- 21:38Great as always, @gurzgri :clap:
- greggirwin
- 22:19Indeed. Very nice @gurzgri. I get errors on the save button, and
hint
for those would be helpful. :^)
- gurzgri
- 22:47Thanks to both of you. Argh, it's always these simple last minute name changes ... fixed. Re: Hints - Yes indeed, thanks for the hint ;) 22:49My idiom of the day btw is
add silver random coal
, I'm sure I never picked a random pale color that way before :) 22:54@hiiamboris How to let root/offset
react on the two scroller's data
instead of setting it thru their on-change
actors, any idea? Didn't managed to do so.
- ldci
- 02:36@Boum69. For fonts testing: https://github.com/ldci/Red-System/tree/main/Fonts
- Boum69
- 03:26Good morning ; ) and thank you @ldci .
- hiiamboris
- 07:22> @hiiamboris How to let
root/offset
react on the two scroller's data
instead of setting it thru their on-change
actors, any idea? Didn't managed to do so.
I just replaced on-change
with react
in your code and it works for me @gurzgri
- gurzgri
- 07:54Oh, thanks man! This is interesting, I‘ve tried adding it as
react later
to the root
face (because it seemed to make more sense over there too me, it‘s root
reacting to the scrollers). Will have a deeper look this evening.
- hiiamboris
- 07:56Objects must exist at react's block parsing time
- gurzgri
- 08:21Makes sense. I assumed
later
to deal with that since it didn‘t complain.
- hiiamboris
- 08:23
later
just skips initial reaction evaluation08:24But it retrieves all reactive sources at parsing time anyway
- bubnenkoff
- 09:06
mmm: #(
test: [
foo: function [value] [
print ["value: " value]
]
]
)
mmm/test/foo 'hello
I am trying to call function foo
what I am missing?
09:08> @bubnenkoff I have put something together along the lines of your key:value editor, see the code at https://gist.github.com/gurzgri/895e8f3f5fe1caf16279725138567389
> * using panels there for easier implementation of nesting levels / indention
> * dynamically created faces with make-face
> * still some flickering, but limited to the tree level just edited (probably related to using OS widgets)
> * added vertical / horizontal scrolling with scrollers and by mouse wheel
> * added a load-from block / save-into block mechanism
> Have fun studying (for more improvements probably ask @hiiamboris)!
Wow!!! Thanks! Looks perfect!
- hiiamboris
- 09:12inspect your block, values of what types do you have there?
- bubnenkoff
- rebolek
- 09:18> what I am missing?
You are missing the basic rule of Redbol languages - everything is data until it's evaluated. Try length? mmm/test
. I guess you expect it to be 2 but you'll be surprised that it's 4. Why is that? Because the block!
assigned to test
wasn't evaluated.
- dockimbel
- 09:27> I am trying to call function foo what I am missing?
There is no "function foo", it does not exist, that's why you can't call it.
- bubnenkoff
- rebolek
- 09:30Yes, you need to reduce, but let's ask first, why do you have such structure? Function in a block in a map? Just because it's possible doesn't mean you should do it.
- bubnenkoff
- 09:33@rebolek because I am writing rules for processing data and every I put every possible operation on data in such structure09:36
mmm: #(
test: [
foo: function [value] [
print ["value: " value]
]
]
)
reduce mmm/test foo "hello"
this works
- rebolek
- 09:37Yes, but is this structure really the best structure for the task?
- bubnenkoff
- 09:41The problem of code above that
foo
become available in global context. Is there any way to prevent it.
@rebolek one moment I will explain what I am doing on better example
- rebolek
- 09:42> The problem of code above that foo become available in global context. Is there any way to prevent it.
Of course. Don't use function in a block in a map, use a function in a context.
- bubnenkoff
- 09:44@rebolek Example:
notifications_section: #(
KBKCode: [ ; tag for checking
action: function [value] [
x: none
result: rejoin parse value [collect some [ digit | keep skip ] ] ;
if not empty? result [x: result]
return x
]
dist: 'KBKCode_letter ; tag for saving result
]
)
The idea is next. Some sections have tags that require some manipulation and saving result to other tag.
- hiiamboris
- 09:47> Is there any way to prevent it.
Walk backwards. Write down how the resulting block should look like, then figure out what to do with the source block to achieve that.
- bubnenkoff
- 10:00> > The problem of code above that foo become available in global context. Is there any way to prevent it.
>
> Of course. Don't use function in a block in a map, use a function in a context.
your are suggesting structure like:
mmm: [
test: context [
foo: function [value] [
print ["value: " value]
]
]
]
- rebolek
- 10:19for example
- bubnenkoff
- 10:34> In Rebol2 and Red, contexts can be extended only by cloning operation (
make
), in Rebol3, object can be extended using series actions. I was not for that change, as it was blurring the lines between objects and series (not even mentioning maps). I personnaly had no need for expandable objects, just maybe for some specific cases, where reconstructing the whole objects with the right binding would have been too expensive/complex. So I was in favor of just an extend
native, which would allow extending objects in-place (and would work only on objects, so avoiding confusion with series). In Red, I plan to add extend
, though, it would probably make objects access path compilation much less efficient a priori, so I need to find a way to avoid the speed penalty for that first.
Do I understand correctly that nothing has changed since then and you can only create a fill object at creation?
- hiiamboris
- 10:48Yes
- bubnenkoff
- 12:32
complex-obj: make object! [
notifications_section: [
tag1: [
action: function [value] [ print ["some operation: " value ] ]
dist: 'KBKCode_letter
]
]
]
Can't understand to make tag1/action binded to context of object.
this code is make action is available from global context:
reduce complex-obj/notifications_section/tag1 action "hello"
- hiiamboris
- bubnenkoff
- 12:50> same as this:
>
> >> o: object [ [x: 1] ]
> == make object! [] ;) oh look! no X!
>
notifications_section and tag1 should also be objects in my example? 12:57
complex-obj: object [
notifications_section: object [
tag1: object [
action: function [value] [ print ["some operation: " value ] ]
dist: 'KBKCode_letter
]
]
]
aaa: reduce complex-obj
bbb: reduce aaa/notifications_section
ccc: reduce bbb/tag1
ccc/action "hello"
Could this reduce chain be simplified?
- hiiamboris
- 12:58Like I said:
> Walk backwards. Write down how the resulting block should look like, then figure out what to do with the source block to achieve that.12:59You have at this moment no idea what you're even doing. Just randomly adding stuff.13:01You're not an [infinite monkey](https://en.wikipedia.org/wiki/Infinite_monkey_theorem), you cannot afford billions of years for this task ;)
- bubnenkoff
- 13:04This moment I understand) But I have doubt about how result block should look like, because I need to simplify it's creation and stay it's isolate
- hiiamboris
- 13:45Always start simple, and only extend it when there's no other way
- greggirwin
- 17:01@bubnenkoff to @hiiamboris' point, there is a big risk in trying advanced things, which you can't solve yourself, and getting help here. We all do want to help, but if you don't take the time to *really* understand things, you may end up in a situation where you can't maintain the code you have because you don't understand it.
I imagine most of us will agree that Boris' advice to "start small" is good. Don't just use your existing code to understand. Use generic bits. Get to really understand blocks, objects, maps, and evaluation, including what context words are bound (set) to.
- cosacam1
- 17:50@bubnenkoff Do you understand Object Oriented Programming? In Rebol/Red or other language? If not, we can help.
- bubnenkoff
- 18:23@greggirwin thanks, I will try)
@cosacam1 yes, I understand, but I think that OOP in Red is significantly difference from other langues
- cosacam1
- 19:14Not too much. Basically, there are no classes and instances, only objects. They have attributes and methods i.e. variables ,(actually words) and functions. Use those vars and functions asv regular ones just remembering they are members of (bibded to) the object.19:27Typo: Not bibded but binded19:54Objects can be made with
make object!
or copied from other object as in john-alias: copy john
where every change in john will be reflected in john-alias. Finally objects can inherit attributes and methods from other object or objects (multiple inheritance) as in other-person: make proto-person
- bubnenkoff
- 09:32What is the difference between language and set of functions like
foo
bar
baz
? Why foo
bar
baz
not yet a language?
- hiiamboris
- 09:40Who said it's not? ☻
- bubnenkoff
- 10:28@hiiamboris they are? Really?
- hiiamboris
- 10:40Sure10:40There exists a language without words, just spaces, new-lines, tabs, etc.10:42If you can describe data with that, it's a language.10:42You can communicate using it.10:42With PC or humans (if they're nerdy enough).
- bubnenkoff
- 10:49But when people are write such functions they are not saying that they are wrote own language
- hiiamboris
- 10:53Perhaps because it was not their intention to communicate with these functions? ;)
- bubnenkoff
- 11:04But then when language become DSL? When foo bar baz solve only domain specific task?
- hiiamboris
- 13:39If it's not general purpose, it's domain specific
- greggirwin
- 18:10It's a gradient between functions/libraries and languages.
Fluent interface
is a modern term as well. We can say that add/subtract/...
are domain specific, because they can behave differently given their arguments, but that's for the language to decide, and also pulls polymorphism into the discussion.
For me, it's less "language" if it always takes the same set of arguments, and those arguments are positional or strictly named. Language allows more flexibility in how to express things and define new extensions to it.
- cosacam1
- 22:23So sql, html, prolog, cobol, gml aka game maker language are DSL, right?
- greggirwin
- 22:46That changes the aspect to general purpose versus domain specific. Also domains versus paradigms. e.g. prolog is a logic language by paradigm, but general purpose at the same time.
- bubnenkoff
- 08:38Oh... after 2 years I decided to try understand
bind
ing again:
users: [foo bar baz]
names: ["Piter" "Mike" "Jow"]
foreach u users [
bind users object compose [(to-set-word u) (take names) ]
]
reduce users
And it seems that it's works:
>> reduce users
== ["Piter" "Mike" "Jow"]
08:43Am I right understand meaning
of word require rebinding. Because I tried to change names and print them with reduce users
and got old results
- hiiamboris
- 08:54What exactly have you tried?
- bubnenkoff
- 09:07I have added after code above next code:
names: ["Apple" "Banana" "Carrot"]
reduce users
I expect: ["Apple" "Banana" "Carrot"]
as output but got: == ["Piter" "Mike" "Jow"]
- hiiamboris
- 09:17
>> block: [1 + 1 2 * 2]
== [1 + 1 2 * 2]
>> result: reduce block
== [2 4]
>> block: [2 + 2 3 * 3]
== [2 + 2 3 * 3]
>> result ;) do you expect it to be [4 9] ?
- bubnenkoff
- 09:26result is still point to
block: [1 + 1 2 * 2]
here.
But I still can't understand difference between simple setting word with word:
and binding. It seems that they are do same things
- hiiamboris
- 09:26My example is no essentially different than yours.09:26You've created an object from values in a block.09:26Then created a new block with new values.09:27What does the object have to do with these?09:37
>> change block 5
== [+ 1 2 * 2]
>> block
== [5 + 1 2 * 2]
>> result
== should be [6 4] you say?
- bubnenkoff
- 09:47change is changing original, so
7 9
(and I checked in console)09:48
>> :block
== [2 + 2 3 * 3]
>>
>> change block 5
== [+ 2 3 * 3]
>>
>> :block
== [5 + 2 3 * 3]
>> reduce block
== [7 9]
- hiiamboris
- 09:48But you're cheating by reducing it *again*09:49
>> block: [2 + 2 3 * 3]
== [2 + 2 3 * 3]
>> result: reduce block
== [4 9]
>> change block 5
== [+ 2 3 * 3]
>> result
== will it be [7 9] ?
- melcepstrum
- 10:46I need help. How to change a red value in a red-system code10:51I have something like this
Red []
#system [
pv: declare float-ptr!
]
c: routine [ vec [vector!] ] [
pv: as float-ptr! vector/rs-head vec
]
p: make reactor! [
v: make vector! [1.0 2.0 3.0]
i: 1
f: 0.1
s: "red"
]
print p
c p/v
#system [
pv/1: 5.0
]
print p
10:57now I want to change int, float and string values from red-system side
- hiiamboris
- 11:00for string look in datatypes/string.reds for some function that works for you11:01it's encoded using one of 1,2 or 4-byte encodings (in your case 1-byte)11:02for int/float, these are not series, so you're gonna change the object instead11:03similarly, look for a function in datatypes/object.reds (or context.reds)
- melcepstrum
- 11:49thanks. I think it's too hard for me :) I was hoping for an example code ;)
- hiiamboris
- 11:51let's start with what do you want to achieve with this? ;)
- melcepstrum
- 12:00i'm writing a small app that do some sound processing
- hiiamboris
- 12:01and why does it need access to anything other than vectors?
- melcepstrum
- 12:02to signal red when buffer is ready
- hiiamboris
- melcepstrum
- 12:04also to get device-name from portaudio and display that in gui12:06ok, but i have to set that flag in red-system
- hiiamboris
- 12:06yes of course
- melcepstrum
- 12:06and routine is called in red
- hiiamboris
- 12:07but it will return Red logic! value12:07routines automatically convert (box) scalars into Red datatypes
- melcepstrum
- 12:08i think it won't work for me
- hiiamboris
- 12:08why?
- melcepstrum
- 12:09sound is processed in red-system function
- hiiamboris
- 12:10I understand that12:10why can't it process it and return readiness flag as Red logic value?12:11and for device name, don't mess with the objects, just return the string:
get-device-name: routine [return: [string!]] [
devname: ... get the name from port-audio ...
string/load devname length? devname UTF-8
]
- melcepstrum
- 12:11ok thanks
- hiiamboris
- 12:13example code:
get-device-name: routine [return: [string!] /local devname [c-string!]] [
devname: "test-name"
string/load devname length? devname UTF-8
]
probe get-device-name
- melcepstrum
- 12:15thanks :)12:16and the sound processing loop is a callback in red system
- hiiamboris
- 12:16well in your Red code you will have to *do something* to test the flag anyway, so call a routine to check the flag, which is set from the R/S callback
- melcepstrum
- 12:18can't this be triggered from the r/s side ?
- hiiamboris
- 12:20it can, with more work, but what's the point?
- melcepstrum
- 12:23i had an idea that it will trigger an event
- hiiamboris
- 12:26ok let me cook smth up12:51
Red []
r: reactor [red-flag: off]
react/later [print ["changed to:" r/red-flag]]
#system [
marked-word: declare red-word!
]
mark: routine [word [word!]] [
copy-cell as cell! word as cell! marked-word
]
flip: routine [/local logic [red-logic!]] [
logic: as red-logic! _context/get marked-word marked-word/ctx
logic/value: not logic/value
_context/set marked-word as red-value! logic
]
mark in r 'red-flag
flip
flip
flip
print "finished"
- melcepstrum
- 12:59thanks :) that's very helpful
- hiiamboris
- 13:01you're welcome
- cosacam1
- 07:11Hi. I've been using Notepad++ now I'm moving to VSCode for the first time. I want to install Red plugin for VScode. I go to https://github.com/red/VScode-extension and it says there I must download the Red binaries to a local folder (I did it), then set the red.redDir to it. Where do I do that? Remember, first time in VSCode. Thanks
- riprwwa
- 08:46You can go to File / Preferences / Settings, where you will be able see a long list of settings. Then either type "red." in the small search bar at the top of that window to filter them down, or expand the category tree in the settings window and look under Extensions for a node called "Red".
- cosacam1
- 09:25What do you suggest? To use IntelliSense or not? What is it good for?09:36I already learnt about IntelliSense. I'll use it. Ok Thank you very much @riprwwa 09:53I wrote that little program to test VSCode. Run it. Doesn't show a window with a button but prints Hola mundo in the console instead, at the bottom of VSCode. Why?10:03Ok, the reason is I previously wrote Red [] print "Hola mundo" and run it ok, then in same file I wrote the code above but didn't save it (in Notepad++ when you run it you save it automatically) so vscode was running the previous version. Now I save it, run it and it says view has no value. Maybe I miss-configured the extension. Here it is10:07[](https://files.gitter.im/5780ef02c2f0db084a2231b0/xJWh/image.png)10:08What do you think?10:22[](https://files.gitter.im/5780ef02c2f0db084a2231b0/AsFe/image.png)10:22As you see, the paths are ok
- riprwwa
- 10:24Well... I'm going to assume the extension is wrongly trying to run that script using the red executable, instead of the red-view one.
Actually I can see it's running using red-.....exe instead of red-view-.....exe.
If you do CTRL+SHIFT+P in VSCode you will see all commands. Type "red", you should see something like "Red: Show all Red commands", and if you do that you will see there is another command there, "Run Current Script in GUI Console" - when I invoked that it worked.
There is another shortcut in VSCode: CTRL+K then CTRL+S. This shows you all keyboard shortcuts. Again, you can filter them by typing "red" or "gui" - that will show you CTRL+F6 runs your script using the GUI console.
- cosacam1
- 10:33Yes, it works with Ctrl F6. Thanks again
- ldci
- 14:11Question: I’ve s string of bits
o: {010110111011001111110110}
and I want a binary string but without changing the content s: #{010110111011001111110110}
- hiiamboris
- 14:17use
debase
14:19but it looks broken14:19:(14:19ah, it just expects integer number of bytes
- ldci
- 14:20@hiiamboris Thanks:)
- bubnenkoff
- 15:03Red have datatype:
dbl-quote
. I need to extend it:
dbl-quote: union dbl-quote {"}
But I am getting an error: Error: union does not allow char! for its set1 argument
15:04Would it be correct to to-string dbl-quote
?
- hiiamboris
- 15:07omg
- bubnenkoff
- 15:07What problem I am trying to solve:
remove-quotes: function [str][
; parse dst: copy str [ ; uncomment if modification of original do not required
parse dst: str [ ;
p-st: opt dbl-quote
some [not dbl-quote skip]
p-end: dbl-quote end
(if p-st/1 = dbl-quote [remove p-end remove p-st])
]
dst
]
dbl-quote: union to-string dbl-quote {"}
str: {"Apple Corp" some text}
remove-quotes str
print str
- hiiamboris
- 15:08have you tried
?
on it?
- bubnenkoff
- 15:09m... it seems that I did string not union
{""}
- hiiamboris
- 15:10on
dbl-quote
- bubnenkoff
- 15:10Yes I tried. It's a char
- hiiamboris
- 15:11so how is it a datatype?
- bubnenkoff
- 15:11it's a char!
- hiiamboris
- 15:12okay, and what result do you expect from such union?
- bubnenkoff
- 15:14And what I should to do in case above? To try to create unions? Or I am on wrong way?
- hiiamboris
- 15:15the only wrong about your way is not understanding what you want :)15:15so I'm asking you, what value do you want to get so it will work in Parse?15:16try to write it literally, then if that works, construct it programmaticaly
- bubnenkoff
- hiiamboris
- 15:40Do you understand what charset is and how parse will apply it to your input?15:45In other words, what are the examples of input that charset will and will not match?
- bubnenkoff
- 15:45Think yes, it's make bit-set.I tried to test:
special: charset {test}
parse {test} [some special]
== true
15:46now test
is bitset
- hiiamboris
- bubnenkoff
- 16:07Egh... it find one or some letters from bit-set that I created. So I wrote wrong code
- hiiamboris
- 16:14yes, you only need to match
"
and nothing else
- bubnenkoff
- 16:23It seems that I do not need to use unions because it not for my task.
I should write else condition like: p-st: opt [dbl-quote | {"}]
- hiiamboris
- 16:24:clap:
- bubnenkoff
- 16:25thanks)
- greggirwin
- 17:36Your confusion seems to have stemmed from not understanding that chars are single values, bitsets are multiple values (e.g. made from multiple chars in this context) with no order and no duplication, while strings are an *ordered* set of chars which can contain duplicates because they differ in their position.
You can create a bitset from a string, but it's a lossy operation because you throw away the ordering.
>> make bitset! #"A"
== make bitset! #{000000000000000040}
>> make bitset! #"a"
== make bitset! #{00000000000000000000000040}
>> make bitset! "Aa"
== make bitset! #{00000000000000004000000040}
>> make bitset! "AaAAAAaaAAaaaaaaAAAAAAAaaaaaaAa"
== make bitset! #{00000000000000004000000040}
- bubnenkoff
- 17:48Gregg, big thanks for example!17:48I remember that scroll is unfinished, but is it possible to get it work inside panel (or it should be outside?)?
view [
size 500x400
panel [
field
field
field
field
field
field
field return
scroller 470
]
]
- greggirwin
- 17:52Not implemented yet. Came up [here](https://gitter.im/red/red/gui-branch?at=63258fae7ccf6b6d45dc52d8) recently.
- luce80
- 18:15Also look at [this](https://gist.github.com/luce80/55bfd71f68716d6e996effa9b99f4a1e)18:33I am trying to ping @qtxie to fully implement the "nicer" version ;)
- Oldes
- 18:42@bubnenkoff I must recomend you to first decode all html entities before processing the input!18:44I have a codec for it in Rebol.. which you may port to Red if you wish https://github.com/Oldes/Rebol3/blob/master/src/mezz/codec-html-entities.reb
- greggirwin
- 18:46Good advice @Oldes.
- hiiamboris
- 18:47your list might be a bit short @Oldes ;)
https://html.spec.whatwg.org/multipage/named-characters.html
- bubnenkoff
- 19:06@Oldes Hi! Thanks!
- toomasv
- 08:44@bubnenkoff
view [
below
panel 400x25 [
origin 0x0
pan: panel [origin 0x0 field "1" field "2" field "3" field "4" field "5" field "6" field "7"]
]
scroller 400 on-created [
face/selected: 100% * face/size/x / pan/size/x
diff: face/size/x - pan/size/x
] [pan/offset/x: max diff min 0 to integer! pan/size/x * -1 * face/data]
]
- bubnenkoff
- 13:59Perfect! Thanks!
- toomasv
- 19:40You are welcome! Did you understand, what and why?
- bubnenkoff
- 05:11@toomasv yes, I understood your are calculation pan offset during scroll moving
- rebolek
- 07:43Re HTML entities. My CASTR package comes with full list of them (and converter also :) https://gitlab.com/rebolek/castr/-/blob/master/entities
- bubnenkoff
- 08:47Hi! I am back to panel problem, I forgot some syntax:
p: [panel []]
view [ do p]
it's not working. I want to declare panel outside view
- ldci
- 09:20@bubnenkoff Try with make face!
- bubnenkoff
- 09:25@ldci ok thanks,
But what I am missing here:
view [ p: panel blue [] button [ p/color: red] ]
why color do not change? I should use react to get it work?
- hiiamboris
- 09:30It's a bug. Report it.
- ldci
- 09:35It’s running for me :Red 0.6.4 for Windows built 24-Sep-2022/9:39:31+02:00 commit #487881e
- hiiamboris
- 09:43Confirmed, regressed between Sep 28 and Sep 30
- bubnenkoff
- 09:45heh) I really spend one hour thinking about what I am forgot again)
- ldci
- 09:45@hiiamboris Thanks :)
- bubnenkoff
- 09:50@hiiamboris done https://github.com/red/red/issues/5222
- hiiamboris
- 09:53:+1:
- bubnenkoff
- 09:58> @bubnenkoff Try with make face!
p: [panel []]
view [make-face p]
error: Error: VID - invalid syntax at: [make-face p]
- hiiamboris
- 10:00You should perhaps re-read what is visual inteface dialect and how it's different from normal Red instead of doing random stuff
- ldci
- 10:07
p: make face! [
type: 'panel offset: 0x0 size: 300x200 color: silver
]
win: layout []
append win/pane p
view win
- toomasv
- ldci
- 11:15@toomasv Fine
- bubnenkoff
- 11:19> Or
>
> p: [panel []]
> view p
>
Heh, I tried a lot of variants because I remember that it should be very simple, but not this) thanks)
- luce80
- 18:05I'd like to make a widget that is made as a group of 3 different
style
s , how can I accomplish that ? Should I use panel
or base
as template ?
- hiiamboris
- 18:13for native widgets, panel18:17you can again use my scrollpanel style as a point of reference
- cosacam1
- 22:21hi everyone, long time away from here, I've been very busy. How can I sync two text-list so when I scroll in one of them the other-one scrolls too. I mean using any means to scroll (scroller, wheel, arrow keys, whatever) I suppose it's related to events, but how can I get to each text-list's scroller so I can use the scroller's data. Thanks in advance
- hiiamboris
- 22:21only using R/S
- cosacam1
- 22:21ouch22:22that makes me compile every time I test my code22:23btw, has compiling improved it's performance?
- hiiamboris
- 22:23you don't have to compile often if you insert R/S code into your console itself22:23> btw, has compiling improved it's performance?
no it hasn't, but devmode (-c) was always fine, <1 sec
- cosacam1
- 22:26do you mean I can put some R/S code in my program and run it w/o compiling some times? I don't understand22:39what I've done so far is to select corresponding items in both text-lists22:42
view [
t1: text-list data [] [t2/selected: t1/selected]
t2: text-list data [] [t1/selected: t2/selected]
return
button "fill" [
loop 40 [
append t1/data copy random "qwertyuiop"
append t2/data copy random "1234567890"
]
]
22:43sorry, it needs one more bracket22:44
view [
t1: text-list data [] [t2/selected: t1/selected]
t2: text-list data [] [t1/selected: t2/selected]
return
button "fill" [
loop 40 [
append t1/data copy random "qwertyuiop"
append t2/data copy random "1234567890"
]
]
]
- ldci
- 05:02@cosacam1 Good approach :)
- ldci
- 06:22How to easily transform Red/System c-string! to a Red string?
- hiiamboris
- 08:26
string/load str length? str UTF-8
- ldci
- 08:36@hiiamboris Thanks a lot
- bubnenkoff
- 09:09Heh, I wrote buggy code and got StackOverflow. Do not know should it be marked as a bug?
a: #(a: 1)
f: function[] [
probe f
]
f
09:18And the second moment, it seems that there is regression. function
have func signature:
b: 1
f: function[] [
print b
]
f
is printing 1
instead of none
:
>> :f
== func [][
print b
]
- hiiamboris
- 09:19stack overflow is expected from that in all languages I know09:20why would it print
none
?
- bubnenkoff
- 09:22Oh... it seems that I am wrong
- cosacam1
- 12:34Hi. How can I set-focus to a field and make the caret be at the end of its text, not at the begining. Also, how to make all its text to be selected (blue) when focused. Thanks
- hiiamboris
- 12:56
view [f: field "text" button [set-focus f f/selected: 1x4]]
12:59view [f: field "text" button [set-focus f f/selected: 5x5]]
for no selection (but it's a hack)
- cosacam1
- 13:28Thanks. I tried also "textos" and 2x4. It selected from the second to the fourth chars. Clever Red. Thanks again @hiiamboris 13:44I think set-focus with /all and /part refinements would be nice applicable to field, area and rtf
- hiiamboris
- 14:13just write your own function for that
- cosacam1
- 15:37Yeap, as soon as I have electricity
- luce80
- 14:00How can I scale something in
draw
block **without** scaling the pen ? I tried with matrix
, scale
and transform
with and without 'pen
with no effect. P.S.: transform
perforns scaling after translation, is it by-design ?
- hiiamboris
- 14:02scaling applies to everything14:02just update line-width as well
- luce80
- hiiamboris
- 14:34I would assume that it applies to bitmap/gradient pens14:35I agree documentation is vague14:35Let's ask @dockimbel
- dockimbel
- 15:11Should be for scaling gradient and pattern pens and fill-pens. I agree that the documentation could be more accurate about that. @qtxie can confirm.
- luce80
- 15:17And how can I "counteract" a not unform scaling like
scale 20 10
?
- hiiamboris
- 15:23I think you can't. Neither this, nor skew.15:24>
transform
perforns scaling after translation, is it by-design ?
By the way I had the same questions when I read the docs. Transformations order is not documented.
- dockimbel
- 17:24@qtxie ^--- please document that.
- qtxie
- 23:48> How can I scale something in
draw
block **without** scaling the pen ? I tried with matrix
, scale
and transform
with and without 'pen
with no effect. P.S.: transform
perforns scaling after translation, is it by-design ?
transform
applies rotate
, scale
and translate
in order.
view [
base 300x300 draw [
transform 10 2 1.5 10x10
box 100x100 150x150
]
base 300x300 draw [
rotate 10 scale 2 1.5 translate 10x10
box 100x100 150x150
]
]
23:53> And what is the difference between scale
and scale 'pen
?
If it's a pure color pen, any transforms on it has no effect. You can see the effect only if scale 'pen
applies to bitmap/gradient pens.
- luce80
- 08:40Ok,
transform
applies **transformation matrix multiplications** in that order.
- bubnenkoff
- 13:46What I missing in next algorithm?
data-pointer: [
purchaseNumber: none
isGOZ: none
docPublishDate: none
responsibleOrg_inn: none
lots: [
mytag: none
lot: [
lotNumber: none
KBKCode: none
lotMaxPrice: none
customers: [
customer: [
customer_regNum: none
customer_fullName: none
]
users: [
user_regNum: none
user_fullName: none
]
]
foo: [a: none]
objects: [
bar: none
object: [
OKPD_code: none
OKPD_name: none
]
]
]
]
]
get-nesting-levels-as-map-list: function [] [
level: 0
tags-before: 0
nested?: false
mmm: copy #()
parent-name: none
walk: function[data-pointer /extern level tags-before parent-name] [
foreach [data-name data-value] data-pointer [
if none? parent-name [ parent-name: 'root] ;
either block? data-value [
mmm/(data-name): copy make map! compose [node-level: (level) tags-before: (tags-before) parent: (parent-name) ]
level: level + 1
if (level > mmm/(data-name)/node-level) [
print ["data-name:" data-name "parent-name:" parent-name]
mmm/(data-name)/parent: parent-name
parent-name: to-word data-name
]
mmm/(data-name)/node-level: level
walk data-value ;
level: level - 1
] [
tags-before: tags-before + 2 ; key and value
]
]
]
walk data-pointer
return mmm
]
probe get-nesting-levels-as-map-list
it's output:
data-name: lots parent-name: root
data-name: lot parent-name: lots
data-name: customers parent-name: lot
data-name: customer parent-name: customers
data-name: users parent-name: customer ; wrong parent should be: customers
data-name: foo parent-name: users ; wrong parent should be: lot
data-name: objects parent-name: foo ; wrong parent should be: lot
data-name: object parent-name: objects
Where am I wrong?
- hiiamboris
- 13:52Hard to say. Use probe or trace to find the point where first value becomes wrong, walk backwards from that.
- bubnenkoff
- 12:02Why I can't create next char?
>> #"^"
*** Syntax Error: (line 2) invalid char at #"^"
*** Where: case
*** Near : :delimiter-lex
*** Stack: load
- Oldes
- bubnenkoff
- 12:09thanks!
- greggirwin
- 18:53@bubnenkoff remember to check docs: https://github.com/red/docs/blob/master/en/datatypes/char.adoc They'll help a lot.
- cosacam1
- 17:23hi guys take a look at this code17:24a: context [
info: make map! [
name "ana"
age 10
]
m2i: func [m][info/name: m/name info/age: m/age]
]
b: copy a
c: copy a
probe a
b/m2i copy make map! [name "berta" age 15]
probe b
probe a
c/m2i copy make map! [name "carlos" age 20]
probe c
probe b
probe a
view [
t: text-list data []
button "Fill list" [
append t/data b/info/name
append t/data b/info
append t/data c/info/name
append t/data c/info
]
button "Show selected" [
probe t/data/(2 * t/selected)
]
]
`17:38I'm trying to append objects to the text-list data so I can use the selected object's properties even to save them in a json file. I know I can append the whole object, but in that case its methods would be appended and saved too, which I don't need, only its properties. That's why I use a map to hold the object's properties. I'm creating different copies of the prototype object however every new object overrides the previous ones although I'm using copy
. Why? Thanks.17:55"override or overwrite", I don't know what's the best word to express what I mean in English. Sorry
- hiiamboris
- 17:56Can you format the code?
- cosacam1
- 18:04I'll try. 18:04Red [needs 'view]
a: context [
info: make map! [
name "ana"
age 10
]
m2i: func [m][info/name: m/name info/age: m/age]
]
b: copy a
c: copy a
probe a
b/m2i copy make map! [name "berta" age 15]
probe b
probe a
c/m2i copy make map! [name "carlos" age 20]
probe c
probe b
probe a
view [
t: text-list data []
button "Fill list" [
append t/data b/info/name
append t/data b/info
append t/data c/info/name
append t/data c/info
]
button "Show selected" [
probe t/data/(2 * t/selected)
]
]
`
- hiiamboris
- 18:04shift+enter
- cosacam1
- 18:04oops. I did ctrl enter18:05
Red [needs 'view]
a: context [
info: make map! [
name "ana"
age 10
]
m2i: func [m][info/name: m/name info/age: m/age]
]
b: copy a
c: copy a
probe a
b/m2i copy make map! [name "berta" age 15]
probe b
probe a
c/m2i copy make map! [name "carlos" age 20]
probe c
probe b
probe a
view [
t: text-list data []
button "Fill list" [
append t/data b/info/name
append t/data b/info
append t/data c/info/name
append t/data c/info
]
button "Show selected" [
probe t/data/(2 * t/selected)
]
]
18:05voila!
- hiiamboris
- 18:06:clap:18:06tried
copy/deep a
?18:07copy
has some weird semantics, making a shallow copy + functions + maybe smth else
- cosacam1
- 18:09copy/deep gave me same result. do you want to see the output?
- hiiamboris
- 18:09no, I'll test here
- cosacam1
- 18:10thanks anyway. someone else has any idea?
- hiiamboris
- 18:13so this is yet another quirk in maps18:13maybe you should just use block instead of map?18:14or replace the whole map?18:15https://github.com/red/red/issues/321818:15https://github.com/red/red/issues/2167
- toomasv
- 17:42Has such error appeared before?
*** Script Error: path element > only < does not apply to function! type
*** Where: eval-path
What does it mean?
I have function with refinement /only typ [word!]
, and I get this error in compiled script on invocation of the function. No error when interpreted.
Here is signature of the function:
set-col-type: function [face [object!] event [event! integer!] /only typ [word!]][...
- greggirwin
- 17:51Some path evaluation changes were made not long ago, mostly related to objects. Need to test on an old compiler, say from August, to see if it occurs there.
- toomasv
- 18:06Tried both with latest and with
30-May-2022/9:33:18+02:00 commit #e633c9a
. Same for both.
- greggirwin
- 18:13Hmmm. No error here.18:18Ah, failing silently here it seems.18:24Nope, I was wrong, it seems fine. 18:26Compiling with redc.exe from 20-Oct-2022.18:26Looks like something deeper is at play.
- toomasv
- 19:06Yeah, when I remove this invocation, I get next one:
*** Script Error: path element > with < does not apply to function! type
about next function.
- luce80
- 19:09How can I make
form
keep the number of decimals I want ? that is instead of:
>> form 10.0
== "10.0"
this:
>> form-or-other-func 10.0
== "10.00" ; or "10.000"
instead of:
>> form 0.000001
== "1.0e-6"
this:
>> form-or-other-func 0.000001
== "0.000001"
Can you suggest a simple function ?
- ldci
- 19:12Use round/to before form
- hiiamboris
- 19:15Float formatting and simple can not belong to the same sentence ;)
- greggirwin
- 19:15@ldci that won't pad zeros on the right. Someday we'll get
format
as standard. In the meantime, @luce80, you'll have to use the experimental formatting work from me or @hiiamboris.
- hiiamboris
- 19:17lvl1: https://codeberg.org/hiiamboris/red-common/src/branch/master/format-number.red
lvl2: https://codeberg.org/hiiamboris/red-common/src/branch/master/format-readable.red
lvl3: https://github.com/red/red/pull/5069
- luce80
- 19:21lvl1 is very nice !
- hiiamboris
- 19:23but has biggest number of edge cases ;)
- luce80
- hiiamboris
- 19:49you already have it in lvl2
- luce80
- 19:10lvl0: (no edge cases considered ;) )
pad-decimals: func [
"Pad FORMed number decimals to given precision"
num [integer! float!] precision [float!]
] [
num: form (round/to num precision) + (precision * 0.1)
copy/part num (length? num) - 1
]
- hiiamboris
- luce80
- 19:40and what about this ? :
>> pad-decimals 10.0 1.0
== "10."
Did I say no edge cases considered ? In fact I do not think I will use it, too low level ;)
- ne1uno
- 19:50https://gist.github.com/toomasv/006aaa95a0da02844916451fce8a6fcf#file-form-to-red I think it needs a fix after more recent changes,
head pad ...
19:51or maybe return head number
- greggirwin
- 20:30:point_up: [this](https://gitter.im/red/help?at=63617042aa210536d63b9622) :^)
- toomasv
- 06:38@ne1uno Thanks, changed! ... Although
?? pad
still claims return: [string!] "Modified input string at head"
.
- ne1uno
- 13:46@toomasv, could be that
find
is what changed?
- bubnenkoff
- 15:54Could anybody to compile next app with
-r
flag and do click on start and start2 ten times
https://gist.githubusercontent.com/bubnenkoff/78ace5972fe501993e480e6ba6f3c385/raw/064a2cbc96119c4217e2892ab39bf625cdfeb89e/app.red
D:\code\test_grow_red> .\stat_ui.exe
start
start
start
start
start
start
start
start
start
*** Runtime Error 1: access violation
if no compile no error
- hiiamboris
- 17:26in what order we should click these? at random?
- bubnenkoff
- 17:28Random
- hiiamboris
- 17:29crashes indeed, some View heisenbugs probably17:31@bubnenkoff can you eliminate View and see if it still crashes?17:32well, probably won't work, since even if compiled with
-r -d
it doesn't crash already17:35but worth trying! because it will be hard to find the bug like this17:43-c
mode broken?17:43crap18:04nevermind @bubnenkoff I minified it to
Red [needs: 'view]
view [
ppp: panel 300x400 []
return button "kill me" [loop 100 [ppp/pane: layout/only [button "abc"]]]
]
- greggirwin
- 20:37So is
-c
mode broken @hiiamboris ?
- hiiamboris
- 20:48nah, it was just an eternal issue https://github.com/red/red/issues/4249
- greggirwin
- 21:54Whew!
- bubnenkoff
- 06:37@hiiamboris sorry, I was go away from PC
- bubnenkoff
- 11:45Am I right that currently impossible to change default button color?
view [ button [ face/color: red] ]
- hiiamboris
- 12:08Text color changes, background is not supported by the OS
- bubnenkoff
- hiiamboris
- 12:17because you're not changing text color12:18try
view [button pink green "abc"]
- bubnenkoff
- hiiamboris
- 12:21first color goes to background in VID12:22but in button's case remains unused
- cosacam1
- 04:14hi there. How to use get-scroller? Thanks
- hiiamboris
- 09:51There's a search function on the panel on the left
- bubnenkoff
- 15:58I need way to make color accent to button could anybody give any suggestion? I tried to use
base
before button, but I do not like how it's look like 15:59[](https://files.gitter.im/5780ef02c2f0db084a2231b0/wAbg/izobrazhenie.png)
- hiiamboris
- 16:11use base in place of a button?16:14or draw a frame around it?16:14or on top of it?16:19
view [button 80x25 "OK" at 10x10 box 82x24 draw [pen magenta line-width 3 box 3x1 79x23]]
- bubnenkoff
- 17:46But I am generation button dynamically, and I do not know it's size because they can different text, so I can't set
box
size and at
.
- hiiamboris
- 17:48Everything VID does can be done in View
- bubnenkoff
- 17:50but how to draw box if I do not know it's size because I do not know length of text on button?17:51By generation I mean:
append ppp/pane layout/only compose/deep [
at (section-pos - 10x0) base 10x25 with [ color: (data-or-stat/(section-name)/(subsection-name)/color) ] at section-pos button (rejoin [to-string subsection-name ": " data-or-stat/(section-name)/(subsection-name)/filled-count] )
]
17:52to draw box around it like on your example I need to know it's size
- hiiamboris
- 17:55you can read button's size after it was shown
- bubnenkoff
- 09:48I found mention in help-in-red.pdf:
group-box
From documentation: A group-box is a container for other faces, with a visible frame
around it. This is a temporary style which will be removed once Red has the support
for edge facet.
Is there any updates on edge face support?
- hiiamboris
- 10:00nope
- bubnenkoff
- 10:05Am i right understand that group-box and just a panel with text label?
- hiiamboris
- 10:21it's an OS widget10:22basically, Red just gives a flag to the OS that it should have a label10:27in fact group-box is a button under the hood in Windows
- bubnenkoff
- 10:49Only button? WoW!
What is the right way to calculate child face size? I want to make tab-panel
take all available size. Setting same size is not good because child should be less then parent:
view [
size 1200x620
tab-panel 1200x620 [ ; I can set it less but I do not want to hardcode sizes of all elements
"Tab1" []
"General2" []
]
]
- hiiamboris
- 10:56default margin and spacing is 10x10
- bubnenkoff
- 10:58But is there any way to not hardcode elements size? And make UI size easier to modifying?
- hiiamboris
- 10:58use reactivity
- bubnenkoff
- 10:59You mean to calculate size reactivity?
- hiiamboris
- 10:59yeah
- bubnenkoff
- 11:09I did it:
view/flags [
panel green with [ react/later [ width: (first parent/size * 90%) height: (second parent/size * 90%) size: as-pair width height ] ] [
panel red []
]
] [resize]
green is stretchable. Could this code be improved? 11:10Maybe react
is better to put in outside function?
- hiiamboris
- 11:17
react
is supported by VID natively11:19also words width
and height
will leak, so you should better use as-pair
without the intermediate words, or put them into a function wrapper
- bubnenkoff
- 11:26I can't remember how to use external variables in VID:
tab-panel-size: 1000x500
view/flags [
size 1200x620
on-resizing [print "ddd"]
tab-panel do (tab-panel-size) [ ; here
"Tab1" []
"General2" []
]
] [resize]
11:27or only way is with
?
- hiiamboris
- 11:27compose too
- bubnenkoff
- 11:29
tab-panel-size: 1000x500
view/flags [
size 1200x620
on-resizing [print "ddd"]
tab-panel compose (tab-panel-size) [ ; invalid syntax at: [compose (tab-panel-size) ["Tab1" [] "General2" []]]
"Tab1" []
"General2" []
]
] [resize]
- hiiamboris
- 11:30compose is not a VID invention, it's a function
- bubnenkoff
- 11:33Than I do not understand how to use it in VID
- hiiamboris
- 11:35use it outside VID
- bubnenkoff
- 11:53What I am missing? Why red panel size do not changing?
base-window-size: 1200x620
tab-panel-size: function [] [
return base-window-size - 10
]
view/flags [
size base-window-size
on-resizing [ base-window-size: face/size ]
tab-panel red with [ react/later [size: tab-panel-size]] [
"Tab1" []
"Tab2" []
]
] [resize]
- hiiamboris
- 11:55
react
needs a _reactive source_11:55https://github.com/red/docs/blob/master/en/reactivity.adoc
- bubnenkoff
- 12:05
is creates a reactive formula whose result will be assigned to a word.
So I could do:
base-window-size: 1200x620
tab-panel-size: reactor [
is [base-window-size - 10]
]
?12:06And should base-window-size
be also reactive?
- hiiamboris
- 12:09reactive source is needed to *trigger* a reaction; what you do inside doesn't matter12:09also
is
is an operator
- bubnenkoff
- 12:12
base-window-size: 1200x620
tab-panel-size: reactor [
print "d"
is [base-window-size - 10]
]
view/flags [
size base-window-size
on-resizing [
base-window-size: face/size
tab-panel-size ; I need to trigger tab-panel-size: reactor here?
]
tab-panel red with [ react/later [size: tab-panel-size]] [
"Tab1" []
"Tab2" []
]
] [resize]
Can't understand how to trigger reactor
- hiiamboris
- bubnenkoff
- hiiamboris
- 12:18I gave you a documentation link12:18please read what is a reactive source12:18it's written black on white there
- bubnenkoff
- 12:48I reread it many times, I can only assume that
base-window-size
should be also reactive
- hiiamboris
- 12:50have you found what is a reactive source?12:50paste here12:51let's read it together :)
- bubnenkoff
- 12:53hah) I have only one idea that reactive source should be
base-window-size
but not it is not
- hiiamboris
- 12:55don't worry, paste the definition from the docs and we'll see
- bubnenkoff
- 12:55"A path! value referring to a field in a reactive object."12:57hm... object ... set word is not an object!
- hiiamboris
- 12:58"A **path!** value" - do you see this?
- bubnenkoff
- 12:58yes...
- hiiamboris
- 12:58do you have a path value in your
react
block?
- bubnenkoff
- 12:59no, so it should be an object and I should to link to
path
inside it?
- hiiamboris
- 13:01no idea what does it mean "link to path"13:01you understand what a path is?13:01give me an example
- bubnenkoff
- 13:01one moment
- hiiamboris
- 13:07yes good, that is a path to a field in a reactive object13:07by the way, every face is also a reactive object13:08now all you need is to give such path to
react
so it can watch it's changes13:09react
only scans the literal block you give it
- bubnenkoff
- 13:10
base-window-object: reactor [ size: 1200x620 ]
tab-panel-size: reactor [
size: is [base-window-object/size - 10] ; what is correct syntax here? should I add set word or it can be returned?
]
view/flags [
size base-window-size
on-resizing [
base-window-object: face/size
]
tab-panel red with [ react/later [size: tab-panel-size/size]] [
"Tab1" []
"Tab2" []
]
] [resize]
- hiiamboris
- 13:13this should work I think
- bubnenkoff
- 13:14Do not:
*** Script Error: VID - invalid syntax at: [base-window-size on-resizing [base-window-object: face/size]]
- hiiamboris
- 13:14but that's because you're not using compose13:14reactive part should be fine
- bubnenkoff
- 13:16
base-window-object: reactor [ size: 1200x620 ]
tab-panel-size: reactor [
size: base-window-object/size - 10
]
view/flags [
size base-window-size
on-resizing [
base-window-object: face/size
]
tab-panel red with [ react/later [size: compose (tab-panel-size/size)]] [ ; compose here? I am getting an error
"Tab1" []
"Tab2" []
]
] [resize]
13:17and it seems that error in:
Script Error: VID - invalid syntax at: [base-window-size on-resizing [base-window-object: face/size]]
13:17oh moment13:18I am seeing an error13:18
base-window-object: reactor [ size: 1200x620 ]
tab-panel-size: reactor [
size: base-window-object/size - 10
]
view/flags [
size base-window-size/size
on-resizing [
base-window-object/size: face/size
]
tab-panel red with [ react/later [size: tab-panel-size/size]] [
"Tab1" []
"Tab2" []
]
] [resize]
Again an error
- hiiamboris
- 13:20have you tried reading the error message? ;)13:22if so, you should consult VID's
size
command syntax13:22https://github.com/red/docs/blob/master/en/vid.adoc13:23you can paste it here too
- bubnenkoff
- hiiamboris
- 13:25and the next line in the docs?
- bubnenkoff
- 13:26"<value> : width and height in pixels (pair!)."
- hiiamboris
- 13:26see the **pair!** there?13:26do you give it a pair?
- bubnenkoff
- 13:27yes, but react should return
1200x620
in my code
- hiiamboris
- 13:27to hell with react13:27
base-window-size
is not a pair
- bubnenkoff
- hiiamboris
- 13:29
do
is not a pair either13:29what type is it?
- bubnenkoff
- 13:30here? Here should be a word
- hiiamboris
- 13:30great, we're getting somewhere13:30so
size
expects a pair, but you keep giving it a word
- bubnenkoff
- hiiamboris
- 13:32can you use compose outside of VID?
- bubnenkoff
- hiiamboris
- 13:38but
foo
is a word
- bubnenkoff
- 13:40hah)) 13:43I am somewhere near!
base-window-object: reactor [ size: 1200x620 ]
tab-panel-size: reactor [
size: base-window-object/size - 10
]
view/flags compose [
size (base-window-size/size)
on-resizing [
base-window-object/size: face/size
]
tab-panel red with [ react/later [size: tab-panel-size/size]] [
"Tab1" []
"Tab2" []
]
] [resize]
13:44btw syntax is still invalid
- hiiamboris
- 13:49:+1:
- bubnenkoff
- 14:38
view/flags compose [
size (base-window-size/size)
on-resizing [
base-window-object/size: face/size
]
tab-panel red with [ size: tab-panel-size/size] [
"Tab1" []
"Tab2" []
]
] [resize]
error: *** Script Error: VID - invalid syntax at: [none on-resizing [base-window-object/size: face/size]]
- hiiamboris
- 14:39figure out your typos
- bubnenkoff
- 14:42Oh indeed! Working example:
base-window-object: reactor [ size: 1200x620 ]
tab-panel-size: reactor [
size: base-window-object/size - 10
]
view/flags compose [
size (base-window-object/size)
on-resizing [
base-window-object/size: face/size
]
tab-panel red with [ size: tab-panel-size/size] [
"Tab1" []
"Tab2" []
]
] [resize]
- hiiamboris
- 14:43:clap:
- bubnenkoff
- 14:44one moment I need to check if it work as expected, because now working example is running example)14:48Not sure that it's work as expected:
base-window-object: reactor [ size: 1100x620 ]
tab-panel-size: reactor [
size: base-window-object/size - 20%
]
view/flags compose [
size (base-window-object/size)
on-resizing [
base-window-object/size: face/size
]
tab-panel red with [ react/later [size: (tab-panel-size/size)]] [
; tab-panel red with [ size: tab-panel-size/size] [
"Tab1" []
"Tab2" []
]
] [resize]
if I understood you right all faces is reactive by default, so commented and uncommented lines should work same?14:49But I do not seeing changing of red panel size on windows resize
- hiiamboris
- 14:51all faces are reactive, but that doesn't change the meaning of
with
14:51(which is only evaluated once)
- bubnenkoff
- 14:52hah) So is it still possible to get my code work?
- hiiamboris
- 14:55use
probe
to see what values get updated14:55you'll find where you broke it
- bubnenkoff
- 15:00
base-window-object: reactor [ size: 1100x620 ]
tab-panel-size: reactor [
size: base-window-object/size - 50
]
view/flags compose [
size (base-window-object/size)
on-resizing [
base-window-object/size: face/size
t/size: tab-panel-size/size
probe t/size ; but i size is not changing
]
t: tab-panel red (tab-panel-size/size) [
"Tab1" []
"Tab2" []
]
] [resize]
- hiiamboris
- 15:03indeed, what do you think will change it?15:03you have zero reactive relations defined
- bubnenkoff
- 15:08I have only idea that
on-resizing
should be somehow maked as reactive...15:09because:
base-window-object: reactor [ size: 1100x620 ]
tab-panel-size: reactor [
size: base-window-object/size - 50
]
should be reactable
- hiiamboris
- 15:09you know how to define a *reactive relation*?
- bubnenkoff
- 15:11If i understand examples right it should be:
on-resizing react [
base-window-object/size: face/size
probe t/size
t/size: tab-panel-size/size
]
But usually understand it wrong
- hiiamboris
- 15:12indeed, does
on-resizing
accept word for it's argument?
- bubnenkoff
- 15:12No
- hiiamboris
- 15:12but that's what you're giving it
- bubnenkoff
- 15:18Now I have no ideas...
- hiiamboris
- 15:19give it a block come on15:19you wrote correct relations an hour ago or so ;)
- bubnenkoff
- 15:26> I did it:
>
> view/flags [
>
> panel green with [ react/later [ width: (first parent/size * 90%) height: (second parent/size * 90%) size: as-pair width height ] ] [
> panel red []
> ]
> ] [resize]
>
> green is stretchable. Could this code be improved?
You are talking about this example?
- hiiamboris
- 15:28yeah this one too15:29and https://gitter.im/red/help?at=636cf8562cb65702401f067b
- bubnenkoff
- 15:35Even having examples I do not understand what I can took from them...15:36I have only stupid ideas like:
with react/later [
base-window-object/size: face/size
probe t/size
t/size: tab-panel-size/size
]
- hiiamboris
- 15:44in that case sleep on it ;)15:46you are clearly tired today
- bubnenkoff
- 16:08You are right. Just say me if I am on right way?
view/flags compose [
size (base-window-object/size)
on-resizing [ ; passing to resize react block
react/later [
base-window-object/size: face/size
probe t/size
t/size: tab-panel-size/size
]
]
t: tab-panel red (tab-panel-size/size) [
"Tab1" []
"Tab2" []
]
] [resize]
- hiiamboris
- 16:10you are
- bubnenkoff
- 16:13But face/size is not available there…
- hiiamboris
- 16:15indeed16:15maybe use VID's
react
instead of on-resizing?16:16or you'll have to make a *dynamic* relation (documented)
- bubnenkoff
- 16:20is it possible to use
react
? I am getting syntax error:
view/flags compose [
size (base-window-object/size)
react/later [
base-window-object/size: face/size
probe t/size
t/size: tab-panel-size/size
]
t: tab-panel red (tab-panel-size/size) [
"Tab1" []
"Tab2" []
]
] [resize]
- hiiamboris
- 16:26because you're not following the VID docs16:26there's no
react/later
syntax in VID16:26and it has to follow a face16:27doing random things again :)16:27good luck with that
- bubnenkoff
- hiiamboris
- 16:49actually, I'm mistaken, you can use
react
globally in VID16:49> This keyword can be used both as a face option or as a global keyword. Arbitrary number of react instances can be used.16:49then you just have to follow the documentation ;)
- bubnenkoff
- 17:57is seems that I should not call face from react, I should link by name. But on follow code react is do not do nothing (I checked with prints in it):
base-window-object: reactor [ size: 1100x620 ]
tab-panel-size: reactor [
size: is base-window-object/size - 50
]
view/flags compose win: [
size (base-window-object/size)
react later [
print "hello"
base-window-object/size: win/size ; I should not use face here
; probe t/size
t/size: tab-panel-size/size
]
t: tab-panel red (tab-panel-size/size) [
"Tab1" []
"Tab2" []
]
] [resize]
- hiiamboris
- 18:31what reactive sources do you see in your react block? how many?
- bubnenkoff
- 05:16> what reactive sources do you see in your react block? how many?
It seems that only one: tab-panel-size/size
win/size
is not react
- hiiamboris
- 08:54yes, and why?
- bubnenkoff
- 08:59I am continue fighting. I got it work and more or less understand how it works:
base-window-objects: reactor [
size: 1100x620
panel-size: is [size - 50]
]
view/flags compose [
size (base-window-objects/size)
on-resizing [
base-window-objects/size: face/size
t/size: base-window-objects/panel-size
]
t: tab-panel red (base-window-objects/panel-size) [
"Tab1" []
"Tab2" []
]
] [resize]
Question: is there any way to change panel size without linking to t
?
- hiiamboris
- 09:02of course, dynamic relations are documented at the link I gave you
- bubnenkoff
- hiiamboris
- 10:44> Percent is from the Latin adverbial phrase per centum meaning “by the hundred.”10:441 per cent means literally
1 / 100
10:44100 percent = 110:46%
sign visually denotes the denominator and the number of zeroes (2)
- bubnenkoff
- 10:51But how to get 80 as result ? %)
- hiiamboris
- 11:03use multiplication, Luke
- bubnenkoff
- luce80
- 19:04Just a thought. I feel a lot like @bubnenkoff when using reactions. I hope he will succeeds in his fight with them and will post the final result, hoping it will clarify that situation even for me.
- dsunanda
- 13:27Is there a way to set the user-agent string before doing a read http://.... ?
- hiiamboris
- 13:35no, it's hardcoded in the source unlike other headers:
https://github.com/red/red/blob/134698f686c200e24d420f28866c8aa03a8557c0/runtime/simple-io.reds#L164413:36@rebolek may know if it's possible in the IO branch though
- dsunanda
- 13:42Thanks. Not a big problem.
- pekr
- 18:35IO branch was supposed to undergo some architectural changes, IIRC, so I would not bet on its API.
- cosacam1
- 20:39About dmitry - hiiamboris chatting on reactors: I like hiamboris' style - He's teaching us how to fish rather than feeding us with fishes. We thank you.
- hiiamboris
- 21:34I appreciate you see the point @cosacam1 ☻21:34Indeed most useful learning skill is not to have the dots but to master how to connect them.
- cosacam1
- 06:05Several days ago I asked about get-scroller. I was suggested to search and I found a Toomas/hiiamboris example. However it doesn't work. It just shows a grey base with nothing in it.
Well, I made some changes, as follows:
- replaced base by panel and named it bg (background panel)
- removed the with section and located scrollable in same line of bg panel declaration
- also removed the pane: layout/only section as fg panel goes automatically in that pane
- renamed p panel to fg (forground panel)
- removed its default size so it gets high enough as to contain any widget in it no matter its size, as usually we do in VID
- changed areas sizes (actually I used a style) so each area doesn't fill the whole panel
- added more areas
- replaced size constants by their respective refinements in bg and fg
- added a diff variable to hold the height difference of both panels
I realized that event/key has right,left,page-right,page-left values instead of down,up,page-down,page-up as stated in the example.
(I guess an horizontal scroll-bar should use left,right,etc. values and a vertical one should use up,down,etc.)
So I finished up with the following script:06:06
view [
size 390x220
across space 0x0
bg: panel 367x200 scrollable [
origin 0x0 space 0x0
bg: panel [
style area: area 350x75
origin 0x0 space 0x0
below
area "A" area "B" area "C" area "D"
area "A1" area "B1" area "C1" area "D1"
area "A2" area "B2" area "C2" area "D2"
area "A3" area "B3" area "C3" area "D3"
]
]
on-created [
put get-scroller face 'horizontal 'visible? no
sc: get-scroller face 'vertical
sc/position: 0
sc/page-size: bg/size/y
sc/max-size: fg/size/y
diff: fg/size/y - bg/size/y
]
on-scroll [
if event/key = 'track [probe reduce ["before " event/picked sc/position]]
sc/position: max 0 min diff switch event/key [
right [sc/position + 20]
left [sc/position - 20]
page-right [sc/position + sc/page-size]
page-left [sc/position - sc/page-size]
track [event/picked - 1]
end [sc/position]
]
if event/key = 'track [probe reduce ["after " event/picked sc/position]]
p/offset: as-pair 0 negate sc/position
]
]
06:06Everything works fine except when I drag the thumb: the block associated to the track key is not working fine.
The thumb always returns to top position and the panel doesn't scroll at all.
As you see, I did probe event/picked and sc/position, before and after the switch. They are 0 all the time. Why?
BTW my Red build date is 9-Jun-2022/20:34:35 running on Windows 10. Maybe that matters.
Thanks.
- ldci
- 07:11@cosacam1 Tested with Red 0.6.4 for Windows built 7-Nov-2022/9:01:41+01:00 commit #134698f. But replace second bg name by fg and use fg/offset. Works fine:)
- cosacam1
- 07:38Thanks @ldci The typos you found are due to... typing the message here in Gitter but they are correctly typed in my IDE. I'll download Red's last version
- ldci
- 08:08Based on a code I found (I don’t know the author) you can also try
Red [
]
view [
across
panel 350x100 [
origin 0x0
pan: panel [
style area: area 350x75
origin 0x0 space 0x0 below
area "1" area "2" area "3" area "4" area "5" area "6" area "7"]
]
scroller 16x100 on-created [
face/selected: 100% * face/size/y / pan/size/y
diff: face/size/y - pan/size/y
] [pan/offset/y: max diff min 0 to integer! pan/size/y * -1 * face/data]
]
- toomasv
- 09:19@cosacam1
> I realized that event/key has right,left,page-right,page-left values instead of down,up,page-down,page-up
It seems vertical scrolling words are restored in later builds. At least I have these in Nov 7 Win build.09:22@ldci Was it working fine for you? I had to replace event/keys to vertical words with same build.
- ldci
- 09:24@toomasv Response too fast
- cosacam1
- 16:06This example is based upon a Toomas / hiiamboris code that uses get-scroller.
The original had neither on-wheel nor on-drag event handlers.
Drag works fine when the difference between panels' height is less than 700, else it gets stuck before reaching the bottom.
I guess it's a Red bug, correct me please if I'm wrong. Thanks.
BTW It happens the same when using a supllied scroller face (not those returned by get-scroller) in the many examples given in the forum (even one of my own)
16:06
Red [needs 'view]
view [
size 390x450
across space 0x0
bg: panel 367x400 scrollable [
origin 0x0 space 0x0
fg: panel blue loose [ ; use blue margin for dragging
style a: area 300x50
origin 0x0 space 0x0
below
a "A0" a "B0" a "C0" a "D0"
a "A1" a "B1" a "C1" a "D1"
a "A2" a "B2" a "C2" a "D2"
a "A3" a "B3" a "C3" a "D3"
a "A4" a "B4" a "C4" a "D4"
a "A5" a "B5" ; a "C5" a "D5" uncomment these and you'll get stuck when dragging
; a "A6" a "B6" a "C6" a "D6"
; a "A7" a "B7" a "C7" a "D7"
; a "A8" a "B8" a "C8" a "D8"
; a "A9" a "B9" a "C9" a "D9"
] with [size/x: size/x + 40] ; 40 :: show blue margin
on-wheel [
sc/position: max 0 min diff sc/position + either positive? event/picked [negate sc/min-size][sc/min-size]
fg/offset/y: negate sc/position
]
on-drag-start [system/view/auto-sync?: no]
on-drag [
unless system/view/auto-sync? [
fg/offset: as-pair 0 (min max negate diff fg/offset/y 0)
sc/position: negate fg/offset/y
]
]
on-drop [system/view/auto-sync?: yes]
]
on-created [
sc: get-scroller face 'vertical
put get-scroller face 'horizontal 'visible? no
td/text: to-string diff: fg/size/y - bg/size/y
either diff > 0 [
put sc 'visible? yes
sc/position: 0
sc/page-size: bg/size/y
sc/min-size: bg/size/y / 10
sc/max-size: fg/size/y
][put sc 'visible? no]
]
on-scroll [
sc/position: max 0 min diff switch event/key [
down [sc/position + sc/min-size]
up [sc/position - sc/min-size]
page-down [sc/position + sc/page-size]
page-up [sc/position - sc/page-size]
track [event/picked - 1]
end [sc/position]
]
fg/offset: as-pair 0 negate sc/position
]
return text "Panel's height difference " td: text
]
- hiiamboris
- 16:16ah, if only copy pasting from this stupid chat was so easy16:2016:21what must I do to make it stuck?
- cosacam1
- 16:22drag on the blue, not on the scroll bar
- hiiamboris
- 16:23I see16:24well I suppose
loose
has some limits?16:25I suggest using on-down/on-up/on-over events instead for this
- cosacam1
- 16:31ok, thanks. Any other suggestion, guys?
- bubnenkoff
- 12:33what is the good way to check first word letter if it any symbol from list?
data-key: '!foo
if ( find any [#"!" #"-"] (first to-string data-key) ) [print "modificator detected"]
error: find does not allow char! for its series argument
- hiiamboris
- 12:37your way is fine, just don't misuse
find
- bubnenkoff
- 12:40thanks! It seems that this way is work too
data-key: '+foo
if ( find [! - +] (to-word first to-string data-key) ) [print "modificator detected"]
14:10hm... is it possible to change spelling of set words here?
data: [
-key: "some text"
]
if ( find [! - +] (to-word first to-string key) ) [
data/:key: to-word (remove at to-string key 1)
]
probe data
to get:
data: [
key: "some text"
]
- hiiamboris
- 14:46you'll figure this out yourself
- bubnenkoff
- 14:54yes, right:
data: [
foo: "some text"
]
replace data 'foo (to-set-word 'bar)
probe data
out:
[bar: "some text"]
- hiiamboris
- 14:57:+1:14:57split big problem into smaller ones and solve these14:58exactly
- bubnenkoff
- 09:05@hiiamboris and what about map? Is it possible to change key name in map?09:10it seems the only way is remove old and create new one key
- hiiamboris
- bubnenkoff
- 13:25I need to display pressed button (or any other kind of visual accent). I tried property
selected
but it's do not work:
view [b: button button [b/selected: true] ]
- hiiamboris
- 13:31well that would be some weird UX
- bubnenkoff
- 13:33hm... is there any
pressed
flag for button?
- hiiamboris
- 13:42no13:42perhaps you should use checkbox instead of a button
- pekr
- 13:43Well, in old VID it was a
toggle
IIRC, but it was a custome gfx. Not sure it exists in RED VID, as the widgets are native, so I doubt it ...
- bubnenkoff
- 13:45Is there any way to detect witch radio button is actived without adding labels and complex logic of iteration?
view [
radio
radio
radio
]
- hiiamboris
- 13:46
on-change
should work
- toomasv
- 14:59
view [style pet: radio on-change [print [face/extra pick ["is born" "is killed"] face/data]] pet extra "Tom" pet extra "Jerry"]
- bubnenkoff
- 09:15Why control is not marked as selected after window creation:
view [r: radio with [selected: true]]
- hiiamboris
- 10:12study the source of
set-focus
11:01sorry I was AFK mostly11:01seems like that doesn't work either, only focus
keyword in VID
- bubnenkoff
- 11:03maybe it's an issue? Because it's expected to work as in my code
- hiiamboris
- 11:04seems like
data
facet controls it11:04which sort of makes sense11:05OTOH it also makes sense to only have one selected radio button per panel, or per some explicit radio group, and for that parent/selected
makes sense.. except it conflicts with the focus model11:07indeed there's a hack that handles per-panel selection (in View code):
;-- Radio faces handler --
insert-event-func [
if all [
event/type = 'click
event/face/type = 'radio
][
foreach f event/face/parent/pane [
if all [f/type = 'radio f/data][f/data: off show f]
]
event/face/data: on
show event/face
event/type: 'change
]
event
]
11:09so I should guess that it was designed so user clicks select one radio per panel, but if you're doing it all programmatically then you're on your own
- greggirwin
- 19:06I want to say there was a facet to control radio grouping in R2, but that may have been something @rgchris did in his style.
- Rebol2Red
- 10:59Can someone explain the differences (the big picture, not the details) between the three versions of Red (Gui, Console and Toolchain version). Is there a version or a hack by which I can redirect the output of Red to a file?
Like red.exe test.red > c:\output.txt
- hiiamboris
- 11:24Have you seen the main page? https://www.red-lang.org/11:28Redirection works fine from CLI console.
- dockimbel
- 11:30It's also briefly explained at the top of the Download page...
- Rebol2Red
- 12:15@hiiamboris Thanks
- ldci
- 12:16@Rebol2Red
Red CLI : Red interpreter and CLI console. Without graphical interface.
Red GUI : Red interpreter and View DSL including GUI console. All you need for graphical apps.
Red Toolchain : Encapper for Red and Red/System compiler. If you want to compile and distribute your code.
- Rebol2Red
- 12:21You need a toggle button with an image
toggle: func ['word][set word not get word]
im1: make image! 100x100 ; im1: load %image1.jpg <- change to one of your own pictures
draw im1 [box 0x0 100x100 circle 50x50 45]
im2: make image! 100x100 ; im2: load %image2.jpg <- ; change to one of your own pictures
draw im2 [box 10x10 90x90]
sw: true ; a switch must be true at startup
view [
title {RvS - Togglebutton @2022}
size 500x500
at 200x200
b: button 100x100 "click me" im1 [ ; <- adjust buttonsize to biggest pictures size
toggle sw
case [
sw = true [b/image: im1]
sw = false [b/image: im2]
]
]
]
Too bad you can't have this resizing with the button image
im1: make image! 100x100 draw im1 [box 0x0 100x100 circle 50x50 45]
im2: make image! 100x100 draw im2 [box 10x10 90x90]
view [
image 50x50 im1
image 50x50 im2
]
So you must resize your pictures outside of Red with Irfanview or the like12:37You can have as many switches as you want
toggle: func ['word][set word not get word]
sw1: true
sw2: false
loop 5 [
toggle sw1
print sw1
toggle sw2
print sw2
]
In regard to my comment "; a switch must be true at startup" this is needed over there otherwise the picture only changes after the second click on it.13:01Using togglebutton with your own pictures:
toggle: func ['word][set word not get word]
im1: load %image1.jpg ;<- change to one of your own pictures
im2: load %image2.jpg ;<- change to one of your own pictures
view [
title {RvS - Togglebutton @2022}
size 500x500
at 200x200
b: button 100x100 im2 [ ; <- adjust buttonsize to biggest picture size or adjust pictures to buttonsize
toggle sw
case [
sw = false [b/image: im1]
sw = true [b/image: im2]
]
]
do [
sw: true ; in this case the switch must be true at startup
]
]
13:21@ldci Thank you, it is all clear now. (I accidently deleted this post)
- rgchris
- 14:52> I want to say there was a facet to control radio grouping in R2, but that may have been something @rgchris did in his style.
@greggirwin No, I believe that was standard. The OF keyword was used for grouping, see this answer here: https://stackoverflow.com/a/6403025/292969
- greggirwin
- 18:38Thanks @rgchris. :+1:
- cosacam1
- 19:39Hi again . Take a look at this19:40
>> c: blue
== 0.0.255
>> find [red green blue] c
== none
>> c: "John"
== "John"
>> find ["Jane" "John" "Joe"] c
== ["John" "Joe"]
>>
19:41why does it find the string in the list but not the tuple?
- dockimbel
- 19:52
lisp
>> foreach item [red green blue] [probe type? item]
word!
word!
word!
>> foreach item reduce [red green blue] [probe type? item]
tuple!
tuple!
tuple!
- cosacam1
- 20:08I see. Thanks. BTW did you see my drag problem above?20:10@luce80 About my drag problem. Thanks for your reply but make the following changes to it and you'll get stuck when dragging the blue.20:13
p: panel loose blue [
origin 0x0 space 0x0 below
style area: area 250x100
area "A"
area "B"
area "C"
area "D"
area "A"
area "B" ; ... insert a lot of areas A thru C
] with [size/x: 300 ]
- hiiamboris
- 20:15I already told you how to properly implement dragging.20:17Otherwise, reduce it to a **minimal** example that shows it's a bug in Red, so we can fix it.
- cosacam1
- 20:19yes, I know, using mouse events, thanks but I'm just curious about this. Besides, I'm working in two projects at the same time. I haven't had time. Thanks again.20:38I'm sorry, maybe I bother you guys but I only have internet access once and a while so... Here is the example. No scroller, only dragging. 20:40
Red [needs 'view]
view [
bg: panel 300x300 [
origin 0x0 space 0x0
fg: panel blue loose [ ; just drag on the blue
style a: area 100x50
origin 0x0 space 0x0
below
a "A" a "B" a "C" a "D"
a "A1" a "B1" a "C1" a "D1"
a "A2" a "B2" a "C2" a "D2"
a "A3" a "B3" a "C3" a "D3"
a "A4" a "B4" a "C4" a "D4"
a "A5" a "B5" a "C5" a "D5" ; get stuck when reaching here
a "A6" a "B6" a "C6" a "D6"
a "A7" a "B7" a "C7" a "D7"
a "A8" a "B8" a "C8" a "D8"
a "A9" a "B9" a "C9" a "D9"
] with [size/x: 200]
on-drag-start [system/view/auto-sync?: no]
on-drag [fg/offset/x: 0]
on-drop [system/view/auto-sync?: yes]
]
]
- hiiamboris
- 20:46well, so far it still looks like a bug in your code - draggable face just gets hidden
- cosacam1
- 20:51The draggable face is the blue panel which contains the areas or whatever other faces we can put in it. I never hide anything. Can you drag it until you see "D9" area? And back again until "A" area. I can't. My Red version is dated to 12-Nov-2022/17:58:23. My system is Win 10.
- hiiamboris
- 20:53this shows the bug:
view [
size 300x300
at 0x-1000 base 300x2100 "DRAG ME" cyan loose
on-drag [?? event/offset]
]
20:54would you like to fill an [issue report](https://github.com/red/red/issues/new?template=bug_report.md) ?
- cosacam1
- 20:59well, for the sake of a better Red... yes21:04may I use your example for the issue? it's shorter than mine. Or you may report it if you want
- hiiamboris
- 21:11indeed, use my example :)21:11if your internet drops again, I'll file a report tomorrow myself
- cosacam1
- 21:37Thanks. Done.
- hiiamboris
- 21:44:+1:
- cosacam1
- 21:47And actually my internet doesn't drops, only that we have a lot of blackouts in my country, my phone (which I use as modem) is broken and I deppend upon a neighbour wifi... well, at least I have a laptop, a brain and a good Red community, thanks God.
- loziniak
- 21:50
>> f: function [code [block!]] [res: do code either unset? res [none] [res]]
== func [code [block!] /local res][res: do code either unset? res [none] [res]]
>> f [123]
== 123
>> f [none]
== none
>> f [()]
*** Script Error: res: needs a value
*** Where: res
*** Near : ()
*** Stack: f
is there a possibility to make last call return none
without repeating do code
?21:53i.e. without doing like this:
>> f: function [code [block!]] [either unset? do code [none] [do code]]
== func [code [block!]][either unset? do code [none] [do code]]
>> f [()]
== none
21:57My usecase is [my unit test library](https://github.com/exercism/red/blob/main/_templates/practice-exercise/testlib.red) - lines 31 and 52 (result: do code
).
- cosacam1
- 21:59How about this?21:59
>> f: function [code [block!]] [either empty? code [none][do code]]
>> f [123]
== 123
>> f [none]
== none
>> f [()]
>> f compose [()]
== none
>> f []
== none
>>
- loziniak
- 22:04hmm your example indeed solves
[()]
case, but it should return none
for every *code* that returns unset!
, like ["blabla" ()]
as well:
>> f: function [code [block!]] [either empty? code [none][do code]]
== func [code [block!]][either empty? code [none] [do code]]
>> f ["blabla" ()]
>> type? f ["blabla" ()]
== unset!
- hiiamboris
- 22:09@loziniak
set/any
- loziniak
- 22:12
>> b: 5
== 5
>> f: function [] [b: 13 set/any 'b () probe b]
== func [/local b][b: 13 set/any 'b () probe b]
>> f
*** Script Error: b has no value
*** Where: probe
*** Near : b
*** Stack: f probe
>> b
== 5
22:12I need it to set local word in function
- hiiamboris
- 22:13@loziniak
get/any
☻
- loziniak
- 22:14:-D
- hiiamboris
- 22:14(although Red has also this handy
:b
notation - just don't tell anyone)
- cosacam1
- 22:14However
- Oldes
- 22:15Of course, because it is a block. Or maybe you want to evaluate the block?
>> unset? do ["ccc" ()]
== true
- cosacam1
- 22:18You guys, with that tricky programming... I still need to learn a lot :)
- loziniak
- 22:19we all learn all the time!
- cosacam1
- 22:19yeap22:22well, I must leave you guys. In a few minutes they'll cut the electricity. It's been a pleasure, as always.
- hiiamboris
- 22:23move to a colder country, cutting electricity there so often is not an option ;)
- loziniak
- 22:25there's something special in Red community that it attracts people from former or even current communist countries :-D22:25sleep well @cosacam1
- cosacam1
- 22:26@hiiamboris not so easy man... never mind. @loziniak maybe the name? Red hahaha
- loziniak
- 22:27hahaha you bet!22:32anyway, problem solved. thank you guys very much!
- bubnenkoff
- 09:33I need to pass
path
to map to function and than access to it's data. But I am getting none:
template2: #(
section_aaa: #(
aa: 111
bb: 222
cc: 333
lots: [
]
)
)
f: function [data [path!]] [
print type? data
probe data
probe data/aa ; here
]
f to-path template2/section_aaa
What I am missing? type is path!
probe print right data because it's evaluate path to data. But how to access to /aa
field?
I am getting:
none
== none
- hiiamboris
- 09:46read [path docs](https://codeberg.org/hiiamboris/red-docs/src/branch/master/en/datatypes/path.adoc) to understand it09:4609:47You made a path with a literal map inside.
- bubnenkoff
- 09:58Egh... after re-reading docs still not understand idea... I should extract map from path?
- hiiamboris
- bubnenkoff
- 10:07yes I already understood this
- hiiamboris
- 10:09don't10:09you should not have put a map inside a path in the first place10:10(unless you know what you're doing, but you do not)
- bubnenkoff
- 10:10But I think that I understand what I am doing and I need to pass path exactly to map10:13
template2: #(
section_aaa: #(
aa: 111
bb: 222
cc: 333
lots: [
]
)
)
f: function [data [path!]] [
print type? data
; doing some operations with passed map
]
f to-path template2/section_aaa ; passing path to map
- hiiamboris
- 10:15when you really understand why it works, you will realize you've had no idea what you were doing ;)
- bubnenkoff
- 10:16oh! thanks! that's work!
template2: #(
section_aaa: #(
aa: 111
bb: 222
cc: 333
lots: [
]
)
)
f: function [data [path!]] [
print type? data
data: first data ; getting map from path
probe data/aa
]
f to-path template2/section_aaa
- hiiamboris
- 10:17so why pass a path if you only need a map? ;)
- bubnenkoff
- 10:24you asking right questions) One reason was to make function able to process blocks and maps with same key-value structure... I need to think more about it..
- loziniak
- 17:44Hi! Is there a reason why in Red and Rebol
while
has condition block and if
has condition expression?
- hiiamboris
- loziniak
- 10:38makes sense! thanks.
- bubnenkoff
- 14:58Hm... I need to change spelling key in map and save it's position:
x: #(foo: 1 bar: 2 baz: 3)
for example I need to get:
x: #(foo: 1 test: 2 baz: 3) ; bar -> test
But remove\adding key with another spelling change order of elements
- hiiamboris
- 15:00maps have no position15:00they're unordered
- bubnenkoff
- 15:01Yes, but I need to display data in map in same order... to make it easier to read...
- hiiamboris
- 15:11don't use maps then15:26well, if your maps are small and you're using them for convenience, not performance, then you can just re-create them15:28
make #() head change find to [] x 'bar 'test
- loziniak
- 11:11Hi! Is this intentional, that the last version available to download on project page is from 17 Aug?11:12When I click "History", there are newer versions as well.
- hiiamboris
- 11:1217 you say?11:13
- loziniak
- 11:13red-view-17aug22-d99a1018a
- hiiamboris
- 11:15lol, how is this possible?
- loziniak
- 11:15[](https://files.gitter.im/5780ef02c2f0db084a2231b0/MkxY/image.png)
- hiiamboris
- 11:16in a fresh browser all ok11:16wow
- loziniak
- 11:16haha just checked, 26 Nov too here in another browser :-)
- hiiamboris
- 11:17ctrl+shift+r doesn't cure it either11:19what fixed it is removing offline data stored by static.red-lang.org11:20@dockimbel
- loziniak
- 11:20
HTTP/2.0 200 OK
X-Firefox-Spdy: h2
content-length: 8216
content-type: text/html
date: Wed, 17 Aug 2022 16:02:26 GMT
last-modified: Wed, 17 Aug 2022 14:44:48 GMT
server: Caddy, Cheyenne/0.9.20.dev
Wed, 17 Aud 2022 :-)
11:25it also helps when you remove ?reload=true
from URL.
- dockimbel
- 14:28From Chrome, I get:
content-length: 8216
content-type: text/html
date: Sun, 27 Nov 2022 14:26:25 GMT
last-modified: Sat, 26 Nov 2022 16:23:01 GMT
server: Caddy
server: Cheyenne/0.9.20.dev
14:30The Download page relies on a
to inject the inner download page from our own server (while the main site is served by Blogger). AFAIK, frames caching is not standardized, so each browser can use different heuristics for such caching.14:34Usually a forced reload (Shift+F5) does the trick.
- hiiamboris
- 14:52> What do you mean by "stored by static.red-lang.org"? What "offline data"?
14:53it was 16k before I cleared it and it updated the site, but became 8k again after I visited it14:55since I got 3 entries there populated over 10 years so, I guess offline storage is not a common practice ;)15:05maybe @rgchris knows more
- dockimbel
- 15:078KB ~= 8216 bytes, so it seems that the page is cached for offline usage by your browser. Can you disable that?
- hiiamboris
- 15:08I sure can, but what about other users who don't know that it must be done?
- dockimbel
- 15:09I guess you're not using the common browser with default setup? I don't have such issues in Chrome.
- hiiamboris
- 15:09I don't, but @loziniak seems to use Firefox
- dockimbel
- 15:11FF has 3% of the [global market share](https://gs.statcounter.com/browser-market-share).
- hiiamboris
- 15:13I think you should be more careful when reading statistics, as it is known that statistics is not science, it's an art ;)15:14Do we consider general population sample to have the same properties as the sample of reducers?15:14This percentage I'm sure comes from mobile users who *don't even know* they can change their browser (which also explains why Safari has the 2nd place)
- ne1uno
- 15:22would a [no-store meta tag] help? (https://stackoverflow.com/questions/49547/how-do-we-control-web-page-caching-across-all-browsers)
- hiiamboris
- 15:24lol, this is what Vivaldi reports in useragent string, go classify it:
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/106.0.0.0 Safari/537.36
- cosacam1
- 19:42hi. I started an issue a few days ago and now it says there is none created by me. Where did it go? thanks
- hiiamboris
- 19:46look into closed issues
- cosacam1
- 20:30I see it's fixed and my examples are working. Thank you very much everybody.
- cosacam1
- 19:16Hi guys, I'm back again. I see in Nenad's cursor.red that you can set a different cursor for a base, like a hand or a hour-glass. I would like to do the same for a panel but it doesn't. A panel is drawn on a base, right? I guess it should be possible . For instance
view [panel [field radio area] cursor hand]
does not give any error but doesn't shows a hand either. Thanks
- hiiamboris
- 19:30seems not implemented19:30panel is not drawn, it's an OS widget
- cosacam1
- 19:58ok
- dockimbel
- 21:17@qtxie ^--- Can panel support that feature (and across all platforms)?
- greggirwin
- 21:20Does @cosacam1 mean that the cursor should override for all embedded faces in the panel? Since a panel doesn't "do" anything, this seems like an edge case.
- qtxie
- 09:40> @qtxie ^--- Can panel support that feature (and across all platforms)?
Looks like we did that on purpose. I need to check the git history...
- qtxie
- 04:00@cosacam1 Pushed a fix for it.
view [panel [field radio area] cursor hand]
works now.
- bubnenkoff
- 11:46What is the right way to prevent an error:
to-local-file does not allow none! for its path argument
on follow code if nothing selected?
to-local-file request-file
I know how to write long version, but I need something small for UI action button. Full code:
button "Select File" [file-full-path/text: to-local-file request-file]
- hiiamboris
- 11:58use
attempt
- cosacam1
- 01:41Hi guys. @greggirwin what I meant is that if a panel is loose then it would be fine to use a hand to show the user he/she can drag the panel and the content in it. @qtxie thanks for fixing that. Meanwhile I did my own version using a base located upon the panel (not as a face in the panel but upon it) so the base is loose (not the panel) and shows the hand, the user drags the base and the base updates the panel offset, simulating that the panel is dragged. Here it is (the same example as before but with a loose base)01:41
Red [needs 'view]
do-wheel: func [event][
sc/position: max 0 min diff sc/position + either positive? event/picked [negate sc/min-size][sc/min-size]
fg/offset/y: bs/offset/y: negate sc/position
]
view [
size 390x450
across space 0x0
bg: panel 367x400 scrollable [
origin 0x0 space 0x0
fg: panel [ ; use blue margin for dragging
style a: area 300x50
origin 0x0 space 0x0
below
a "A0" a "B0" a "C0" a "D0"
a "A1" a "B1" a "C1" a "D1"
a "A2" a "B2" a "C2" a "D2"
a "A3" a "B3" a "C3" a "D3"
a "A4" a "B4" a "C4" a "D4"
a "A5" a "B5" a "C5" a "D5"
a "A6" a "B6" a "C6" a "D6"
a "A7" a "B7" a "C7" a "D7"
a "A8" a "B8" a "C8" a "D8"
a "A9" a "B9" a "C9" a "D9"
] with [size/x: size/x + 40] ; 40 :: show blue margin
on-wheel [do-wheel event]
do [
xx: fg/offset/x + fg/size/x - 40
yy: fg/offset/y
sx: 40
sy: fg/size/y
]
at as-pair xx yy
bs: base blue loose cursor hand with [size: as-pair sx sy]
on-wheel [do-wheel event]
on-drag-start [system/view/auto-sync?: no]
on-drag [
unless system/view/auto-sync? [
bs/offset: as-pair xx (min max negate diff bs/offset/y 0)
fg/offset: bs/offset
fg/offset/x: 0
show fg
sc/position: negate fg/offset/y
]
]
on-drop [system/view/auto-sync?: yes]
]
on-created [
sc: get-scroller face 'vertical
put get-scroller face 'horizontal 'visible? no
td/text: to-string diff: fg/size/y - bg/size/y
either diff > 0 [
put sc 'visible? yes
sc/position: 0
sc/page-size: bg/size/y
sc/min-size: bg/size/y / 10
sc/max-size: fg/size/y
][put sc 'visible? no]
]
on-scroll [
sc/position: max 0 min diff switch event/key [
down [sc/position + sc/min-size]
up [sc/position - sc/min-size]
page-down [sc/position + sc/page-size]
page-up [sc/position - sc/page-size]
track [event/picked - 1]
end [sc/position]
]
fg/offset/y: bs/offset/y: negate sc/position
show fg
]
return text "Panel's height difference " td: text
]
01:46btw have you noticed that in november versions the field height is larger than before? It used to be the same height as button but now is different. No big deal but I think "one text line" faces like field, button, drop-list, etc. should be the same height (and maybe the same width) by default. Something cosmetic. What do you think?01:53I've been studying about carets, too. I see caret-to-offset needs the caret pos as an argument but how can I know where the caret is located in the text string at a given moment in a field, for instance? Besides, I started typing in the field and after some letters I moved the caret back, then I noticed that it blinked 5 times then it stopped blinking. I repeated the experiment several times with the same weird effect. Nothing critical but... well I'm just a curious person. I guess you have noticed that already :)03:33Also, quoting @ldci Red CLI : Red interpreter and CLI console. Without graphical interface.
Red GUI : Red interpreter and View DSL including GUI console. All you need for graphical apps.
Red Toolchain : Encapper for Red and Red/System compiler. If you want to compile and distribute your code.
Well, I tried to compile my program with toolchaing this way E:\red\red-toolchain.exe -c -t Windows .\BB.red
(I've tried also with -r) but it does not create BB.exe, it only creates 3 files in the destination folder (which is also the source folder) libRedRT.dll, libRedRT-defs.r and libRedRT-include.red. Why? Thanks
- greggirwin
- 07:26@cosacam1 a hand for dragging makes sense.
- luce80
- 09:41@cosacam1 **nice** ! I will study this and perhaps will steal one or two things ;) . A really "professional" thing would be having the scrolling go on for a moment and then decelerate until stop after
on-drop
. I think it would not be easy to implement but if you succeeded I will **surely definetly** steal that ;)
- hiiamboris
- 09:43> it does not create BB.exe, it only creates 3 files in the destination folder
@cosacam1 read the compiler's error I guess09:46> november versions the field height is larger than before? It used to be the same height as button but now is different
there's indeed a mess now, @qtxie

view [field "abc" button "abc" text "abc" return field button text "abc"]
09:4909:51> noticed that it blinked 5 times then it stopped blinking. I repeated the experiment several times with the same weird effect
I don't have blinking turned on, maybe others have seen it. Anyway blinking is controlled by the OS, not Red
- ldci
- 09:52@cosacam1 I add the path to red binaries in Windows path and I can compile in windows terminal without problems.
- luce80
- 13:16> I see caret-to-offset needs the caret pos as an argument but how can I know where the caret is located in the text string at a given moment in a field, for instance?
@cosacam1 A few of us are waiting for a way to set
and get
the caret position. I hope it will happen sooner then later. AFAIK caret-to-offset
is meant to be used with rich-text
- cosacam1
- 23:54well, a lot of replies! thanks a lot. @luce80 thanks for that "nice!", I do my best but I know I still have a lot to learn yet. About that deceleration you say, I remember I did it once in RFO-BASIC! some years ago. I must find out where that code is. Basically is about getting both mouse coordinates and clock time at "touch and untouch events", then the Y difference gives you the distance, and the milliseconds difference gives you the time lapse. Distance divided by time lapse is velocity, how far or slow the user did the drag movement. But acceleration is a little tricky, kind of a coefficient that you must decrease exponentially (not linearly) in every step or frame. Then you multiply some delta_y (the minimal displacement of the objects to be dragged) by this coeficient so at the beggining they move fast and slower at the end. That's what I recall right now. As you see this `rate' must be involved here. I can't promess I'll code it for you because I'm very busy with my work right now, two projects at the same time (three if I count that I'm trying to teach Red to my son, haha), but I guess this explanation is a clue for you to make it. Good luck! 23:56@hiiamboris well you are more curious than me. I see there's a difference between a field with and without a text in it. Interesting :)23:58@ldci I did what you suggested, added the path to tool-chain in Windows system vars but I got the same result: only those three files are generated but no .exe file
- cosacam1
- 00:04[](https://files.gitter.im/5780ef02c2f0db084a2231b0/Hh5h/Captura-de-pantalla-69-.png)00:05[](https://files.gitter.im/5780ef02c2f0db084a2231b0/Q5W9/Captura-de-pantalla-70-.png)00:10[](https://files.gitter.im/5780ef02c2f0db084a2231b0/JZXW/Captura-de-pantalla-71-.png)00:15[](https://files.gitter.im/5780ef02c2f0db084a2231b0/V56k/Captura-de-pantalla-72-.png)00:22And guys... we've been without blackouts for three nights in a row!!!00:42@hiiamboris I see that blinking is by OS. I made a test, wrote some URL in FireFox, I stopped writing and finally noticed that it stopped blinking by itself. Interesting.04:11@hiiamboris
read the compiler's error I guess
well, the compiler didn't show any error, it just didn't create any .exe
- hiiamboris
- 08:22It's your AV killing the exe then.
- ldci
- 09:10hiiamboris is probably right:)
- cosacam1
- 19:43well, I'll check it asap, today I'm at job, not at home where I've been working recently. Thanks again
- bubnenkoff
- 14:42If object can't be extended does it mean that it for example I want to create:
config: object [] ; as global variable
And after reading config try to fill it. I can't do it. Because objects not extendable and I need to create object at reading config moment?
- hiiamboris
- 14:53or you may reassign
config
word
- Oldes
- 15:55You can use map instead of object
- bubnenkoff
- 16:40thanks!
- bubnenkoff
- 10:32
none
can represent NULL
in SQL.
But what if I need to get NOT NULL
.
Is there any ideas?
For example I need to generate SQL from config:
foo: none
is there any good ideas?>
- hiiamboris
- 10:46
complement make typeset! [none!]
?
- bubnenkoff
- 11:08good idea!11:18>
complement make typeset! [none!]
?
I am afraid that it increase complex of code... maybe !none
is better for NOT NULL
?
- hiiamboris
- 11:22> Did not know about complement. Why:
>
> >> complement 2
> == -3
>
study the numbers with to-binary
12:23What would be the least awkward way to represent caret's state as a Red value? Caret is a combination of nonnegative integer offset (0..length) and side (left/right). Side is supposed to affect both it's line of appearance (around line wraps) and insertion behavior (e.g. when you type a char at the tail, whether bold/italic/etc attributes apply to the new char or not).
Options I can think of:
- integer -N
for left caret +N
for right, abs caret
to get offset from it, but I don't like that it will be able to flip it's sign on keypresses
- floats N - 0.1
for left N + 0.1
for right, round/to caret 1
to get offset - no flipping but more awkward convesion
- block [N left]
/[N right]
- looks self explanatory but I don't like /1
and /2
access to modify it
- block [offset: N side: left]
/[offset: N side: right]
- access looks better but I don't like find
invocation such access incurs, and it generally looks like an overkill
(object is not considered being too heavy)
- luce80
- 13:18What about implementing it as a function! so you can change idea in the future ?
P.S. new char is always to the right ;) ?
- hiiamboris
- 13:24It might be used as an argument to other functions (but I'm not yet 100% sure how it will play out), so with function it'll be a bit problematic - where do I keep this function?13:27> P.S. new char is always to the right ;) ?
I'm talking about this behavior:
1. original: "**abcd**" (source: bold "abcd" /bold
)
2. left insertion of e
(to the left of /bold
, after "d"
): "**abcde**"
3. right insertion of e
(to the right of /bold
, at tail): "**abcd**e"
I think what I call left insertion here is more commonly expected behavior (though both seem useful).13:37Or more sophisticated example:  (two text cells in a grid)
There is no item between c
and e
, so to the right of c
and to the left of e
is the same integer caret offset. But it can appear at left side c|
and at right side |e
. Where your insertion goes depends on the side (and ofc you don't want to carry styles from the left cell to the right one when you type).13:54What also complicates the choice is that not all functions are side-sensitive. E.g. remove
or copy
could care less.
- luce80
- 07:30How are
system/view/metrics/margins
interpreted ? That is , how are they mapped to top, left, right and bottom ?
- hiiamboris
- 08:04LeftxRight TopxBottom it seems.
- bubnenkoff
- 08:56It seems that I have found wrong behavior of function:
view [
file-full-path: field 500x25
button "Select File" [
print get-current-dir
attempt [file-full-path/text: to-local-file request-file]
print get-current-dir
]
]
result:
C:\WINDOWS\system32\
D:\test\test_files\
request-file
should not change working dir
- ldci
- 09:30@bubnenkoff. Yes there is a problem with request-file. In may cases I need to check
if get-current-dir <> appDir [change-dir appDir]
- hiiamboris
- 09:32Interestingly, while
get-current-dir
returns a changed path, pwd
and what-dir
still return the old.09:32@dockimbel may say if it's by design and what's the difference.
- bubnenkoff
- 12:42Has anyone written some code for SQL formatting? If yes please give a link...
- dockimbel
- 14:55Don't use
get-current-dir
, set-current-dir
, create-dir
. They are not part of Red standard API. Those are temporary routines for internal use until we get a dir://
port.
- cosacam1
- 23:04Hi everyone. Take a look. Click the button and you'll see that each line's height is about 22 or 23 pixels.
However, size-text b4
is counting 3 lines of text, not 2. Why?
Or, how can I detect that the last line is actually empty or not? Thanks.
23:05
Red [needs 'view]
view [
style b: base 120 wrap top left font-size 12 yellow
below
b1: b "qwertyuiop"
t1: text
b2: b "qwertyuiop aasdf ghjk l"
t2: text
b3: b "qwertyuiop aasdf ghjk l zxcccc vbn m"
t3: text
b4: b "qwertyuiop aasdf ghjk l zxcc"
t4: text
button "Calc" [
t1/text: to-string size-text b1
t2/text: to-string size-text b2
t3/text: to-string size-text b3
t4/text: to-string size-text b4
]
]
23:05PS. I did source size-text
and source system/view/platform/size-text
and finally I studied get-text-size
in gui.reds
I see you send a msg to system to get the text width and you also get the hight "directly" from a CPU register.
So, it's system who computes the text size.
But... how can I get the right text size? I need some of your magic, guys.
It's the only thing left to finish my project. Thanks again.
BTW I can compile now. Some days ago I told you I couldn't. The reason is I had to declare some vars before using them.
The interpreter has no problem with that but the compiler needs it. I forgot about that.
The compiler showed the error but it closed the window so fast that I couldn't see it.
So I did E:\red\red-toolchain.exe -c -t Windows .\BB.red > log.txt
There I saw the error, declared the vars and compiled to .exe
Thanks for your help.
- hiiamboris
- 23:22
b: [rich-text 120x80 wrap top left font-size 12 yellow]
view compose [
below
b1: (b) "qwertyuiop"
t1: text
b2: (b) "qwertyuiop aasdf ghjk l"
t2: text
b3: (b) "qwertyuiop aasdf ghjk l zxcccc vbn m"
t3: text
b4: (b) "qwertyuiop aasdf ghjk l zxcc"
t4: text
button "Calc" [
t1/text: to-string size-text b1
t2/text: to-string size-text b2
t3/text: to-string size-text b3
t4/text: to-string size-text b4
]
]
23:30rich-text styling is bugged (https://github.com/red/red/issues/5254) so I used compose23:32> The compiler showed the error but it closed the window so fast that I couldn't see it.
You can run cmd
program and type your commands there. 23:34Or use ConEmu, it doesn't close new tabs if they finish too quickly.
- cosacam1
- 00:07thanks a lot
- bubnenkoff
- 09:55Is it possible to get access to
args
when execution script with do
? I would like to get same behavior when app run as script and when it compiled
- hiiamboris
- 10:10
? do
- bubnenkoff
- 10:56hah, really)
- bubnenkoff
- 13:10@hiiamboris strange, yesterday I remember that I get all work and it was very simple but today I was surprised that same solution not worked O.o
do/args %/d/code/app.red "-proj=foo"
--> []
file:
args: system/options/args
prin "--> "
probe args
What I am doing wrong today O.o
- hiiamboris
- 13:18looks like a bug in
do
13:18it sets system/script/args
directly to any value I give to it, not even checking if it's a string or what, and doesn't set system/options/args
at all
- bubnenkoff
- 13:19Very strange that yesterday I get it work... maybe a float bug...
- hiiamboris
- 13:21Your memory maybe playing tricks on you ;)13:22@dockimbel is this a bug or just never designed? what do we do about it?13:23@bubnenkoff you can call
extract-boot-args
manually for now (but it will eat the first argument, thinking it's an exe name)
That is: do/args %/d/code/app.red "any-token -proj=foo"
Then: extract-boot-args probe system/options/args
13:26I find this whole system/script
vs system/options
thing confusing by the way. I got used to it eventually, but for any newcomer these names doesn't tell where to look for processed and where for the original args.
- dockimbel
- 13:30
system/options
relates to the interpreter executable itself, while system/script
to user code run by do
. Though, for compiled/encapped scripts, they overlap. I guess it's an original design in Rebol that didn't age well, back in the days where you could only run scripts through the console/interpreter.
- Kazzum
- 13:36okay, I'm stumped. I'm looking for documentation / examples on interacting with files. Reading, writing, deleting, creating etc...
I'm trying to convert some of my batch scripts into red as a place to get started learning the language. am I jumping in the deep end here?
- hiiamboris
- Kazzum
- 13:37I did try help and the help file however it wasn't as straight forward as "print read temp.txt"13:38if I wanted to create a small gui, I was able to find some rather straight forward examples (I could follow and modify) but as far saving data or moving data having some trouble finding something.
- hiiamboris
- 13:39
help "file"
lists more
- Kazzum
- 13:40AH I misunderstood what you were trying to tell me. thanks for being patient.
- hiiamboris
- 13:42Sure no problem, we all can get overwhelmed at the start ;)
- Kazzum
- 13:44hmm before I ask more let me look up those commands.13:45gosh with descriptions like that, it's like red is it's own operating system
- hiiamboris
- 13:47Basic idea is that Red handles file names in it's own format, which you need to convert before it and the OS (but on Linux it just happens to work without that)
- Kazzum
- 13:48yeah that sounds right with windows black box I can understand the limitations.14:25okay just for posterity's sake. it is as simple as it seems to read a .txt file using the "read" command even if you created the file from windows notepad. The issue I was having was that whatever program I had used to create the text in "temp.txt" encoded it into a strange format. some OEM Windows format.
- hiiamboris
- 14:30OEM is a single-byte per character format, from the old days14:31You can
read/binary
it and then decode char by char if you know the encoding14:32@rebolek has some decoders I believe, but not sure where maybe [here](https://gitlab.com/rebolek/castr) somewhere
- greggirwin
- 17:50As a side note, where you have
"temp.txt"
, which is a string, you should use file!
values when possible in Red. e.g. %temp.txt
or %"file with spaces.txt"
. Leveraging datatypes and their lexical forms, is a big part of using Red effectively.
- Kazzum
- 18:00Thanks, while fumbling around in the red console, the program itself has yelled at me alot for that sin. warranted though.
- greggirwin
- 18:01It's worth the effort. :^)
- Kazzum
- 20:05when I use a variable like
upath: rejoin ["/c/users/" get-env username]
is red storing the output of that command as a variable, or is it storing the code itself in the variable?
Functionally I can't tell the difference when typing upath
but if I were stick a command in front of upath
such as print
or cd
this makes a different doesn't it?
upath
outputs
"/c/users/username"
print upath
outputs
/c/users/username
cd upath
outputs
*** Access Error: cannot open: %"/C/Program Files/upath/"
*** Where: do
*** Near : cd upath
*** Stack: cd change-dir cause-error
20:10so it looks like red isn't evaluating my variable before processing the command cd
but I find it MUCH more likely that I'm doing it wrong.
- hiiamboris
- 20:13a few other console commands work like this too20:13
:dir
is a get-word, and arguments denoted like this are not evaluated
- Kazzum
- hiiamboris
- 20:17
cd
is a helper command available only the console (not in the runtime)
- Kazzum
- 20:21ah okay, and I can use
word?
and other data types with a question mark to check what kind of data I have
- hiiamboris
- 20:21but as you'll see it has it's shortcomings, one of them is inability to evaluate the argument, another is e.g. you can't write
cd 123
or cd /c/windows
, have to write cd %123
or cd %/c/windows
instead20:22also a debugging advice: ? upath
will tell you what your value really is20:30people tend to skim the output of help
quickly as if not expecting it to teach them anything, but it contains this advice as well ;)
- Kazzum
- 15:05
get-current-dir
is giving me the current directory in a windows format. i.e. using back slashes ( C:\path\
) but the change-dir
commands need directories in a linux like format using forward slashes and omitting the colon ( :
)from the path.
From the command available to me it seems like a complicated operation of turn the output of get-current-dir
to a series where each char is put into an array, Find
is used against the array to find each instance of a \
and replace them with /
( perhaps by using alter
? ). and the :
is deleted out of the array then rejoin
is used to piece it all back together.
would I be doing this the hard way?
- hiiamboris
- 15:08but I also suggest you scroll up to :point_up: [December 13, 2022 5:55 PM](https://gitter.im/red/help?at=6398927adbde086250dffa98)
- Kazzum
- 15:09AH okay
- hiiamboris
- Kazzum
- hiiamboris
- 15:12no, I just used it to show the intermediate result15:13and as a debugging hint ;)
- Kazzum
- 15:14again thank you
- hiiamboris
- 15:14:+1:
- Oldes
- 15:47Isn't
get-current-dir
just leaked internal routine? In Rebol there was always what-dir
returning current directory in a Rebol format. It is in Red as well.15:48:point_up: [December 13, 2022 3:55 PM](https://gitter.im/red/help?at=6398927adbde086250dffa98)
- Kazzum
- 15:51thanks, I'll read up15:57ah okay, I should use
what-dir
instead of get-current-dir
, change-dir
instead of set-current-dir
, and make-dir
instead of create-dir
. got it.
- hiiamboris
- 15:59:+1:
- Kazzum
- 16:40having trouble interacting with the output of
list-dir
>> unset? list-dir what-dir
red-view-...
== true
>> map? list-dir what-dir
red-view-...
== false
16:41or rather anything I can interact with
- hiiamboris
- 16:42
read %dir
- cosacam1
- 17:57Hi. On mid September I installed VSCode in my laptop, which I use at home and now I installed it in my PC at job.
The problem is I see no extensions for Red in File > Preferences > Settings > Extensions
I've been following the advices @riprwwa gave to me last September (they worked ok then) buy with no avail.
VSCode shows extensions for many languages but not for Red.
I even copied the extensions\red-auto.red-0.4.4
folder from my laptop to the corresponding folder in my PC. I also modified properly (I think) .init-default-profile-extensions
and extensions.json
files. I copied theme-red
folder too.
Before all that, I googled "Red extension for VSCode" and it gave me the following links: https://github.com/red/VScode-extension and https://marketplace.visualstudio.com/items?itemName=red-auto.red.
The former tells me to set red.redDir
which takes me to the situation I had in September that I explained I could solve then but not now.
The later shows a green button to Install (the extension, I suppose). I click on it at it tries to do something with VSCode but there it shows an error message "XHR failed".
In brief, I can't use Red extension in my PC VSCode. Any help? Thanks.
- greggirwin
- 19:12On
*dir
funcs:
1) We need a way to identify commands that are meant *only* for console use. Not an easy call because we want them to be short and direct, so prefixing with con-
or a con
context isn't great. Even a prefixed sigil isn't great, since the console prompt is there.
2) Can we come up with a better name than what-dir
? Say current-dir
or active-dir
?
- hiiamboris
- 19:201) identify and then what?
2) I'm for current-dir
, and maybe leaving what-dir
for backward compatibility
- Kazzum
- 19:28
current-dir
could be shortended to cd
which would cause confusion, it doesn't confuse me because I come from windows command prompt. this-dir
might be nicer as it's still short.
- greggirwin
- 19:291) Then write a doc that explains them, and their design intent. It's about managing expectations as much as anything. That may also flush out inconsistent behavior or lead to new ideas for a Red Shell (which we make a Mario Kart reference:
Destroy the Problem Ahead of You!
). We learned a lesson with help
in that people wanted the output, which is why help-string
now exists.
2) Yes, we can mark what-dir
as deprecated.
- Kazzum
- 19:30also linking to https://www.red-by-example.org/ on the main website would be great. the examples REALLLLY clear things up for me.
- greggirwin
- 19:31Yes, we need to get red-by-example back up to date and promote it more. I've been working on doc ideas and tools, and that's on my list.
- Kazzum
- 19:34I think there may be a misunderstanding.
I only started using get-current-dir
because it was higher on the list using what
in the console and described what I needed.
I don't find anything objectional about what-dir
19:36a "see also" section would of told me to try the other commands that may of been relevant to what I was trying to do.
- greggirwin
- 19:37Yes, "see also" is *very* high on my list for docs and tools.
- cosacam1
- 19:44@Kazzum about the "see also" take a look at https://www.red-by-example.org/ maybe that helps19:47@Kazzum about config files in VSCode I see nothing
- hiiamboris
- 19:48I *very* rarely use
cd
/ls
, and nothing else of console commands, so I don't even care if they exist. Heavy users of these should drive the direction.
- cosacam1
- 19:49In https://github.com/red/VScode-extension it says
Download the Red binaries to a local folder, then set the red.redDir to it. The plugin will use the latest one according to the filename. "red.redDir": "D:/Tools/Red/"
but where do I write this?
- greggirwin
- 20:10I also rarely use them, but I *do* want a real Red shell with even more power, AWK, etc.
- Kazzum
- 20:19I would argue it would be better to lay the shell ontop of red i.e. red/system | red | red shell
but that is because it's what I am used to. it's very linux philosophy. Do one thing and do it well then build ontop of that. 20:20but also I'm still bumbling my way through my first script so mayhaps don't do what I say. I am strange and silly person.
- greggirwin
- 20:30Welcome to the club. :^)
- Kazzum
- cosacam1
- 22:10He22:11Wh
- cosacam1
- 01:17Sorry, where can I find red.vsix (if any) so I can manually install it in VSCode? Thanks
- bubnenkoff
- 14:15How to check if
view
is already loaded?
app: []
view layout app
I have some logic of that need to know if window is already opened or no14:18
open-project: function [project-name [string! none!]] [
either not none? project-name [
] [
; view/no-wait app-ui ; !! we should prevent of calling when we will again call open-project
]
] [
view/no-wait app-ui ; open empty window
]
]
- hiiamboris
- 14:38if it's the only window, check
system/view/screens/1/pane
- greggirwin
- 20:16We need to think a bit about how we'd want this to work, for sub-faces, windows, and screens. But here's a start.
find-window: func [
"Find a face's window face."
face [object!]
][
while [
all [
face/parent
face/parent/type <> 'screen ; stop at the top window, not the screen.
]
][face: face/parent]
face
]
viewed?: func [
"Returns TRUE if face is displayed."
face [object!]
/screen scr-num [integer!]
][
default [scr-num 1]
to logic! find system/view/screens/:scr-num/pane find-window face
]
wnd-a: view/no-wait [size 400x300 text "I'm A"]
view [
button "Is window A open?" [print viewed? wnd-a]
button "Close Window A" [unview/only wnd-a]
button "Open Window A" [view wnd-a]
]
(replace default
with standard code or I can post my default
func)
@hiiamboris do you have anything like this planned for spaces
?
- hiiamboris
- 20:58Spaces don't deal with windows, so no21:00I only have internal checking for spaces if they're live or orphaned to turn their timers off until they're drawn again.21:01For Dmitry's task I just had
empty? system/view/screens/1/pane
in mind.21:04In the general case it all highly depends on particular task. You may check if window is in the tree, but how reliable is this check? What if you entered the function that should show the window but it has not finished yet?21:05Plus this all gets us back to general tree/node type and general iteration that I'd like to see in place of 100500 adhoc foreach/while variants.
- loziniak
- 23:54How to compare maps with *none!* values?
>> b: #(x: "abc")
== #(
x: "abc"
)
>> a: #(x: "def")
== #(
x: "def"
)
>> a = b
== false
>> a: #(x: #[none])
== #(
x: none
)
>> a = b
== true
23:58@Kazzum you can find relevant commands by digging red-by-example: https://www.red-by-example.org/
Commands are conveniently grouped by categories there.
- bubnenkoff
- 06:30Is there any plan of further developing of VID? For example it support resize of main window, but resizing of children controls is a pain. Spaces solve a lot of problems, but it's important to know plan for VID
- hiiamboris
- 10:04@loziniak report it, it's a bug10:06## 🤦🏻♂️10:09@bubnenkoff https://gitlab.com/hiiamboris/red-elastic-ui may alleviate some pain
- loziniak
- 10:20thanks @hiiamboris ! voila: https://github.com/red/red/issues/5259
- bubnenkoff
- 12:14> @bubnenkoff https://gitlab.com/hiiamboris/red-elastic-ui may alleviate some pain
is it totally compatible with VID?
- hiiamboris
- 13:16Yes13:17Well, I hope so. If you find layouts that work in VID but not when you pass it to
elastic
, tell me, I'll fix it.
- luce80
- 15:07@bubnenkoff If you have only a few VID styles that resize in simple ways it is not so difficult:
win: layout [
f: field
b1: button "abc"
return
a: area
return
b2: button "def"
]
react compose [
f/size/x: win/size/x - (win/size/x - f/size/x)
b1/offset/x: win/size/x - (win/size/x - b1/offset/x)
a/size: win/size - (win/size - a/size)
b2/offset/y: win/size/y - (win/size/y - b2/offset/y)
]
view/flags win 'resize
Take a look also at [this](https://gist.github.com/luce80/433286c66d98997aff6e69fbd6323a35#file-splitter-red)17:41Has someone a function to transform a text with html entities e.g. "
to "normal" text ?
- hiiamboris
- 17:48https://github.com/Oldes/Rebol3/blob/master/src/mezz/codec-html-entities.reb
- luce80
- 08:35@hiiamboris thanks , quite exaustive!
Interesting that I see here another [string! binary! file! url!] pattern ! Typical of codecs so let's take a look:
>> source system/codecs/json/decode
system/codecs/json/decode: func [text [string! binary! file!]][
if file? text [text: read text]
if binary? text [text: to string! text]
load-json text
]
Since to string!
also accepts string!
we could write:
decode: func [text [string! binary! file!]][
if file? text [text: read text]
text: to string! text
load-json text
]
And possibly shorten as:
decode: func [text [string! binary! file!]][
if file? text [text: read text]
load-json to string! text
]
Since url!
is almost a synonim of file!
we could easily extend it to:
decode: func [text [string! binary! file! url!]][
if any [file? text url? text] [text: read text]
load-json to string! text
]
And now if read
accepted also string!
and binary!
by simply passing them as is we could write:
decode: func [text [string! binary! file! url!]] [
load-json to string! read text ; or read/binary ?
]
P.S. Merry Christmas ;)
- hiiamboris
- 09:13the list is far from exhaustive actually, but the design is sound ;)
- bubnenkoff
- 09:23> @bubnenkoff If you have only a few VID styles that resize in simple ways it is not so difficult:
>
> win: layout [
> f: field
> b1: button "abc"
> return
> a: area
> return
> b2: button "def"
> ]
> react compose [
> f/size/x: win/size/x - (win/size/x - f/size/x)
> b1/offset/x: win/size/x - (win/size/x - b1/offset/x)
> a/size: win/size - (win/size - a/size)
> b2/offset/y: win/size/y - (win/size/y - b2/offset/y)
> ]
> view/flags win 'resize
>
> Take a look also at [this](https://gist.github.com/luce80/433286c66d98997aff6e69fbd6323a35#file-splitter-red)
Wow! Looks very cool!!
- luce80
- 11:08>
text: to string! text
this is an equivalent of text: copy text
really ? if initial text is a binary!
?
- hiiamboris
- 13:07Then new buffer is a conversion from binary.13:08Result of
to
is always a new buffer, so it should not be used carelessly.
- luce80
- 16:36>Then new buffer is a conversion from binary.
?? I meant:
>> copy #{61}
== #{61}
>> to string! #{61}
== "a"
>> to string! "a"
== "a"
- hiiamboris
- 16:45Sorry for confusion :)16:47In other words, in your first code reduction iteration you introduced a copy :)
- luce80
- 16:53True, a possibly unnecessary copy, but we have GC memory allocations ;) , or we could introduce
as string! #{61}
?
or read
could do the conversion ? (Adding a copy... ;( )
- hiiamboris
- 16:56or we could let the working code continue to work ☻16:57GC currently is something to avoid when possible, unfortunately https://github.com/red/red/issues/4837
- cosacam1
- 02:57Well, I finished my Bible Sketch project some days ago (an application for reading the Bible, compare passages, search for texts in it and compose Bible sketches or sermons) completely made in Red. I want to thank you guys for your help. And of course I want to thank God, for letting me know one day that there was an extraordinary language out there called Rebol and its successor Red. Merry Christmas and Happy New Year dear fellow REDducers.
- hiiamboris
- 10:15# 👏🎉
- ldci
- 12:39@cosacam1. This project really sounds good. Congratulations :) Did you plan to publish your code? Some of my colleagues could be interested by your approach. BTW, I think we have to add to Red language website an entry to professional applications written with Red. I mean, applications used daily by professionals. Regards
- greggirwin
- 18:32Congratulations @cosacam1. :^)
- bubnenkoff
- 13:01is it possible to increase font in list in text-list?
view [
t: text-list data ["aaa" "bbb"]
]
I want to make it's bigger
- dsunanda
- 13:08Two ways here:
view/no-wait [
t1: text-list data ["aaa" "bbb"]
t2: text-list data ["aaa" "bbb"] font [size: 18]
]
t1/font: make font! [size: 30]
- hiiamboris
- 13:29https://github.com/red/docs/blob/master/en/vid.adoc#font-size
- bubnenkoff
- 13:43oh thanks! I tried
with [size: 18]
and it did not work)
- hiiamboris
- 13:44random stuff never works :)
- bubnenkoff
- 14:02Why sometimes I need to use
with
sometimes no?
- hiiamboris
- 14:31
with
is an escape route, it can do anything VID cannot
- bubnenkoff
- 15:23I faced with issue from here
https://github.com/red/red/issues/4892
Can't get unselect work
The code from there rising an error after few clicks on same selected element.
If not specify name of action directly event/pick
is always return 0.
view [
t: text-list data ["aaa" "bbb"] [
probe event/picked
probe face/selected
if face/selected == event/picked [
face/selected: none
]
]
]
I tried different combinations, but was not able to get code work
15:27
view [
t: text-list data ["aaa" "bbb"] on-dbl-click [
print [ "Dbl click" "face/selected:" face/selected "event/picked:" event/picked ]
face/selected: none
]
]
error:
Dbl click face/selected: 1 event/picked: 1
*** Script Error: pick does not allow none! for its index argument
*** Where: either
*** Near : all [word = 'selected block? data find [] ]
*** Stack: view do-events do-actor do-safe
- hiiamboris
- 15:34I'll open an issue15:42https://github.com/red/red/issues/5260
- bubnenkoff
- 15:44thanks!
- hiiamboris
- bubnenkoff
- 16:10thanks! work!
- bubnenkoff
- 09:16is it possible to create composite face (widget) I need
text-list
with checkbox. Like checkbox with multiselect.
view [
panel [
origin 0x0
text-list data ["aa" "bb" "cc" "dd"]
]
panel [
origin 0x0
check "aa" return
check "bb" return
check "cc" return
check "dd" return
]
]
The problem that size of controls are different and it's displaying on different level in each panel09:19Padding a little bit helps, but I am afraid that on large number of elements the will become shifted:
view [
panel [
origin 0x0
text-list 100x400 data ["aa" "bb" "cc" "dd" "ee" "ff" "gg" "gg1" "gg2" "gg3" "gg4" "gg5"] font-size 12
]
panel [
origin 0x0
pad 0x0 check "aa" return
pad 0x-11 check "bb" return
pad 0x-11 check "cc" return
pad 0x-11 check "dd" return
pad 0x-11 check "ee" return
pad 0x-11 check "ff" return
pad 0x-11 check "gg" return
pad 0x-11 check "gg1" return
pad 0x-11 check "gg2" return
pad 0x-11 check "gg3" return
pad 0x-11 check "gg4" return
pad 0x-11 check "gg5" return
]
]
- hiiamboris
- 09:52Bad idea IMO.09:54Text-list is just that. Text-list.
- bubnenkoff
- 10:47@hiiamboris
view [
t: text-list data ["aaa" "bbb"] on-down [
selected-name: pick face/data face/selected
print selected-name
]
]
on-down even every first click return none
:
none <-- first click
aaa
aaa
aaa
bbb
- G8nes
- 10:54Yo someone can advise me a book for starting using red? (I’m not a rebol user)
- bubnenkoff
- 10:59> Yo someone can advise me a book for starting using red? (I’m not a rebol user)
sure https://helpin.red/Helpin%27%20Red.pdf
- hiiamboris
- 11:34@G8nes Hi :) See also the list in the topic of https://gitter.im/red/red/welcome11:36@bubnenkoff use
on-change
- G8nes
- 18:34Thx!
- Kazzum
- 18:59
Cause-error
is what I would want to use to halt the script immediately and "throw" an error in the traditional sense correct? (( as apposed to throw
and catch
))
- greggirwin
- hiiamboris
- 19:08
cause-error
for throwing standard errors from the catalog, do make error! "message"
for your own
- Kazzum
- 19:40errr is the command
cause-error 'note 'code [100]
supposed to crash the console?19:41or rather it closes the console without any error message at all19:49Nevermind I suddenly get it. the first two fields code
and type
are not words to use with cause-error
but are words defining what the word!
note
is.
- hiiamboris
- 19:50see
system/catalog/errors
- Kazzum
- 19:50that's where I got it from
- hiiamboris
- 19:50right
- Kazzum
- hiiamboris
- 19:51
no-load
is the only one there
- Kazzum
- 19:51[](https://files.gitter.im/5780ef02c2f0db084a2231b0/eaYT/image.png)
- hiiamboris
- 19:52Yeah it should have errored. I'll report it
- Kazzum
- 19:52Thanks much.
- hiiamboris
- 19:55https://github.com/red/red/issues/5262
- Kazzum
- 18:01
log: rejoin [%log n %.txt]
while exists? (rejoin [upath log])[
n: n + 1
log: rejoin [%log n %.txt]
]
I can't use the Logic! value true
or false
in a while
loop?
- hiiamboris
- 18:02you want to pass a block instead
- Kazzum
- 18:03I'm trying to check if a file exists and if it does loop through numerals until I have a unique document to prevent overwriting.
- hiiamboris
- 18:04
while [exists? (rejoin [upath log])] [
- Kazzum
- 18:04OH okay
- Oldes
- greggirwin
- 19:23In this case, @Kazzum, consider:
1) Which is shorter?
2) Which is more specific, and requires less thinking (because it can only mean one thing).
3) Which uses less arguments? (free ranging evaluation is a hurdle for new people or complex expressions.
4) Which makes the data the focus, rather than the function?
Think about those, then feel free to ask questions about the quesitons. :^)
- Kazzum
- 19:49is this in order of importance?
- greggirwin
- 19:50No, just as they came to mind.
- Kazzum
- 19:51oh okay, that helps alleviate the mind-bending nature of the questions to me.
- greggirwin
- 19:51Anyone else should also feel free to ask about the questions, or at least think about them.19:51:^) Your mind has barely begun to bend.
- Kazzum
- 19:53oh I understand that which is why I didn't shoot off my first thoughts. typed some stuff into the console. looked some more stuff in "red-by-example". typed a few drafts, walked away, came back, etc...
I am assuming as I'm an IT guy, not a programmer, that I need some perspective I'm missing to truly understand the questions much less the answers.
- greggirwin
- 19:59Red is great for non-programmer technical people. You don't need to do advanced things in fancy ways. But it will help you to know enough tricks to make your scripts and code easier to maintain and adapt.
I've written a lot of code that was basically "Do what the human does now, over and over", i.e. automation. Programming is just taking a process and breaking it down into steps. Don't be afraid of thinking like a human, and let those who think like machines handle the deeper stuff. Start small, enjoy the learning process, and you'll find your way.
- Kazzum
- 20:02thank you I appreciate that, I'm still in the throws of my first script not doing exactly what I expected based off what I did in the console. but thanks to this chat I've kept at it and I'm learning things bit by bit. experiment by experiment. (typo by typo)
- greggirwin
- 20:04Pick yourself up, dust yourself off, and try, try again. :^)20:08It's also important to be aware that some behaviors in the console *are* different, which can trip you up. The reason being that *code is data* in Red, so when you type things in the console, it's sort of like putting them, line by line, in a script; repeated lines, typos, and all.20:09There are deeper aspects, but we don't want to melt your brain just yet.
- Kazzum
- 20:14for any interested the biggest challenge for me has been the... directionality of the commands. I'm use to
command qualifiers data /refinements
but unless I am mistaken red is command/refinements data qualifiers
but not always? I'm still a bit blurry on the pattern.
- greggirwin
- 20:19You are correct. Generally the primary data affected generally comes first. That is a switch for you, to be sure.
- cosacam1
- 14:18Hi there. I'm trying to validate fields in a dialog box by means of a generic function.
There is a variable (called err) that holds all error messages created inside the function, which finally returns err.
I also define a style where some features for each field are held as a block in the field's extra facet.
So it's easy to do the validation based upon these features.
When the dialog is shown I click (on purpose) the Validate button without even filling any field.
It should show that non optional fields are empty.
I made two versions of the same function.
The first one using if all [(cond1) (not cond2)] [...]
The second one using if (cond1) and (not cond2) [...]
AFAIK they are both the same. Right?
Version 2 works fine but version 1 neither prints any "... error found" debug message nor fills the err variable !!!
However if all [(cond1) (not cond2)][...]
works fine in a simple example like this14:19Interesting, isn't it? Or... am I doing something wrong?
Well, here is my program. Remember, the second function is the one that works.
14:23
Red [needs 'view]
validate-fields: func [parent /local err n][ ; print statements are for debugging purpose
err: copy "" ; holds all errors found as fields are checked
foreach-face/with parent [ ; with :: check only field faces (see below)
print face/extra/label ; so we know which face is being checked
any [ ; as soon as an error is found in a field, go to check the next field
; 1st check: there's an error when the field is empty and the field is not optional
print [(empty? face/text) (not reduce face/extra/optional)] ; this is working...
if all [(empty? face/text) (not reduce face/extra/optional)][ ; ...but this is not
print ["optional error found"]
repend err [newline face/extra/label " can't be empty."]
]
; 2nd check: there's an error when an integer is expected and the field content can't be converted to integer
if all [("i" = lowercase face/extra/type) (not attempt [n: to-integer face/text])][
print ["integer error found"]
repend err [newline face/extra/label " must be an integer number."]
]
; 3rd check: there's an error when a float is expected and the field content can't be converted to float
if all [("f" = lowercase face/extra/type) (not attempt [n: to-float face/text])][
print ["float error found"]
repend err [newline face/extra/label " must be a fractional number."]
]
; 4th check: there's an error when the number in the field should be in some range and it is not
if all [(face/extra/lo <> face/extra/hi) (any [n < face/extra/lo n > face/extra/hi])][
print ["range error found"]
repend err [newline face/extra/label " must be a number between " face/extra/lo " and " face/extra/hi]
]
]
][face/type = 'field] ; only field faces are checked
return err
]
validate-fields-2: func [parent /local err n][
err: copy ""
foreach-face/with parent [
print face/extra/label
any [
if (empty? face/text) and (not reduce face/extra/optional) [
print ["optional error found"]
repend err [newline face/extra/label " can't be empty."]
]
if ("i" = lowercase face/extra/type) and (not attempt [n: to-integer face/text]) [
print ["integer error found"]
repend err [newline face/extra/label " must be an integer number."]
]
if ("f" = lowercase face/extra/type) and (not attempt [n: to-float face/text]) [
print ["float error found"]
repend err [newline face/extra/label " must be a fractional number."]
]
if (face/extra/lo <> face/extra/hi) and ((n < face/extra/lo) or (n > face/extra/hi)) [
print ["range error found"]
repend err [newline face/extra/label " must be a number between " face/extra/lo " and " face/extra/hi]
]
]
][face/type = 'field]
return err
]
14:24oops! too many chars in my msg. Now the view [...] part
- hiiamboris
- cosacam1
- 14:24
view [
style fld: field with [
extra: [
optional false ; true :: the field might be empty, false :: it must be filled
label "" ; the label that identifies the field
type "s" ; "s" :: string "i" :: integer "f" :: float
lo 0 hi 0 ; lo = hi :: don't check range, lo <> hi :: check range
]
]
below
gbx: group-box " Personal information " [
text "Name"
fld 300 with [extra/label: "Name"] return
text "Age"
fAge: fld 50 hint "1 ~ 100"
with [
extra/label: "Age"
extra/type: "i"
extra/lo: 1
extra/hi: 100
]
hAge-group: h5 "" react [ ; kind of a validation on the fly
; it takes the value from Age field and does something with it, if possible...
; to-integer none, to-integer "", to-integer "abc" and to-integer "3.5" are illegal but to-integer "3" is not
; so use attempt
hAge-group/text: either attempt [age: to-integer fAge/text][
case [
age < 0 [""]
age < 3 ["Toddler"]
age < 10 ["Child"]
age < 20 ["Teenager"]
age < 35 ["Young"]
age < 65 ["Adult"]
true ["Elder"]
]
][""] ; ...not possible? no problem, it quietly disappears
; attempt and reactive programming - I love RED
]
return
; you may have regular VID fields too, no problem, just they won't be checked against any criteria
field "Regular field" return
text "Salary"
fld hint "1000 ~ 10000"
with [
extra/optional: true ; because toddlers don't get paid yet!
extra/label: "Salary"
extra/type: "f"
extra/lo: 2500
extra/hi: 10000
] return
text "Address"
fld 300 hint "This field is optional"
with [
extra/optional: true
extra/label: "Address"
] return
]
across
button "Validate" focus [
print "using version 1"
errors: validate-fields gbx
prin "Validation result: "
print either empty? errors ["all fields ok"][errors]
print "==============="
print "using version 2"
errors: validate-fields-2 gbx
prin "Validation result: "
print either empty? errors ["all fields ok"][errors]
print "==============="
]
button "Close" [unview]
]
14:29Oh, my! I've been struggling against myself for hours! hahaha
- hiiamboris
- 14:31:)