Archived messages from: gitter.im/red/help from year: 2020

rebred
14:07[![image.png](https://files.gitter.im/red/help/tpCM/thumb/image.png)](https://files.gitter.im/red/help/tpCM/image.png)

vazub
21:26Not sure whether this is a bug of circle command or if I am doing something wrong. Consider this snippet:
i: make image! 100x100
points: [40x40 50x50 60x60]
foreach point points [
    draw i [circle point 1]
]

It fails with an error. However, if provided with a literal pair! argument to 'circle' command, it works. Can anyone explain what is happening here?
greggirwin
21:40You need to reduce or compose to get the point value.
i: make image! 100x100
points: [40x40 50x50 60x60]
foreach point points [
    draw i compose [circle (point) 1]
]
? i
vazub
23:16thanks @greggirwin , much appreciated!

GiuseppeChillemi
21:14The is still something not clear to me about words, their values and contexts.

If I have the following line of codes:

a: [a block]
a: 22


When the program flow encounters the first instruction what happens? I have guessed:

The a entry in the system context word-value table is updated linking it to the block structure. This link is done at runtime and not at program loading.

Then, when the second a: is encountered, what does happen ?

Will the a value in the context word-value table be changed? Or will the context word entry be linked to the element just after the a: word ?






hiiamboris
21:19latter
GiuseppeChillemi
21:33So having this code:

sel-code: [s: select s path-item]
fin-code: [s: first at s path-item]

do sel-code
do fin-code


If both s: are in the same context, the first one will link s to the result of the SELECT, then the same word will be linked to the result of FIRST operation.

If the second one has a different context, then the link in the second context will be changed.

Ok but if I perform a y: s what will this do internally ? If s is an integer, will be created a copy in memory and then linked to y entries in y definition context ?
hiiamboris
22:03yes ☺
GiuseppeChillemi
22:10And I should have understood the whole mechanism from the REBOL/core manual ???
God save the newcomers !
hiiamboris
22:14no, I don't think /core manual should cover such inner workings
GiuseppeChillemi
22:19Hiiamboris, not every inner working but the concept code-is-data/data-is-code together with word/context/value mechanism and persistence of series deserve a clear and strong introductive chapter.
We will work on this.
greggirwin
23:22This is a tough call because, while you can trip over the inner workings (as you have @GiuseppeChillemi), it's possible to use Red effectively without knowing anything about them. Just as very few people know how *any* language works internally.

GiuseppeChillemi
10:38@greggirwin Yes, you can use it effectively, and I have used it, but until you do not start having your "there is no spoon" moments, you will never use it at its full potential.
greggirwin
18:25@GiuseppeChillemi but that's OK. VB was a world-transforming tool, no matter how much it has been criticized by developers. It wasn't and advanced language, but it was *useful*. Yes, some people wrote VBX controls, which let others do even *more*, and Red will have the same groups of people. Those who just need to get simple things done are a huge audience with many unmet needs.
GiuseppeChillemi
22:34@greggirwin I agree with you, it is the correct vision. I just hope we will able to make some adjustments to the documentation that will help lower the drop rate that seems high. (I have not numbers, just personal sensations).
dockimbel
23:58@GiuseppeChillemi You cannot make assertions about reality based purely on your personal imagination. Please refrain from posting such baseless statements.

GiuseppeChillemi
00:42@dockimbel Not every assertion can/must be accompanied by measurements. We are human we have opinions, and they are based on the personal unmeasurable perception of reality, knowledge and experience. When data on RED user adoptions/drop rate will be available I would be very interested in comparing my opinions with them and eventually change my mind. Until then, I consider mine valid ones.

While we are on this topic, why not turning it into something good ? I suppose that apart from website telemetry you do not have data too. I have a couple of simple ideas that would help you have real data to analyze adoption/drop trends. Are you interested into discussing about them either in red/red or any other area, even a private one ?

GaryMiller
03:16@gregirwin I think a programming cookbook type approach with lots of commented source code for real world example projects. Toy problems or examples should be avoided though because it often have to see how they would be used in real world problems.
greggirwin
06:52@GaryMiller agreed.
dockimbel
12:14@GiuseppeChillemi Let me try again: opinions based purely on personal feelings but expressed as facts contain no useful information for anyone, so keep such delusions for yourself. This is not your personal blog here.

> I have a couple of simple ideas that would help you have real data to analyze adoption/drop trends.

Thanks, but we know how to gather such information, and such action is not useful at this point of the project, as we are still in the construction phase.
GiuseppeChillemi
16:40@dockimbel Delusion? I would not call it this way: it's fear and commitment to not have another Rebol here. It's my **passion** for Red/Rebol which drives my thought processes and fingers. And to be clear, even if you are the author of the language, the force of my passion is not second to yours. I want Red to be widely adopted and every obstacle removed to reach this goal. Please, before writing me "it's not your blog", or labeling my words as caused by "delusion", why don't you ask me: Giuseppe, which are the foundations of your opinion (note that support data sometime come first, sometime later) ? Which problems do you think you have spotted? Do this if you are interested in the point of view of one of the "customers" of your project, a customer who has faced many difficulties and, instead of abandoning Red, is keeping the faith and commitment, going on despite the big obstacles in the learning path.
16:54However, let's delay this discussion to later times or never have it. Personally I have all the instruments and knowledge needed to create something to help newcomers to Red overcome these obstacles. So, even if you, or anyone else, are not interested in discussing about the (IMHO) Red dropping patters and causes I am ready to move on and help newcomers the best I can.

TheHowdy_gitlab
21:33Can someone point me to a documentation on contexts?
21:34Couldn't find any explanation except the rebol manual, at which point I wondered if there are any differences between Red and Rebol regarding Contexts.
hiiamboris
21:39https://github.com/meijeru/red.specs-public/blob/master/specs.adoc#words-contexts-and-binding-1
vazub
21:52Is there any reason behind having similar in essense and yet separate words like "cos" and "cosine"?
Rebol2Red
22:08@hiiamboris I was trying reddo and have a question:
This works:
reddo "print {Directory listing:} foreach x read %. [print [sp x]]"


How can i get this to work?
reddo "view [button {click cluck} focus [unview]]"
*** Script Error: View has no value

Another way to compile reddo.red or ...?
hiiamboris
22:18@vazub we should ask Carl about that :)
22:19@Rebol2Red what platform?
Rebol2Red
22:19@hiiamboris Windows 10
hiiamboris
22:22@Rebol2Red Confirmed! Thanks. Let me try the obvious solution...
22:23I updated it with needs: 'view now it works
Rebol2Red
22:28@hiiamboris Why does reddo "dir" not work?
*** Script Error: expand-directives does not allow word! for its code argument
hiiamboris
22:29"dir" is part of the console, not part of Red
Rebol2Red
22:30How can i know if it is part of the console?
hiiamboris
22:31I just updated it again, to support single words without explicit brackets.
22:32Script Error: dir has no value now
22:33help facilities and ls/dir/cd/pwd are all part of the console
22:33you can use the batch file if you want full support (it invokes console, so you get everything)
22:34just modify it for your paths
Rebol2Red
22:37To be sure, you mean reddo.bat?
hiiamboris
22:43Yeah ☻
Rebol2Red
22:44Just tested it. Everything seems to work now. Many Thanks!
hiiamboris
22:44:+1:
Rebol2Red
22:49Btw As far as i know is the tick before View not needed anymore
hiiamboris
22:51Yeah, you're right
Rebol2Red
22:53Thanks for confirming this. Now i know for sure.
dockimbel
23:03@vazub cos is the C-like version, concise and accepting radians, convenient for (complex) math expression. cosine is the human-friendly version, accepting degrees and not having a mangled name.

TheHowdy_gitlab
06:23@hiiamboris thx
vazub
06:37> @vazub cos is the C-like version, concise and accepting radians, convenient for (complex) math expression. cosine is the human-friendly version, accepting degrees and not having a mangled name.

Thanks for the reply, @dockimbel ! So this is merely a convenience function, for specific use cases? Interesting. However, cosine seems to accept radians as well, with /radians refinement and is of native! type, which, in my limited understanding should provide some performance benefits - is that correct? Unless I am missing something else here, I am unsure what additional cases would justify for me using cos instead of cosine, aside of somewhat lesser verbosity.

And by the way, speaking of some possible additional redundancy: %, //, mod, modulo, remainder also confuse me a little bit in terms of choice. Aside of being used in either infix or prefix scenarios, how should one proceed with deciding on what should be the most appropriate for their case? Help description states that modulo "handles errors like REMAINER", but no further details are given, so this seems to be quite abstract for me as a newcomer still.
hiiamboris
08:43https://github.com/red/red/issues/2433#issuecomment-538787348
08:44and just a bit above there are points on what to use
greggirwin
08:52@dockimbel do you and the deep core want to weigh in on :point_up:

GiuseppeChillemi
13:57If an argument is defined as: :arg, which is the difference from 'arg' when passing an integer or other arguments which are not functions? Is it equivalent or it is different in some way ?
hiiamboris
14:41try passing a paren to it

endo64
11:56We may add below difference to the wiki:
f: func [:a] [probe a]
f myword
; R2  == ** Script Error: f is missing its a argument
; R3 & Red  == myword
bubnenkoff
12:19is there any difference between:
>> a: "aaa"
== "aaa"
>> b: a
== "aaa"


and
>> a: "aaa"
== "aaa"
>> b: :a ; colon before a
== "aaa"
rebolek
12:21Not in your case, a evaluates, while :a does not, but string evaluates to itself, so it's same. But there are types where it makes difference.
GiuseppeChillemi
13:16Functions, lit-words and.. ?
13:17I remember a document written by Vladimir on this topic but I can't find it.
rebolek
13:18certainly parens and also other function-like types (natives, ops, actions, ...).Maybe I missed something

GiuseppeChillemi
22:28You can't insert into a block a RANGE (from position/to position) of another block and keep the link, can it ? You can do this only using copy but you loose the link capabilities.
greggirwin
22:33Correct. There is no concept of block "slices" in Red. I would say "at this time" but while it comes up in chat occasionally, it's not on our roadmap.
GiuseppeChillemi
22:52@greggirwin It seems there are discussions dated back to [2004](http://www.rebol.org/ml-display-message.r?m=rmlGGHC) ;) I have just found [this](https://github.com/red/red/wiki/%5BPROP%5D-Ranges)
hiiamboris
23:00Shows how high demand is ;)
GiuseppeChillemi
23:17Resistance is futile, someday your blocks will be sliced and assimilated in a composite one.

GiuseppeChillemi
15:21I am studing function passing throught function Inferface. I supposed

f: func [:arg][type? :arg] 
probe f print


Gives the same result as:
f: func [arg] [type? :arg]
probe f :print


REBOL has the same native!result, while for Red print is just a *word* in the first situation.

REBOL:

>> f: func [:arg] [type? :arg]
>> probe f print
native!
== native!
>> f: func [arg] [type? :arg]
>> probe f :print
native!
== native!
>>


RED

>>  f: func [:arg] [type? :arg]
== func [:arg][type? :arg]
>> probe f print
word!
== word!
>>  f: func [arg] [type? :arg]
== func [arg][type? :arg]
>> probe f :print
native!
== native!
>>


It is not mentioned in [RED-REBOL Differencies](https://github.com/red/red/wiki/%5BDOC%5D-Differences-between-Red-and-Rebol) and also I do not know if it is intended.
hiiamboris
15:25It is
GiuseppeChillemi
15:29I don't understand the reason. Could you explain?
hiiamboris
15:37I can only guess ☻ Maybe for more control?
15:38This behavior is inherited from R3 btw
15:40Do you like this in R2?
>> probe quote print
native
GiuseppeChillemi
15:41I have learnt something new, thanks.I will propose to add an entry to the differences document on red/doc
hiiamboris
15:46Strictly speaking it's R2/R3 difference ;)

bubnenkoff
12:10Why if we can change value of f by assigning body-of to b, but can't change a by using b in last few line:
>> f: func[] [v: [] append v "aa"]
== func [][v: [] append v "aa"]
>> f
== ["aa"]
>> f
== ["aa" "aa"]
>> f
== ["aa" "aa" "aa"]
>> 
>> b: body-of :f
== [v: ["aa" "aa" "aa"] append v "aa"]
>> 
>> b/2/1
== "aa"
>> b/2/1: "cc"
== "cc"
>> 
>> f
== ["cc" "aa" "aa" "aa"]
>> 
>> 
>> a: "aaa"
== "aaa"
>> b: a
== "aaa"
>> 
>> b: "bbb"
== "bbb"
>> a ; a still aaa
== "aaa"
>>
rebolek
12:14Because you reassign where b points to. If you need to change a from b, you need to change the block directly, not just reassign b:
>> a: "aaa"
== "aaa"
>> b: a
== "aaa"
>> change b "bbb"
== ""
>> a
== "bbb"
Oldes
12:21@bubnenkoff I don't know what you want to achieve, but what you do now is a way for a trouble! You don't have defined v inside the function as a local, so once you call the f function, the value v will be global! Check this in fresh console:
>> f: func[] [v: [] append v "aa"]
== func [][v: [] append v "aa"]
>> v
*** Script Error: v has no value
*** Where: catch
*** Stack:  

>> f
== ["aa"]
>> v
== ["aa"]
12:23I'm quite not sure if it is good that body-of does not copy the function body like Rebol does so you can mess with it like @bubnenkoff does.
ne1uno
12:25foot: the: self: shoot: your: unset!
12:26^H^H^H^H woops
greggirwin
19:18Identifying the real goal is key. There may be easier ways.

GiuseppeChillemi
09:48Is this hierarchy of values retrieving I am looking at ?
Who told f2 to take the context of f and associate to it's a in place of system/words ? Has the context of a in f2 been set at function definition or at runtime ?


a: 22
f: func [/local a] [a: 33 
	f2: func [] [print ["A value: " a]]
		f2
]


f
;f2


Result

A value:  33


(Note, the commented f2 if removed prints "a value: 33" in R2 and "Context for a is not available" in Red for reasons already explained from Vladimir months ago.)
hiiamboris
09:52body of f was bound at the time of func evaluation
GiuseppeChillemi
09:56@hiiamboris could words with no context exist and be at runtime automatically associated with the current one (if the concept of "corrent context" exists, because it seems to me we have not a current one).
hiiamboris
09:57no and no ;)
GiuseppeChillemi
09:58A double no, bingo !
09:59The context is defined at loading and creation.
13:28Another question:

when inside a function you encounter set words to static structures like:

a: "hello word!"

And you use the function multiple times, what actually happen at each round when the set-word is found ?

1) The link between the word and the context with the value is set again ?
2) It's just a printout of the things as they actually are.

hiiamboris
13:411) yes
2) I don't what you mean here
13:42you can test things yourself with probe and context? btw
GiuseppeChillemi
16:352) For a moment I supposed the SET WORD had already a link to the context and the string. But I remembered its a dynamic connection.

About encountering a set word in a funcion:
Set word to a literal: associates word -> context(word) and sets the (word) value to the literal on the right of the set word, even if it already the same. (Set = copy)
Set word to a static structure: sets the link of the word to the static structure in the context, even if the link is already present (Set = link)

17:05word -> contexts(word)-Value are dynamic and continuously established at runtime. If you have a set word to a static structure during the program flow, even if already established, Red re-sets the value in the context to the same structure. In other words, there is no connection between set word and the element on the right if the program is not running (code = data) but it is established when it is being interpreted.
17:11(I am just thinking loudly about words, values, and contexts and program evaluation and if someone wants to comment, he is welcome !)
greggirwin
19:48If not being evaluated, it's all just data.

GiuseppeChillemi
00:23@greggirwin I think mind clouds have disappeared just today.
23:04I have tried to force a loop to try what happens and I have found 3 dots in place of data inside a block.

f: func [arg1 arg2] [block: [arg1 arg2] f1 block]
f1: func [arg3] [append/only arg3 arg3 probe arg3]

f 10 20


Result is:

[arg1 arg2 [...]]


I do not know what they mean but I imagine they are there for some reason.
23:08Also, while experimenting, I have discovered that if the first argument of a function is halt than you have no error it has been called with less arguments than needed. I supposed it is wanted too.
Just change the last line in f halt and see no error being returned.
greggirwin
23:14You're appending a block to itself. The ... indicates that there's a cycle.
GiuseppeChillemi
23:20Thanks, I have imagined. Asked just to be sure.

GiuseppeChillemi
01:00In Rebol2 I can do:

>> do :print [2 + 2]
4


In Red

>> do :print [2 + 2]
== [2 + 2]


It seems I have to use a temporary word

>> p: :print p [2 + 2]
4



Is there any method to have Red act like Rebol2 does without using a temporary word ?

endo64
08:21
>> do reduce [:print [2 + 2]]
4

GiuseppeChillemi
10:25@endo64 Thanks. I admit I find Rebol 2 way of work more direct and I prefer it. Red way should have a reason for this. Do you know why there is such difference? I mean: what has driven the choice?
hiiamboris
10:47to fight variable arity
endo64
10:59@GiuseppeChillemi About, ... cycle issue, you can see the similar output for objects: o: object [x: self]
hiiamboris
14:01should we be able to convert objects and maps into each other using to or make (or at least object into map, as ordered into orderless collection)?
>> make map! object [a: 1]
*** Script Error: cannot MAKE/TO map! from: make object! [a: 1]
*** Where: make
*** Stack:  

>> object #(a: 1)
*** Script Error: object does not allow map! for its spec argument
*** Where: object
*** Stack: object
dockimbel
14:51* Map->object: would only work on a subset of possible maps.
* Object->map: binding info would be lost, making evaluation of code held inside the map erroring out.

You can still use an intermediary block to force conversions in such cases, if really needed. You can also write a routine if memory usage or performance is a show-stopper.
vazub
15:07Please, forgive my ignorance, but can anyone explain the reasoning behind a design decision to have y axis increasing from top to bottom of the display for draw dialect? I have a gut feeling that this might have something to do with the way images are represented in Red (as a 1D space by taking first row of pixels from left to right, then second row, and so on - according to the documentation), but this is just a guess.
hiiamboris
15:19@dockimbel, understood ☻
15:23@vazub common thing. Google for "screen coordinate system"
vazub
15:32@hiiamboris thanks! sorry again for the ignorance, I am just starting my learning in this direction.
GiuseppeChillemi
18:05I was trying having different versions of the same function and a way to call them. I have started with Rebol:

f1versions: reduce [
		'v1 func [arg1] [print ["arg1 is: " arg1]]
		'v2 func [arg1 arg2] [print ["arg1 is: " arg1 " arg2 is: " arg2]]
		'v3 func [arg1 arg2 arg3 /additional arg4] [print ["arg1 is: " arg1 " arg2 is: " arg2 " arg3 is: " arg3]]
]

f1: func [version] [select f1versions version]

do f1 'v1 14
do f1 'v2 15 25
do f1 'v3 16 26 36


Output is:

arg1 is:  14
arg1 is:  15  arg2 is:  25
arg1 is:  16  arg2 is:  26  arg3 is:  36



Red

f1versions: reduce [
		'v1 func [arg1] [print ["arg1 is: " arg1]]
		'v2 func [arg1 arg2] [print ["arg1 is: " arg1 " arg2 is: " arg2]]
		'v3 func [arg1 arg2 arg3 /additional arg4] [print ["arg1 is: " arg1 " arg2 is: " arg2 " arg3 is: " arg3]]
]

f1: func [version] [select f1versions version]

do reduce compose [(:f1) 'v1 14]
do reduce compose [(:f1) 'v2 15 25]
do reduce compose [(:f1) 'v3 16 26 36]

arg1 is:  14
arg1 is:  15  arg2 is:  25
arg1 is:  16  arg2 is:  26  arg3 is:  36


Red version is not so direct.

Note: I do not want to say Rebol is better than Red, I am just experimenting with this particular coding pattern.

Oldes
18:13Your coding pattern is imho very strange. I wonder which magic you will make if you would need to use the /additional refinement using your current pattern.
18:18I wonder why you just don't use something like:
f1: context [
	v1: func [arg1] [print ["arg1 is: " arg1]]
	v2: func [arg1 arg2] [print ["arg1 is: " arg1 " arg2 is: " arg2]]
	v3: func [arg1 arg2 arg3 /additional arg4] [print ["arg1 is: " arg1 " arg2 is: " arg2 " arg3 is: " arg3]]
]
f1/v1 14
f1/v2 15 25
f1/v3 16 26 36
GiuseppeChillemi
18:32Additional is there for an error.
18:33Because I have already seen that Rebol2 does not accept it.
giesse
18:38@dockimbel there are a lot of very common cases where converting from map to object is important. and, unfortunately, using intermediate block conversion does NOT work well enough. You have to do something like this:
map-to-object: function [map [map!]] [
    body: body-of map
    words: clear []
    values: clear []
    foreach [word value] body [
        append words word
        append/only values :value
    ]
    obj: construct words
    set obj values
    obj
]
GiuseppeChillemi
18:39@Oldes for 2 reasons: I am playing with the language; I am working on a way to extending the basic commands recreating automatically them from specs.
18:41Also a third one: objects can't be extended and manipulated like blocks.
18:41If you want to create a modificable library you have to clone the object.
Oldes
19:27@GiuseppeChillemi the question probably is, why anybody needs a _modificable library_. Maybe I will have to wait a few more years to see some example of good use.
endo64
19:37@giesse But map-to-object can misbehave for maps with non-word keys:
>> map-to-object probe #(a: 1 "b" 2 'c 3 :d 4 0 5)
#(
    a: 1
    "b" 2
    c: 3
    d: 4
    0 5
)
== make object! [
    a: 1
    c: 2
    d: 3
]
Oldes
19:44@endo64 that is the mentioned:

> Map->object: would only work on a subset of possible maps.
GiuseppeChillemi
19:50@Oldes Adding a new datatype and its corresponding method(s)?
pekr
19:55Why is there clearinstead of a copyin @giesse's example? Haven't seen it yet used like that :-)
hiiamboris
19:56To eliminate extra GC overhead where function is known not to be recursive
GiuseppeChillemi
20:06However, the biggest limit using this approach and other approaches is just refinements. I have found no way to pass refinement evaluation to the function returned as result. The base function must have the refinements of the returned one
20:07I have ended my solutions.
hiiamboris
20:12Yeah, refinements and function literals don't play along ;)
20:12I miss apply a lot too
GiuseppeChillemi
20:13What does apply do? (I am on mobile)
hiiamboris
20:14Question is rather - 'what *will* it do?' ;)
20:15One point would be to be able to pass arguments and refinements from one function to another without reconstructing the path
20:15Another - to call a function without evaluating it's arguments
dockimbel
20:16@hiiamboris apply is another design/implementation pitfall (reduced block vs non-reduced, named args vs providing all the args+refinements,...). Propositions are welcome (in HOF group) as I don't have the spare time to work on that.
hiiamboris
20:17Okay :+1:
dockimbel
20:17@giesse Can you provide me some use-cases to consider?
GiuseppeChillemi
20:31@hiiamboris could you provide some use examples of apply?
hiiamboris
20:34Easy ☻ Suppose you want to extend find, add your shiny epic refinement to it. E.g. /epic message. You write find/epic ... "my message" so it will do just print "my message", then call native find and return it's result. Try to implement this ;)
GiuseppeChillemi
20:38So in rebol you use apply :find [series value /epic "my message"] ?
hiiamboris
20:39I haven't tried it in R2. Try to implement it in R2 if you wish, or even using R2's apply ;)
20:40Ideally I would like to have apply that makes this task a one-liner
greggirwin
20:57:point_up: [January 19, 2020 7:51 AM](https://gitter.im/red/help?at=5e246cff0dbd9379ed625826) Added to [wiki](https://github.com/red/red/wiki/%5BDOC%5D-Object-Notes#conversions-with-map)
21:06Of course we can make the conversions work in Red, with the known limitations. The question is whether that will cause more pain and confusion. Like copying, it can be a gotcha, but something people can learn, and there are many use cases where it will work just fine. e.g., just as JSON allows keys with spaces, the vast majority of key names are word compatible.
pekr
21:30applywas part of R3 implementation - http://www.rebol.com/r3/docs/functions/apply.html

GiuseppeChillemi
00:51I do not if this could be called apply. I have created it on R2:
If you have an extended version of a function, it runs the original version applying only the arguments and refinement of the original one. The extended parameters and refinement will be available to the extended one for any processing.

myapply: func [
	{Given an extended function (with more arguments and refinements), applies
	 and run the funcion being exteded providing only the parameters and refinement 
	 present in both specs and used in the extetend function} 
	func-word [word!]
	"A function name which is an extension of another one"
	func-to-patch [word!]
	"The original function which has been extended"
	ctx [word!]
	"an argument of the function with extended parameters"
	/only
	/local 
	line-to-run 
	found-refinement 
	ref-word 
	item 
	specs
	specs-func-to-patch
	refs
] [


	line-to-run: copy []
	refs: to-path func-to-patch
	
 	specs: spec-of get func-word
 	specs-func-to-patch: spec-of get func-to-patch
 	bind specs 'ctx
 		

	
	found-refinement: false
	ref-word: false

	forall specs [
	 item: first specs 
	 either refinement? item [
	 	if (get in bound? ctx item) [
		 	if found? find specs-func-to-patch item [append/only refs to-word in bound? ctx item]
	 		found-refinement = true
	 		ref-word: true
	 	]
	 ]
	 [

	 	if word? item [
	 		if (get in bound? ctx item) [
	 			if found? find specs-func-to-patch item [
		 			either only
		 				[append/only line-to-run reduce in bound? ctx item]
		 				[append/only line-to-run in bound? ctx item]
		 		]
	 			
			]
		]
	 ]
	]
	do head insert/only head line-to-run refs
]


Lets extend a function an process extended refinements

newfind: func append spec-of :find /epic [
	if epic [print "--- !!!!! This is epic !!!!! ---"]
	probe myapply 'newfind 'find 'series
]


Test it:
newfind [a b c] 'b 								
newfind/epic [a b c] 'b
newfind/epic/tail [a b c] 'b
newfind/tail/epic [a b c] 'b

[b c]
--- !!!!! This is epic !!!!! ---
[b c]
--- !!!!! This is epic !!!!! ---
[c]
--- !!!!! This is epic !!!!! ---
[c]


@hiiamboris , was this the function you where asking for ?
00:53I think it can be easily ported to Red.
01:07This one:
newfind: func append spec-of :find /epic [


Should be changed to
newfind: func append copy/deep spec-of :find /epic [

giesse
05:55@dockimbel the main issue is that objects cannot be extended, but maps can. so creating a map and then converting it is easier; creating a block and using construct is equally tricky, so i find the map way easier to deal with. YMMV. other use cases would be something like JSON, where the result of the conversion has to be map for generality, but if you know exactly what you are dealing with you may want to convert to object for other reasons (eg. binding).
hiiamboris
09:51@GiuseppeChillemi :clap: I'm using a very similar approach in my CLI btw
Although there are some deficiencies:
>> newfind reduce ['a off 'b] no
none
== none
>> f: does [print "CALLED"] newfind reduce ['a :f 'b] :f
CALLED
none
== none

And it isn't clear what role your found-refinement and ref-word play. And then what if I wish to rename some refinements, or add those not provided to my newfind? Or if I wrote the spec of newfind by hand, but spec of find changes in the new release? Details, details...
But the point of exercise was to find out that this task is not doable without spec parsing and path reconstruction. And that slows your code by an order of magnitude.
GiuseppeChillemi
10:23@hiiamboris Thanks. I will take a look at the deficiencies you have spotted.
About your observations: renaming refinements and adding arguments is planned in the future. Also, it is planned to have the ability to extend datatypes and change description. Actually, it is an exercise to for me to test what can be done.
Ref-word and found-refinement could probably be removed but I have completed the function at 02:00 AM so code cleaning should be done better.
10:24About your CLI, It is on my TODO list to learn how to use it.
Oldes
11:26:point_up: [January 19, 2020 8:50 PM](https://gitter.im/red/help?at=5e24b3154c1f9679ec14a7b3) @GiuseppeChillemi there definitely must be better ways how to do it, than the way you are walking. I wonder if you have more concrete idea, how such a _new datatype_ should be constructed and used. But it is out off topic for a /help channel.
GiuseppeChillemi
12:52The datatype system is half done. I am experimenting with different methods for extending functions like AT, SELECT, PICK, without rewriting everything. As said, it's just an experiment but functions like myapply are at its base to avoid much work.
13:45@hiiamboris About changing the name of the argument or refinement, it could be done with either a positional approach (easier) or with an additional block with base/renamed elements. They are all options. To extend just Red/Rebol function, having the original specs and additional ones could save you a lot of work. The only problem you can have is if function arguments name will change. This would break your extended code. The absolute position approach will shield your code for such changes.
20:32@hiiamboris I have seen the mistake that causes the first example problem: words with false are considered unset. What do you suggest to check if also a word is set in the context ? words-of and a find on it or something else ? (and quicker !)
hiiamboris
20:51Decouple in from get? ;)
GiuseppeChillemi
21:04I can't, get confessed to love in and I will not divide an happy couple!

bubnenkoff
13:53Is there any difference between do and do-file?
>> do-file %app.red
hi
>> 
>> do %app.red
hi
>>
rebolek
14:04 @bubnenkoff ? do-file -> Internal use only. So just forget about it :smile:
bubnenkoff
14:16It's works under the hood of Red?
14:16How get list of files? I am getting error:
>> f: list-dir to-path get-current-dir
*** Access Error: cannot open: %/D/code/2020/redparse/D:\code\2020\redparse\/
rebolek
14:17f: read %./
14:17path! type is not file path, do not confuse them!
pekr
14:17in console, you can use just dir
rebolek
14:18dir is fine for printing, but you can't assign its output to a word.
bubnenkoff
14:29> f: read %./

That's work! But how I can use list-dir?
rebolek
14:31@bubnenkoff why don't you try help?
>> help list-dir
USAGE:
     LIST-DIR dir

DESCRIPTION:
     Displays a list of files and directories from given folder or current one.
     LIST-DIR is a function! value.

ARGUMENTS:
     dir          [any-type!] "Folder to list."

REFINEMENTS:
     /col         => Forces the display in a given number of columns.
        n            [integer!] "Number of columns."

>> list-dir %./
        make-csv.red    gui-conso...    CODE_OF_C...    usr/            BSL-Licen...    cleaned.red     libRedRT-...    boot.red        red-063
        compiler.r      crush.dylib     version.r       stylize.exe     red.r           quick-test/     runtime/        tests/          .gitignor...
        pp.red          utils/          docs/           .appveyor...    bridges/        .editorco...    README.md       system/         user.red
        CONTRIBUT...    csv-test/       .github/        rebol.exe       rebol           environment/    gui-console     build/          custom.red
        libRed/         .git/           rebuild         modules/        lexer.r         run-all.r       .travis.yml     BSD-3-Lic...    usage.txt
        console
bubnenkoff
14:32Yes I tried:
>> f: list-dir %./
	app.red           	backup.txt        	r1.r              	r2.r              	r3.r              
*** Script Error: f: needs a value
*** Where: f
rebolek
14:32***Displays** a list...* - displays being the most important word here.
14:34It’s basically print read %./ (plus formatting) and as print, it doesn’t return value.
bubnenkoff
14:47Thanks! Now I am have trouble with filter function that I did:
>> foreach file read %./ [if find file ".r" print file]
app.red
*** Script Error: if does not allow unset! for its then-blk argument
rebolek
14:49@bubnenkoff of course, if needs block! -> if find file %.r [print file] (I also changed your suffix to file! from string!. Not necessary, but IMO it’s better to use appropriate datatype).
14:51Also, there is suffix? function, that may be useful for this kind of checks, e.g.: equal? %.red suffix? file
14:53I’m not sure what you are trying to find, but I think you may have some false positives:
>> if find %bad.robot.jpg ".r" [print "found"]
found
bubnenkoff
15:09Oh! I get it work!
foreach f files [if find f ".r" [print f]]

but is there any way to filter **only** .r files but end exclude all other like .readme?
rebolek
15:10@bubnenkoff As I wrote, suffix? is your friend: if equal? %.r suffix? f [print f]
pekr
15:14@bubnenkoff I always liked the remove-eachfunction, though it needs to reverse to condition naturally:

>> remove-each file data: read %./ [not find file ".r"]
>> data
== [%boot.red %compiler.r %lexer.r %libRedRT-extras.r %particles.red %red.r %run-all.r %version.r]
15:14It's kind of a filter function imo ...
rebolek
15:14@pekr this still has false positives problem
pekr
15:15You mean not using suffix?
rebolek
15:15yes, as @bubnenkoff wrote: " is there any way to filter only .r files but end exclude all other like .readme?"
pekr
15:16You can use find/tail
rebolek
15:16yes, that's an alternative way
pekr
15:17In the past I also opted for keep-eachfunction, so that you don't have to reverse the condition, especially if there is multiple conditions there ....
15:18But I suspect such wrapper mind be easy to write around remove-each? :-)
bubnenkoff
15:18it's works!
>> foreach f files [if equal? suffix? f ".r" [print f]]
r1.r
r2.r
r3.r

Oldes
15:20This is shorter:
foreach f files [if %.r = suffix? f [print f]]
15:21And this probably faster:
foreach f files [if parse f [thru %.r end][print f]]
greggirwin
18:00:point_up: [January 23, 2020 8:17 AM](https://gitter.im/red/help?at=5e29b91a01914e3e04357ec3) @pekr, here's an old one:
keep-each: func [
	"Keeps only values from a series where body block returns TRUE."
	'word [get-word! word! block!] "Word or block of words to set each time (will be local)"
	data  [series!]
	body  [block!] "Block to evaluate; return TRUE to collect"
][
	remove-each :word data compose [not do (body)]
	data
]
e.g. [
	filter: :keep-each
	filter x [1 2 3] [x = 2]
	filter x [1 2 3] [odd? x]
	filter res [1 2 3] [odd? res]
	filter [x y] [a 1 b 2 c 3] [all [odd? y  'c = x]]
	filter x [(1 2) (2 3) (3 4)] [x = first [(2 3)]]
]
18:09@Oldes %.r = suffix? f is so nice and clear. If you're really printing, that may hide any speed gains from parse, but let's see...using 10'000 random files, of which 223 have a %.r suffix:
Time         | Time (Per)   | Memory      | Code
0:00:00.012  | 0:00:00.012  | 440284      | [n: 0 foreach f files [if %.r = suffix? f [n: n + 1]]]
0:00:00.014  | 0:00:00.014  | 284         | [n: 0 foreach f files [if parse f [thru %.r end] [n: n + 1]]]
0:00:00.244  | 0:00:00.244  | 33288       | [foreach f files [if parse f [thru %.r end] [print f]]]
0:00:00.287  | 0:00:00.287  | 473444      | [foreach f files [if %.r = suffix? f [print f]]]
18:10Memory use for suffix? isn't consistent, due to a single run. Here's another:
Time         | Time (Per)   | Memory      | Code
0:00:00.014  | 0:00:00.014  | -1637792    | suffix'n
0:00:00.014  | 0:00:00.014  | 284         | parse'n
0:00:00.226  | 0:00:00.226  | 33288       | parse'
0:00:00.262  | 0:00:00.262  | 537468      | suffix'
hiiamboris
18:10parse variant is buggy though ;)
greggirwin
18:11Impossible, I trust every snippet ever posted to be correct. ;^)
hiiamboris
18:36
>> m: #()
== #()
>> m/(#x): 1
*** Script Error: issue! type is not allowed here
*** Where: set-path
*** Stack:

Is there a reason?
dockimbel
18:39@qtxie ^---
hiiamboris
18:39Even this
put [] #x 1
*** Script Error: put does not allow issue! for its key argument
*** Where: put
*** Stack:
18:40Issue has too many issues... ):
greggirwin
18:41It's the subtle difference between any-word! and all-word!.
18:43For maps a little thinking is needed. Should refinement and issue be supported, formed, disallowed because either could work and consensus will be hard?
hiiamboris
18:53just not coerce issues to other words and back, or what do you mean?
greggirwin
18:59We can't coerce back if we change to another word type, because the casting is lossy.

1) Support them directly. Ugly in use, but flexible.
2) Form, (mold actually), which is still lossy, and is something users can do themselves.
3) Just say No. Doesn't rule out #2, or doing #1 later.
19:01Coercing to plan word seems worst, because it doesn't look lossy, and may lead to subtle overwrite bugs.
hiiamboris
19:03I'm for direct support. What I wanted is just a map with issue test snippets right now.. to have keys like #1234
19:03I'm molding as a workaround for now, but I see no reason not to support issues directly
rebolek
19:04Having issue! as key makes a lot of sense to me.
Oldes
19:04[![image.png](https://files.gitter.im/red/help/i6gs/thumb/image.png)](https://files.gitter.im/red/help/i6gs/image.png)
19:04[![image.png](https://files.gitter.im/red/help/oGAP/thumb/image.png)](https://files.gitter.im/red/help/oGAP/image.png)
19:04[![image.png](https://files.gitter.im/red/help/rP6z/thumb/image.png)](https://files.gitter.im/red/help/rP6z/image.png)
19:04[![image.png](https://files.gitter.im/red/help/l46d/thumb/image.png)](https://files.gitter.im/red/help/l46d/image.png)
19:04[![image.png](https://files.gitter.im/red/help/w28n/thumb/image.png)](https://files.gitter.im/red/help/w28n/image.png)
19:04[![image.png](https://files.gitter.im/red/help/gXsl/thumb/image.png)](https://files.gitter.im/red/help/gXsl/image.png)
hiiamboris
19:04crashdump? ;)
dockimbel
19:05He just felt asleep on his keyboard. ;-)
hiiamboris
greggirwin
19:05I agree on support I think, because we have the same issues with blocks when referencing them. So there's a clear precedent.

You guys beat me to jokes. ;^(
dander
21:30This was my [HOF version](https://gist.github.com/dander/47d10aa43d04bfcd27080ba6f3cf04ba#file-find-pattern-red-L54) of filtering files on one or more extensions. Trying to prioritize readability here, but involves more code than the previous examples
sources: get-files/filter dir ends-with extensions
greggirwin
21:58:+1:
Oldes
22:04Ah.. sorry.. that was our cat!
greggirwin
22:05:^) You should name it crashdump.
dander
22:05that seems like a very appropriate name for a cat 😸
Oldes
22:09I quite don't undtestand how she did it.. just by sitting on a keyboard.
dander
22:10It's always amazing to me what a computer can do with a baby or cat sitting in front/on it
greggirwin
22:11It's how most cat pictures get on the internet. Selfies.
22:11I feel someone ready to call me out for cat chat.

bubnenkoff
06:31What extension should use Red apps? I know that base is .red, but I is there any cases when .r is using?
06:41Hm, strange. Why word get only one .r file:
>> list-of-rules: foreach f files [if equal? suffix? f ".r" [f]]
== %r3.r
>> 
>> foreach f files [if equal? suffix? f ".r" [print f]]
r1.r
r2.r
r3.r
toomasv
06:44You are not collecting these files. In each loop it returns current file, the last stays.
bubnenkoff
06:57
>> files
== [%app.red %backup.txt %r1.r %r2.r %r3.r]
>> 
>> 
>> foreach f files [if equal? suffix? f ".r" [append list-of-rules f]]
== [%r1.r %r2.r %"" %r1.r %r2.r %r3.r]


Do I now collect them? Why so strange result with duplicates?
pekr
07:03Your console session is broken. Try to clear/reset your list-of-rules first ...
07:04
>> files: [%app.red %backup.txt %r1.r %r2.r %r3.r]
== [%app.red %backup.txt %r1.r %r2.r %r3.r]
>> list-of-rules: []
== []
>> foreach f files [if equal? suffix? f ".r" [append list-of-rules f]]
== [%r1.r %r2.r %r3.r]

bubnenkoff
07:11thanks! Can be this code rewritten to make foreach return values instead of appending them? Or what best practice for writing such functions?
toomasv
07:29Use collect/keep.
greggirwin
08:22:point_up: [January 23, 2020 11:31 PM](https://gitter.im/red/help?at=5e2a8f29f85dba0aab05a6b1) @bubnenkoff %.r is the extension used for Rebol files.
bubnenkoff
08:30> Use collect/keep.

I know how to use it inside red parse, but have not ideas how work with it in classic red. Something like?
l: foreach f files [if equal? suffix? f ".r" [collect keep f]]


And it's seems that keep can't use outside red parse:
>> ? keep
No matching values were found in the global context.
GiuseppeChillemi
08:36@bubnenkoff Yes, it can't. It is a word of parse dialect and not e standalone function.
bubnenkoff
08:38So the function can't be rewritten to return result to word? Or it's absolutely normal that it looks so?
toomasv
08:40Wrong. Please use help on collect.
bubnenkoff
08:46Bingo!
l: collect [foreach f files [if equal? suffix? f ".r" [keep f]]]
== [%r1.r %r2.r %r3.r]
08:46But why keep works outside parse?
rebolek
08:47This has nothing to do with parse at all
bubnenkoff
08:48I am a little bit confuse how to know how every words work in different dialect and if it can\cannot be used there
toomasv
08:57Research and practice. And then practice.
loziniak
15:31Is there any possibility to use refinements on functions programatically?
15:32Like if I wanted to use refinement or not depending on some condition, without repeating all other function arguments?
15:34like f/:cond xyz
15:35probably just construct the call dynamically, then do?
rebolek
15:36@loziniak Right, right now that's the only way. Once we get apply it gets better.
greggirwin
18:29:point_up: [January 24, 2020 1:48 AM](https://gitter.im/red/help?at=5e2aaf4d44c076313cd862ae) @bubnenkoff each dialect defines its own rules. Sometimes the same names will be used, e.g. copy, collect, and keep so they align with standard Red functions, but they may behave differently. It may seem strange at first, but it becomes natural before too long for most people.
Respectech
19:03@bubnenkoff Carl, the creator of Rebol, wanted to create a system that allowed people to create dialects for domain-specific tasks. This would be like if you went to a conference and in one room, there were a number of astronomers. In another room, there were doctors. And in another room, there were lawyers. Another room had stock analysts. They might all be speaking the same language, but they would be using dialects to more efficiently communicate with others in the same specialty.
19:04We could live without parse. But we wouldn't be as effective without it, and our code would be more complicated.
19:06Also, in the military, they may use the word asset. The military's meaning of asset would be different than the financial analyst's meaning of asset.
GiuseppeChillemi
23:07@bubnenkoff Have you read Rebol/Core manual up to parse?

anonymouXnash
10:34
>_apt update
10:34` apt
10:35`git clone https://github.com/anonymouXnash
hiiamboris
21:44@GiuseppeChillemi re: starter example
Can't write you one, but here's some ideas:
- call a function with the code (which is data) in question
- have 2 states - do-evaluation or parse-evaluation - there
- in do-mode, use do/next and check the mode again (switch if needed)
- in parse-mode, define a rule exit that sets the position and breaks out of parse, then after a break (in do-mode again), continue from that position
21:45The biggest headache will be to support (if you need it) this in inner nested blocks and when leaving those
GiuseppeChillemi
21:50@hiiamboris could be done at pre lexer level?
hiiamboris
21:56Neither in pre-load nor (reliably) after lexing. You need to evaluate your code, to be aware of definition changes since the initial boot-up. E.g. you think + is an operator, but at some point it may change into a value or a function and you need to be up to date with this change. The only way to be up to date is to evaluate ;)
21:57If your switch is static enough that you pretty much know the outcome in advance, then just resort to macros (#if, #either, #switch, #case).
GiuseppeChillemi
22:12Well, I do not have enough knowledge to understand the pre lexer and after lexer and macros level but the do/next and switching to parse is at my reach.
hiiamboris
22:12:+1:
GiuseppeChillemi
22:13Also, seeking docs and examples on pre lexer, could you point me to something?
hiiamboris
22:14> Well, I do not have enough knowledge to understand the pre lexer and after lexer and macros level but the do/next and switching to parse is at my reach.

pre-lexer is just a big string, system/lexer/pre-load thing abuses that
after lexing it's a block of Red values, there goes preprocessor and expands macros
then goes do on the result
22:15> Also, seeking docs and examples on pre lexer, could you point me to something?

search wiki for pre-load, there must be something

Rebol2Red
16:26 In Rebol we can do this:
img1: make image! 100x100
img2: make image! 10x10

; copy image img2 into img1 
xy: 10x10
change at img1 xy img2


Why can't we do this in Red anymore?
*** Script Error: change does not allow image! for its series argument

If there is no reason why not then should i issue a wish for it? I could really use it.
hiiamboris
16:42Do you realize you're asking it to change a single row in img1 to unrolled img2?
16:44I would suspect what you really want is this:
draw img1 compose [image img2 (xy)]
Oldes
16:47I'm using this Rebol method quite extensively.. it should be supported in Red imho.
hiiamboris
16:48And what if we actually want to change pixels.. sequentially?
Oldes
16:49I don't know what you mean.
hiiamboris
16:51Okay, like this I mean:
>> i1: make image! 2x2
>> i2: make image! [1x4 255.0.0]
== make image! [1x4 #{FF0000FF0000FF0000FF0000}]
>> head change i1 i2
== make image! [2x2 #{FF0000FF0000FF0000FF0000}]
Oldes
16:53I have: make image! [2x2 #{FF0000FFFFFFFF0000FFFFFF}]
hiiamboris
16:54Yes, I imagined.
16:55In my example, I'm ignoring dimensions and treat images as series of tuples. (I made it up just to show the intent)
dockimbel
16:55@Rebol2Red
> Why can't we do this in Red anymore?

Which previous version of Red did support that?
Oldes
16:56@dockimbel he consider Rebol to be Red's ancestor. So the answer is Rebol.
17:00@hiiamboris I'm using this technique to pack hundreds of small images into texture atlases. For me it's the most lightweight and pixel precise way, which I can use without any OS (or external) dependencies. I was using ImageMagick before I found I could use Rebol directly.
hiiamboris
17:02I see. Good argument.
dockimbel
17:09IIRC, it is a pending feature on @qtxie's todo list for images.
Oldes
17:10@hiiamboris Btw.. this is also useful (maybe that is what you mean with _sequentially_):
>> i1: make image! 2x2
== make image! [2x2 #{FFFFFFFFFFFFFFFFFFFFFFFF}]
>> change i1 #{112233FF}
== make image! [2x2 #{112233FFFFFFFFFFFFFFFFFF}]
hiiamboris
17:15Yes. That's what I mean. I understand it's possible, but it's just to-binary on an image is a VERY slow operation ☻
Rebol2Red
19:22@dockimbel glad to hear it is on the todo list. It will be very useful. See the examples at http://www.rebol.com/docs/image.html Some things already works and some do'nt.
19:41@hiiamboris :point_up: [27 januari 2020 17:42](https://gitter.im/red/help?at=5e2f12df44c076313cf6b05d) This is just what i needed thanks
giesse
21:47@hiiamboris perhaps as binary! should work with image!? (Don't have a /View build handy to check)
hiiamboris
21:58No, the problem is that it gets the bits in internal ARGB format and has to reorder all that into Red's own

loziniak
09:01The fact, that image! is sometimes indeed treated as a kind of 2D series! may be additionally confusing: https://doc.red-lang.org/en/datatypes/image.html#_manipulation

bubnenkoff
12:55How to remove word?
rebolek
12:56what word, where and why?
bubnenkoff
12:58x: "abc"
12:58I want to make as x was not declared
rebolek
12:58Ok and why?
12:58unset 'x
12:59But the question is why, maybe there's a better way.
bubnenkoff
12:59oh, I forgot about '
12:59I am just learning, nothing more for now
rebolek
12:59ok :)
vazub
20:36Sorry if this is a layman's question, but why do these two commands provide different results? One is a mere hex byte (as I would expect), and another is the same byte but padded with zeroes to the left.
>> make binary! [98]
== #{62}
>> to binary! 98
== #{00000062}
hiiamboris
20:37'98' is a 32-bit integer value
20:38
>> to binary! to char! 98
== #{62}

may be what you want
greggirwin
20:39Be sure to compare one change at a time.
>> make binary! [98]
== #{62}
>> to binary! [98]
== #{62}
>> to binary! 98
== #{00000062}
>> make binary! 98
== #{}

And please add to https://github.com/red/red/wiki/%5BDOC%5D-%60to%60-vs-%60make%60 to help others (beat you @hiiamboris ! :^).
hiiamboris
20:40dammit! :D
greggirwin
20:41Somewhere someone is looking for a slow mouse emoji. :^)
hiiamboris
20:42this is not fair - my browser hanged :)
greggirwin
20:42A likely story.
vazub
20:42thanks @hiiamboris and @greggirwin ! I was oblivious to the fact, that I didn't provide spec-block in tocommand
greggirwin
20:42Happens to us all @vazub.
vazub
20:50Why would a spec-block change the outcome? Again, sorry for my confusion, but i was looking at this guide - https://doc.red-lang.org/en/datatypes/binary.html - and it doesn't show the use of a block as an argument to to binary!. What are different semantic meanings in these two cases? (with and without [])
greggirwin
21:16When you use a block spec, it treats each value as a byte or series of bytes.
>> to binary! [98 99 #"d" "ef" [103 104]]
== #{62636465666768}
vazub
21:26@greggirwin and if you don't, it just treats the number as a Red-default integer (32bit), as @hiiamboris mentioned earlier... Now I get it, thanks! :)
By the way, a small suggestion if I may - it might be useful to have this note in the guide for binary! datatype, wouldn't you agree? I suspect I wasn't the first and wouldn't be the last one to ask this question.
greggirwin
21:29Of course, docs always need to be improved. I created a ticket for it.
vazub
21:32thanks, @greggirwin! :)
meijeru
22:52Inspired by the above, I did some testing and stumbled on two issues (#4272 and #4273).
hiiamboris
23:12:+1:

bubnenkoff
08:33I need to get full path. But next code is returning only xml files:
xml-files: read %/C/current_month/notice/notification_Moskva_2019020200_2019020300_001.xml/
list-of-files-for-processing: collect [foreach f xml-files [if equal? suffix? f ".xml" [keep f]]]

like:
== [%fcsNotificationEA44_0373200101018000262_19160099.xml %fcsNotificationEA44_0373200101018000263_19160346.xml]


How to get full-path?
rebolek
08:36you can either rejoin [your-path file] or try clean-path your-file
bubnenkoff
08:39Can it be shorten?
xml-folder: %/C/current_month/notice/notification_Moskva_2019020200_2019020300_001.xml/
xml-files: read xml-folder
list-of-files-for-processing: collect [foreach f xml-files [if equal? suffix? f ".xml" [keep rejoin [xml-folder f] ]]]


or it's right way?
rebolek
08:40You can use %.xml instead of ".xml", now it's one char shorter. :)
bubnenkoff
08:40so this code is fine?
rebolek
bubnenkoff
08:45And what about naming? What is the best practice? For example next code can be written in different ways:
foreach _file list-of-files-for-processing [
    file: read _file
	; ...
	]
		
foreach file list-of-files-for-processing [
    file: read file
	; ...
	]	
	
foreach _ list-of-files-for-processing [
    file: read _
	; ...
	]
rebolek
08:51what I use is something like foreach file files [file: read file]. If I need to keep the filename, I change it to foreach file files [data: read file]
08:51list-of-files-for-processing is too long for my taste
pekr
08:53All good advices. Try to keep the naming to 2-3 segments max. file-listwould be ok too ....
Dooview_gitlab
10:32Hello, I haven't used Red in awhile because it didn't support 'ftp'. Is this now supported with 0.64? And if so where can I find the documentation? Thanks in advance for an answer.
greggirwin
16:47@Dooview_gitlab no FTP yet. Will come after ports in 0.7.0.
16:50@bubnenkoff another way to filter: remove-each f xml-files [%.xml <> suffix? f]
16:52On naming, most of the time you can use undecorated words without conflict.
foreach file files [
    data: read file
    ; ...
]

You should also read https://doc.red-lang.org/en/style-guide.html

GalenIvanov
08:42
f: func[s][
    foreach [a b] s [
        prin rejoin [a t: any[b ""] t]
    ]
]

f "abcde"
print ""
f "abcdef"

abbcdde
abbcddeff
>>
08:44It works as expected in the GUI console on Win 8.1 as is the above snippet shows. Can someone try it for me on Linux?
rebolek
08:54@GalenIvanov I have same result on Linux.
08:55
>> f: func[s][
[        foreach [a b] s [
[            prin rejoin [a t: any[b ""] t]
[        ]
[    ]
== func [s][foreach [a b] s [
    prin rejoin [a t: any [b ""] t]
]]
>> f "abcde"
abbcdde
>> f "abcdef"
abbcddeff
GalenIvanov
09:16> It works as expected in the GUI console on Win 8.1. Can someone try it for me on Linux?
@rebolek Thanks! It was my fault - the unexpected behaviour comes when I printed what the function returns.
greggirwin
19:58@GalenIvanov note that a, b, t won't be captured, since you're using func instead of function.

vazub
12:29 Is there a way to input and print combined Unicode codepoints? For example, I want to use digit 1 with an overline as one symbol. This doesn't work for me:

>> print rejoin [#"^(0031)" #"^(0305)"]
. Any ideas?
hiiamboris
12:39not implemented
12:39some info here https://github.com/red/red/wiki/[PROP]-Unicode-Issues-with-Proposed-Resolutions
12:40for now, if you need it badly, download unicode tables and do your own composition
vazub
12:51understood, thanks
GiuseppeChillemi
16:51Is it possible to add classification custom tags to VID elements and then search for elements with specific tag(s) and get the element word ?
hiiamboris
17:22/extra field is yours to abuse
GiuseppeChillemi
17:32@hiiamboris Thanks, and how to have the list (words) of all elements I have created?
hiiamboris
17:40that's up to you to design
17:40foreach-face is your friend I guess
GiuseppeChillemi
18:53So, no face word available?
hiiamboris
18:55no idea what you mean by face word ☻
GalenIvanov
19:03@greggirwin Yes, thank you!
greggirwin
19:11:point_up: [February 2, 2020 11:53 AM](https://gitter.im/red/help?at=5e371ab3dc52c34ace405891) No, you can't go from a value to a word that refers to it directly. As @hiiamboris said, you have to build that yourself, either including the word in extra too, or walking words to look for those that refer to an object (in this case), which is very brute force, but can work fine. It's not hard to do yourself, but it *is* harder to generalize, because more than one word can refer to the same value. The "harder" part is not every user has the same needs.
GiuseppeChillemi
19:53@hiiamboris I still confused about the correct terms, especially when they belongs to VID/VIEW. I will search for a glossary.
@greggirwin We have discussed this in the past with Vladimir but I supposed that VID maintains a list of his elements together with their words.
greggirwin
19:55> I supposed that VID maintains a list of his elements together with their words.

It does not.
19:56There is no "VID Context".
GiuseppeChillemi
19:56/extras: [myname ] could be a good place.
19:58I have just to understand how to set it when the layout is built.
20:00@greggirwin So, you are telling me using a-button: button on-something [] a-button: is in the global context ?
greggirwin
20:00There's an easy way to find out. :^)
GiuseppeChillemi
20:00I knew you would answer this !
20:01I have just written it to see your answer happening !
20:04@greggirwin
Here it is the answer:

>> view/no-wait [aword: button on-click [unview]] probe aword
make object! [
    type: 'button
    offset: 10x9
    size: 78x27
20:07But it is not so simple:

b: make object! [aword: none]
view/no-wait [b/aword: button on-click [unview]] probe b/aword

*** Script Error: VID - invalid syntax at: [b/aword: button on-click]
*** Where: do
*** Stack: view layout cause-error

20:08Having a context around words seems not supported
greggirwin
20:14Correct.
20:14That feature idea comes up from time to time.
GiuseppeChillemi
20:18Its not bad. You can easily use the context to define the data structure surrounding the layout. Also words-of would do (part of) the magic for my starting question.
greggirwin
20:25I don't remember if there are deeper issues, which @dockimbel or @qtxie might recall. The basic change, where set-word? valueis checked (line 646) and where it's set (line 727) won't be hard to change.
20:26@rebolek (or anyone else), do you know if there's a reason this was never done?
hiiamboris
20:45was there ever a need?
GiuseppeChillemi
21:23@hiiamboris I see some applications for accessing tables rows contained in an object but I need more time to have a clearer idea.
Actually I am working on auto composing code to display table records and modify them but I am still at the start of this task.
greggirwin
21:48Not a desperate need, for me. The larger applications I wrote were still manageable with naming conventions, though I will think about this more, especially in the context of tooling and two-way binding. As an example, imagine a User editor; just a form for editing users. How do you do it if you want to have 2 open at the same time, for different users? It would be nice to bind an instance of a form to an associated "record".

R2 exposed face/style internals, which gave you control, but you also had no choice as to whether to use them. e.g. having to know what facets or functions to use in combination, so lists and scrollers stayed in sync with data, when to refresh, etc. Accessors were added later, and helped some. When it comes time to do our own GUI system, there's a lot to think about, in how to facilitate tooling and higher level features.
GiuseppeChillemi
23:38I see that VID dialect does not accept objects words event for its init values:

z: [a "hello" b "world"] 
view [aword: button z/a on-click [unview]] 
*** Script Error: VID - invalid syntax at: [z/a on-click [unview]]
*** Where: do
*** Stack: view layout cause-error


Can't see the reason but there should be to have such limitation.

greggirwin
02:11R2 allows it. Something to think about.
GiuseppeChillemi
07:36Yes, as it does not permits expressing data as datarow/column, and similar, which are used often.
rebolek
07:42@greggirwin IIRC something about getting path is more expensive than getting word.
GiuseppeChillemi
07:49@rebolek if you talk about data access speed, data manipulation masks do not need them.
07:51Also, which is the lifespan of the element, is it used only to get its value at layout creation or is it used after that phase?
rebolek
08:04@GiuseppeChillemi I'm not going to defend it, I'm not a great fan of it, I don't see problems with paths there. Make a wish on REP and I would support it.
GiuseppeChillemi
08:13@rebolek Ok, I will make the wish.

Under the light of your CSV codec and extended use of paths to access data it becomes more important. (I thought it was only object related but it is path related)

planets: [
	#(Name: "Mercury" Mass: 0.055 Orbit: 0.4)
	#(Name: "Venus" Mass: 0.815 Orbit: 0.7)
	#(Name: "Earth" Mass: 1.0 Orbit: 1.0)
	#(Name: "Mars" Mass: 0.107 Orbit: 1.5)
]

>> view layout [button planets/1/name on-click [probe face/text unview]]
*** Script Error: VID - invalid syntax at: [planets/1/name on-click [probe face/text unview]]
*** Where: do
*** Stack: view layout cause-error

08:15To use proper vocabulary, how to you call element parameter in BUTTON ? The data element ?
Oldes
09:57I still think that when we are talking about improvements, get-word! and get-path! datatypes should be supported, so the code would be:
view layout [button :planets/1/name on-click [probe face/text unview]]
09:58Here in github the color syntax is still wrong, but in modern editors supporting Red/Rebol syntax, the get-* variants would increase readability quite a lot.
hiiamboris
11:34> IIRC something about getting path is more expensive than getting word.

that was about Draw ;)
rebolek
11:35@hiiamboris Ah, thanks!
proksi21
14:26Hey guys, is there a way to create app without popping up console window?
I’ve achieved this by “Needs: View”, but it adds 300kb to my exe. Maybe there’s another way?
hiiamboris
14:35use flip-exe-flag command in Red console, then mpress or upx --best your exe
proksi21
14:37Thnx, I’ll give it a try
hiiamboris
14:38as an alternative to flip-exe-flag you can also add config: [sub-system: 'GUI] to the script header
proksi21
14:47And then I compile as usual console app?
14:47Or with target Windows?
hiiamboris
15:24Yeah as usual.
15:37actually, -t Windows might even produce a smaller exe
greggirwin
20:32> To use proper vocabulary, how to you call element parameter in BUTTON <ELEMENT> ? The data element ?

We usually say facet.
GiuseppeChillemi
21:53So, <ELEMENT> is the facet?
21:53@greggirwin
greggirwin
22:55Yes, what other systems call a property or attribute. Those words are sometimes used as well. The term is most prominently used [here](http://rebol.com/docs/view-guide.html), and Red hasn't pushed hard on its use, but it's a nice word in the context of GUI objects, because you can "look at" a particular facet of, e.g. a gem. Just searching, I found other good interpretations:

- One of numerous aspects, as of a subject
- A little face
- A distinct feature

GiuseppeChillemi
18:37I don't see a -wish- entry in Red github page, only Issues. Should I write my request there ?
ne1uno
18:48is this a curated list? https://github.com/red/REP/labels/Wish
18:48https://github.com/red/red/issues?q=is:issue+sort:updated-desc+is:open+label:type.task.wish
hiiamboris
18:58@GiuseppeChillemi wishes go to https://github.com/red/REP/issues
GiuseppeChillemi
19:52Request for path use for facets is located [here](https://github.com/red/REP/issues/65). @Oldes Why don't you add you request too ?

proksi21
14:07Hey! Can’t find any crypto functions in docs. Does Red have AES and RSA out of the box?
rebolek
14:08It would be nice, but there are no cryptographic functions available yet.
loziniak
14:11Just hashes – MD5, SHA etc.
14:11see function checksum
14:12I'm currently working on an AES encryption with libssl bindings.
14:12I can post it here when it's done.
proksi21
14:14That would be great!
14:17You can even dm me, and I’ll try to help with RSA and other useful stuff (I’m good with crypto, but discovered Red about a week ago. It seems promising.)
loziniak
14:19You can check @bitbegin's [eth-wallet](https://github.com/bitbegin/eth-wallet), he's done some good work there.
rebolek
14:22I believe cryptographic functions will be available because Red is going to need them for TLS/HTTPS anyway.
proksi21
14:24@loziniak thanks, I’ll have a look!
14:25@rebolek yes, it’s absolutely must have
pluckyporcupine
19:37so I'm trying to get this tutorial code (https://hastebin.com/yutuliteki.php) to run and it's telling me the following: *** Script Error: VID - invalid syntax at: [piece button 60x60]
19:37this was originally REBOL code. I've tried looking at the documentation for "style" and can't seem to figure out what is different
hiiamboris
19:49Red styles require a set-word: style piece:
19:50Also, Red uses native button control, so you better replace it with base
19:50edge you should remove
pluckyporcupine
19:50does
edge
need replaced or?
hiiamboris
19:50style piece: base coal 60x60 on-down [... style works for me
pluckyporcupine
19:51okay, awesome, thanks. that helps a ton. will make a note of all of this for future reference :D
hiiamboris
19:52> does
edge
need replaced or?

You can re-create it using draw, if you wish
pluckyporcupine
19:52yeah, I ran it and see that it seems to be working without
edge
, I'm assuming because it's using
base
instead of
button
greggirwin
20:33:point_up: [February 6, 2020 12:52 PM](https://gitter.im/red/help?at=5e3c6e88dc52c34ace4da79c) Yes.
20:35Rebol used its own GUI system, while Red currently uses native controls. We will have a non-native system in the future as well. Base is just an empty box, basically, so doesn't look like anything. :^)
20:36You can also check out https://github.com/red/community and https://github.com/red/code for samples.
20:36e.g. https://github.com/red/community/blob/master/games/tile-game.red
pluckyporcupine
20:39thanks! bookmarked those
GiuseppeChillemi
21:09About code evaluation, please consider this code:

Red [
]

Do [Mycode my-code]

Switch code [
	A [Mycode mycode]
	B [othercode other-code]
]


Once a script has been loaded, is there any overhead to run the first type of code ? I mean: is the block preprocessed in any way by do ?

And the second one ? Apart searching either for A or B, is the code floowing those words preprocessed before execution ? Which are the avaluation/execution steps if any ?

hiiamboris
21:14you can profile it to see ;)
GiuseppeChillemi
21:35profile? Never read about this function. I'll try and report!
greggirwin
21:40https://gist.github.com/greggirwin/908d44dc069ed84cf69f053e1308390d

GiuseppeChillemi
08:47It's a function to check timings. I just need to know if DO and SWITCH perform extra operations on the code block that adds overhead or it is immediately executed.
Oldes
09:10@GiuseppeChillemi why don't you check sources? Here is [do](https://github.com/red/red/blob/master/runtime/natives.reds#L525-L586) and here is [switch](https://github.com/red/red/blob/master/runtime/natives.reds#L459-L489)
proksi21
09:16Does latest Red build support compiling for Android already?
Oldes
09:17I don't think so.. current focus seems to be on fast lexer. There were some android experiments, but I don't think these are up to date.
GiuseppeChillemi
13:56@Oldes I am reading the sources but I do not know R/S dialect and inner Red structure, it's difficult to understand what I see and I should make a lot of questions. But if you are available to answer I could start my R/S studies early than planned.
13:57However, sources made me laugh with the comment: ";-- 0 to make compiler happy".
14:00@rebolek Please, correct me if I am wrong but you should have created a Red code navigator, shouldn't you ?
rebolek
14:01@GiuseppeChillemi Hm, I'm not sure what do you mean by that.
GiuseppeChillemi
14:05I remember having read about a GUI able to navigate the red sources, functions, and so on.
rebolek
14:28@GiuseppeChillemi there's [Anamonitor](http://rebol.net/plugin/demos/sources/anamonitor.html) for Rebol, but I'm not sure if there's something similar for Red, certainly not from me, I spend 95% of time in console, so I have no use for GUI code browser.
loziniak
15:41@proksi21 see my libssl code: https://github.com/loziniak/libssl-crypt
15:56Perhaps you could comment on my method of salt, key and iv generation (line 188 of libssl-crypt,red):
1. Take date string with microseconds
2. Randomize it
3. Hash with SHA256
4. Take first 8 bytes as **salt**
5. Derive 48 bytes from 10k iterations of *pbkdf2* salted with this salt
6. First 32 bytes are **key**, next 16 bytes are **iv**
7. Encrypt data with this key/iv pair
8. Prepend salt to encrypted data.
9. On decryption key and iv are derived from salt and password and data is decrypted.

(it would be best if you answered in red/blockchain channel)
greggirwin
23:47@GiuseppeChillemi there is my [old object browser](https://gist.github.com/greggirwin/91dc1c3971998e0babeedba9f7e60bc5), and @rebolek (IIRC) did a func to jump to R/S source on github.

rebred
01:2599 / 50 gives me 1. how do I round it to 2
redredwine
02:58I am trying to understand the difference betwee view and vid.
so I see this is VID code
Red [need 'view ]
view [ button "hello" ]

how would the equivalent VIEW code look like?

thank you.
greggirwin
04:58:point_up: [February 7, 2020 6:25 PM](https://gitter.im/red/help?at=5e3e0e1a45000661fca99276) @rebred >> round 99 / 50.0 == 2.0

There is a pending design change that will make / on ints coerce, while // will be the new integer divide op.
05:04@redredwine
win: make face! [
	type: 'window
	text: "Red View"
	size: 320x240
]
win/pane: reduce [
	hello-btn: make face! [
		type:   'button
		text:   "Hello"
		offset: 10x10
		size:   75x35
		actors: object [
			on-click: func [
				face [object!]
				event [event!]
			][
				print "Hello!"
			]
		]
	]
]
view win
proksi21
10:32Hey guys! Does anyone use Red on macOS?
rebolek
10:32Hi, I do.
proksi21
10:33When I download latest build, I get .dms file
10:33What should I do to run it?
rebolek
10:35IIRC just rename it and it should work. I build from sources.
proksi21
10:38I did the following: renamed it, chmod +x and I got an error “bad CPU type in executable”
10:38I’m using macOS Catalina 10.15
10:40To make it clear - I’m not Mac user at all, just tried to check cross-compilation:D
rebolek
10:41Unfortunately, Catalina doesn't support 32bit apps anymore.
proksi21
10:41Ohhh, I got it. Thank you!
10:43How far are we from supporting 64bit as well?
rebolek
10:47I don't know, but it's a priority, as more systems are moving to 64bit only.
proksi21
10:51Yeah, I’ve faced this problem when tried to install Linux on my old Asus Eeebook (64 bit cpu, but 32bit Uefi bootloader). A lot of distros are 64bit only.
rebolek
10:55What distro you settled on? I have an old Eeebook too that I want to reinstall.
endo64
16:00I'm getting: The Red Language Server server crashed 5 times in the last 3 minutes. The server will not be restarted. msg on VSCode extension:
Any idea how to fix it?
[Trace - 17:11:18] Sending request 'textDocument/hover - (3)'.
[Trace - 17:11:20] Received notification 'textDocument/publishDiagnostics'.
[Info  - 17:11:20] Connection to server got closed. Server will restart.
[Error - 17:11:20] Request textDocument/hover failed.
Error: Connection got disposed.
	at Object.dispose (c:\Users\endo\.vscode\extensions\red-auto.red-0.3.6\node_modules\vscode-jsonrpc\lib\main.js:876:25)
	at Object.dispose (c:\Users\endo\.vscode\extensions\red-auto.red-0.3.6\node_modules\vscode-languageclient\lib\client.js:71:35)
	at LanguageClient.handleConnectionClosed (c:\Users\endo\.vscode\extensions\red-auto.red-0.3.6\node_modules\vscode-languageclient\lib\client.js:2153:42)
	at LanguageClient.handleConnectionClosed (c:\Users\endo\.vscode\extensions\red-auto.red-0.3.6\node_modules\vscode-languageclient\lib\main.js:151:15)
	at closeHandler (c:\Users\endo\.vscode\extensions\red-auto.red-0.3.6\node_modules\vscode-languageclient\lib\client.js:2140:18)
	at CallbackList.invoke (c:\Users\endo\.vscode\extensions\red-auto.red-0.3.6\node_modules\vscode-jsonrpc\lib\events.js:62:39)
	at Emitter.fire (c:\Users\endo\.vscode\extensions\red-auto.red-0.3.6\node_modules\vscode-jsonrpc\lib\events.js:120:36)
	at closeHandler (c:\Users\endo\.vscode\extensions\red-auto.red-0.3.6\node_modules\vscode-jsonrpc\lib\main.js:226:26)
	at CallbackList.invoke (c:\Users\endo\.vscode\extensions\red-auto.red-0.3.6\node_modules\vscode-jsonrpc\lib\events.js:62:39)
	at Emitter.fire (c:\Users\endo\.vscode\extensions\red-auto.red-0.3.6\node_modules\vscode-jsonrpc\lib\events.js:120:36)
	at StreamMessageReader.fireClose (c:\Users\endo\.vscode\extensions\red-auto.red-0.3.6\node_modules\vscode-jsonrpc\lib\messageReader.js:111:27)
	at Socket.<anonymous> (c:\Users\endo\.vscode\extensions\red-auto.red-0.3.6\node_modules\vscode-jsonrpc\lib\messageReader.js:151:46)
	at Socket.emit (events.js:205:15)
	at Pipe.<anonymous> (net.js:586:12)
hiiamboris
16:07@bitbegin ^^
proksi21
16:52@rebolek Any Debian based distro is ok. Just install it as usual from live, then skip bootloader installation, chroot to your new system and install 32bit grub
16:53OpenBSD works out of the box, btw

bitbegin
01:34@endo64 i have tested, it still works. you can update Red toolchain to retry
rebred
02:31all operations with float numbers are wrong by tiny amounts - is this normal ?
endo64
10:40@rebred it's a know issue for all floating point numbers independent of the language.
redredwine
15:40@greggirwin thanks for the VIEW code.
fergus4
17:09Why does 'wait' pause preceding commands too? For example: print "hi" wait 5 print "bye" results in a 5 second pause then print "hi" and "bye" instead of printing "hi" and 5 seconds later printing "bye"
endo64
17:13it's a current limitationa
17:14Will probably change when console port is implemented.
greggirwin
17:40:point_up: [February 9, 2020 10:09 AM](https://gitter.im/red/help?at=5e403cbb37545d247d2c0e82) @fergus4 that affects the GUI console only. If you use the CLI console, it works as expected.
hiiamboris
21:56Interesting how one can optimize Red by making operators:
>> ~: make op! :as-pair
>> clock/times [as-pair 1 2] 1000000
241 ms	[as-pair 1 2]
== 1x2
>> clock/times [1 ~ 2] 1000000
143 ms	[1 ~ 2]
== 1x2
21:57A lot of actions, like append are binary in their common form
greggirwin
22:17Code obfuscation *and* optimization. :^)
hiiamboris
22:18Right! :D
greggirwin
22:18We'll have the fastest emoji-based apps in the world.
rebred
23:34>> to-float pad/with find/tail form round/to 1 .07 dot 2 #"0"
== 0.98
23:36trying to give each number at least 2 digits after 0. is there a simple way to make it work ?
23:360.98 is not 1.00 !

ne1uno
07:40@rebred float won't show trailing zero. you need some kind of string format. @toomasv has form-to.red https://gist.github.com/toomasv/006aaa95a0da02844916451fce8a6fcf
07:42round /to is scale not precision. round/to 1 .01 is 1.0
rebolek
08:50@rebred you are rounding to multiples of 0.07, so you can't get 1.00!
08:52Also your to-float will convert string to float, so you will lose your padding zeroes:

>> pad/with find/tail form round/to 1 .01 dot 2 #"0"
== "1.00"
Oldes
09:09@greggirwin where is your form function? ;-)
rebred
12:53@ne1uno @rebolek great thanks!!!
rebolek
12:55@Oldes if you ask...https://github.com/greggirwin/red-formatting and some notes about it are here: https://github.com/greggirwin/red-formatting/blob/master/formatting-functions.adoc
Oldes
13:09Cool... [sad faces dialect](https://github.com/greggirwin/red-formatting/blob/master/formatting-functions.adoc#2-composite) :-) The [format](https://github.com/greggirwin/red-formatting/blob/master/formatting-functions.adoc#16-format-specifications) looks quite complicated to remember.
rebolek
13:23It’s a dialect covering many cases. Simple things should be easy and complicated things should be possible. It's not a thing where you should remember all details IMO.
manuelcaeiro
19:23Recently I installed Avira Antivirus.
Several redlang files were immediately quarantined.
What would you advise me to do?
Thanks.
hiiamboris
19:35report false positives to Avira and add Red to exceptions
19:37https://github.com/red/red/wiki/[NOTE]-Anti-virus-false-positives for more verbose answer
manuelcaeiro
23:13Thanks for the link @hiiamboris
Perhaps you would also be able to explain why the same red code compiled to a Windows executable runs perfectly, but compiled to a Debian executable does not run?
hiiamboris
23:20can't say without knowing what's in the code or an exact error message ;)
manuelcaeiro
23:21There is no error massage. It just does not execute.
I can send you an example:
hiiamboris
23:22sure, send it
manuelcaeiro
23:28
Red [
    needs: 'view
    file: insults.red
    Author: "manuelcaeiro"
]

col1: ["Away, you" "Come, you" "Thou" "You poor"]
col2: [" peevish" " grizzled" " greasy" " jaded" " waggish" " purpled" " rank" 
      " saucy" " vacant" " yeasty"]
col3: [" clay-brained" " dog-hearted" " evil-eyed" " lily-livered" " mad-bred" 
      " onion-eyed" " paper-faced" " rump-fed" " shag-eared" " white-livered"]
col4: [" three-inch fool" " canker blossom" " clot pole" " hedge-pig" " dogfish" 
      " egg-shell" " nut-hook" " pantaloon" " rabbit-sucker" " snipe younker"]
      
ins: [random/only col1 random/only col2 "," random/only col3 "," random/only col4 "!"]
view [
     size 750x100 
     title "Shakespearean insult generator for kids" 
     below center button "Insult me!" [phrase/text: form rejoin ins] phrase: text 725x35 font-size 20 center
]

hiiamboris
23:31oh, I see
23:32View support on Linux is still experimental, so you better ask in https://gitter.im/red/GTK room how they compile scripts for GTK
23:32Love your script btw ;)
manuelcaeiro
23:34Okay. Thank you. Good evening.

Oldes
10:44In Rebol3 setting value in a map! to none removes the value. Is it possible in Red?
>> m: make map! [a: 1 b: 2]
== make map! [
    a: 1
    b: 2
]

>> m/a: none
== none

>> m
== make map! [
    b: 2
]
10:47Ok.. I found it:
>> remove/key m 'a
== #(
    b: 2
)
rebolek
11:29It was possible in earlier version, but was removed as having none keys in map! has its value.
bubnenkoff
14:19Where I can track the status of ports?
Phryxe
16:09https://trello.com/b/FlQ6pzdB/red-tasks-overview
pekr
16:20I am not sure Trello is being updated lately ....
greggirwin
19:24Port work is being done in a private branch right now.
GiuseppeChillemi
20:01Is there a function abke to return an unique ID each round it is called?
hiiamboris
20:02random ?
GiuseppeChillemi
20:03No chance it will return an already emitted number?
hiiamboris
20:06I see. Well, for that I guess the best 'ID' is SHA-256 today
20:06but you need some unique data, like time & date :)
GiuseppeChillemi
20:08Until I emit at a rate higher than time an date :-)
hiiamboris
20:08Yes ;) Well, no GUIDs out of the box yet
20:08What's your use case?
GiuseppeChillemi
20:08Are you reading my mind?
hiiamboris
20:09@hiiamboris withdraws from Giuseppe's mind
20:09uhm... no not at all..
GiuseppeChillemi
20:10Creste unique handlers to append to VID word for faces, so WORD-HANDLER will be unique. I am thinking about this as I create panels from the same model and set of words.
20:11*create
20:12I could use a simple counter...
20:13That's easier, I was just thinking if Red could provide this ID
20:13It's a stupid question, I whitdraw from the discussion full of shame!
hiiamboris
greggirwin
20:35@GiuseppeChillemi the standard approach is a gensym func.
20:35
gensym: func [/with 'word /reset /local count] [
	count: [0]
	count/1: add 1 either reset [0] [count/1]
	to word! append to string! any [word "g"] count/1
]
loop 3 [print gensym]
loop 3 [print gensym]
gensym/reset
loop 3 [print gensym]
loop 3 [print gensym/with 'xx]
ne1uno
22:06search uuid rebol/red

GiuseppeChillemi
23:28Thanks both @greggirwin and @ne1uno
23:31I can't find anything about string formatting. In Rebol3 there is FORMAT function. Is there anything for Red and Rebol2 ? I miss all those poweful instruction I had in AREXX
greggirwin
23:42Experiments are [here](https://github.com/greggirwin/red-formatting) but we don't know what things will look like in final form. Play and comment.
GiuseppeChillemi
23:43@greggirwin Thanks, again.

GalenIvanov
07:26@greggirwin Thank you for the gensym example! So this is how to implement a generator in Red - very nice!
bferris413
15:37what am I missing here (want to work directly with view engine):
Red [ Needs: 'View ]

b: make face! [ 
    type: 'button 
    text: "ok"
    enabled?: yes
    visible?: yes
]

w: make face! [ 
    type: 'window 
    text: "My Window" 
    pane: [b]
    offset: 50x50
    size: 300x300
    enabled?: yes
    visible?: yes
]

view w
hiiamboris
15:43
Red [ Needs: 'View ]

b: make face! [ 
    type: 'button 
    text: "ok"
	offset: 0x0
	size: 80x25
]

w: make face! [ 
    type: 'window 
    text: "My Window" 
    pane: reduce [b]
    offset: 50x50
    size: 300x300
]

view w
bferris413
16:06:+1: noted the reduce
16:44and button sizing/placement

xqlab
08:35probe w

rebred
19:44
text: {ok start this is a test string stop test testing startokstring2stop test start wordstring3 stop ok}
a: parse text [collect any [thru "start" | keep to ["stop" | end]]]
print a

19:45this only gives me the last string found out of 3. how do I keep all the strings between start and stop
toomasv
19:48Remove first |:
>> a: parse text [collect any [thru "start" keep to ["stop" | end]]]
== [" this is a test string " "okstring2" " wordstring3 "]
rebred
19:50@toomasv that's great thanks!!!!
toomasv
19:50:+1:

bubnenkoff
11:55I am doing load %file. How to check if it have function foo inside? I tried set-word? but it's seems that it's not for this
hiiamboris
11:56use find
rebolek
11:57find code [foo: func] in case you're not using something more interesting to create your functions :-)
bubnenkoff
11:57Why function? do not work?
>> ? function?
USAGE:
     FUNCTION? value

DESCRIPTION: 
     Returns true if the value is this type. 
     FUNCTION? is a function! value.

ARGUMENTS:
     value        [any-type!] 

>> func function function! function?
>> foo: func[] [print "hello"]
== func [][print "hello"]
>> 
>> 
>> function? foo
hello
== false
loziniak
11:57hehe there is does, has, func...
rebolek
11:58function? :foo
hiiamboris
11:58@bubnenkoff because load returns *data*
loziniak
11:58maybe you want do load %file ?
bubnenkoff
11:58but how to check if this data is just data or function?
rebolek
11:58@bubnenkoff foo evaluates function and returns unset!
11:59so use :foo to get value
loziniak
11:59then you can use function? :foo
bubnenkoff
12:03my case. I am iterating thru files. I need to run function foo from every file if it exists in it.
foreach _rule list-of-rules [
        rule: load _rule
        do do-parsing file ; do-parsing can exist of not in files
    ]

So the second question should I use unset after every function call ir I can simply go to next file
loziniak
12:06you mean foo or do-parsing?
bubnenkoff
12:06it's same in my case. I asked about abstract code, and in real code it's do-parsing
loziniak
12:07what's file?
bubnenkoff
12:07
list-of-files-for-processing: collect [foreach f xml-files [if equal? suffix? f ".xml" [keep rejoin [xml-folder f] ]]]

foreach _file list-of-files-for-processing [
    file: read _file
    foreach _rule list-of-rules [
        rule: load _rule
        do do-parsing file
    ]

]
12:10So if I right understand I should remove\unset do-parsing after each call
loziniak
12:29Maybe something like this after rule: load _rule:
dp: find/tail rule 'do-parsing
if dp [
    dp: do copy/part dp 3
    dp file
]
bubnenkoff
12:50is it's better than:
>> function? :do-parsing
== true


If file have this function I will get true
loziniak
12:51Yes, but you have to do do rule to execute the code inside rule. And all other code from rule will run as well.
bubnenkoff
13:51Hmm.... why I can't call function?
>> rule: load %.\rules\r1.red
== [Red [] 
    "aabbccdd" 
    x: "hello" 
    foo: func [] [print "hello world from foo"]
]
>> 
>> 
>> do rule/foo
*** Script Error: func is missing its spec argument
hiiamboris
13:52try type? rule/foo
loziniak
13:52rule is just a block of Red values (code = data)
13:52to create a function it has to be evaluated
bubnenkoff
13:52I thought do is evaluate it
loziniak
13:53yes, but it evaluates func word alone
13:54because:
a: [x y x] ; a/x = y
13:55so when you use rule/foo on not evaluated block of data, you just get a value following word 'foo, and it's word 'func. So you actually do something like: do 'func
13:58you need to copy all 3 values following foo and evaluate them.
13:59or evaluate (do) entire loaded file, but then you'll execute all code in it.
bubnenkoff
14:51I simplified case. Let's assume that I have only one function in each file.
>> rule
== [do-parsing: function [file result-file-name] [print "start do-parsing" 
    data: object [
        id: none 
        lots: []
    ] 
...
>> do copy/part rule 3
*** Script Error: function is missing its body argument
*** Where: function
*** Stack:


14:52do-parsing - first arg
function - second
[file result-file-name] - third
loziniak
14:55you need to copy 3 values starting AFTER do-parsing:.
14:57or in your 4 values including do-parsing:, but you have to be sure, that in each rule you use same word for function name.
14:58or just delete do-parsing: from rule.
bubnenkoff
14:59and evaluate pure function?
loziniak
14:59use probe to check what values you get: do probe copy/part rule 3
15:00yes, you can do this: dp: do copy/part rule 3
15:00do copy/part rule 3 will just return function value, and you assign it to dp word.

xqlab
07:53you can use do/next as in
>> do/next fn: back find rule 'function 'rpos
== func [file result-file-name][print "start do-parsing"]
>>     
>> print to-word fn/1
do-parsing
>> do reduce [to-word fn/1 1 2]
start do-parsing
>>

stmungo
22:33Could someone help me with code to return a curried function please? I want to define a function called curry which takes 2 args, firstly a function which requires 2 arguments and secondly an argument of the function. So fir example I want to be able to code plus: function [ x y][x + y] then incr: curry :plus 1. My attempt at coding curry as function [f y][ function [x] [f x y]] gave an error saying f is not known, with incr value being func [x][f x y]. How do I get a function returned with the name of my 2 arg function included, please?
hiiamboris
22:36f and y only exist before function [f y] returns, so you have to inline them with compose
22:37i.e. substitute words f and y with their values in the new returned function
stmungo
23:05 @hiiamboris
Thank you for your prompt advice. I have explored it and this is now my working code:
23:06curry: function [ fc [function!] yc ] [ function [ xc ] compose [ (:fc) xc (yc) ] ]
plus: function [x y][ x + y]
incr: curry :plus 1
incr 10
hiiamboris
23:07:+1:

ne1uno
10:06f: func [/local x A][foreach [x][0 1][A: x print [s: {add A 12} do s]]]
10:06 ** Script Error: A has no value. red or rebol 2
10:06 is this a known limitation of function? if don't declare /local A, it works as expected.
hiiamboris
10:37Yes. do loads your string. load binds it to the global context.
10:38You can load and bind it yourself

raynerzed
15:49I'm stuck! this code gives me an error:
15:49text "Recording the following:"
text ID/data
15:49*** Script Error: VID - invalid syntax at: [ID/data text "ID Number: "]
*** Where: do
*** Stack: view do-events do-actor do-safe view layout cause-error
hiiamboris
15:54VID does not support paths, use compose
raynerzed
15:54sorry, i'm literally very new at this
15:55so instead of text ID/data, i will use compose ID/data?
hiiamboris
15:55no problem ;)
it's like view compose [... your VID stuff and (ID/data) <-- you put parens around paths]
raynerzed
15:57i see. so need to add compose after view
15:59OH MY GOD
15:59THANK YOU
15:59IT WORKS
16:00@hiiamboris THANKSSSS
hiiamboris
16:00☻☻
16:00:+1:
raynerzed
16:00been killing me for the past hour lol
16:00how is this not in the documentation?
hiiamboris
16:01Documentation assumes some familiarity with the language ;)
raynerzed
16:01hahaha. i see. coming from Qbasic and very little java I really have much to learn. thanks again!
17:07last help please :( im getting an error for load command
17:08*** Script Error: VID - invalid syntax at: [read/lines %record.txt]
*** Where: do
*** Stack: view layout cause-error
17:08code: translog: read/lines %record.txt
hiiamboris
17:15same thing as before ;)
raynerzed
17:16ahhh hahha OMG thanks! :)
greggirwin
19:42@raynerzed, welcome to Red! As @hiiamboris said, the docs make some assumptions, and some of those are unknown to us. We can improve them in this area. If you look at the VID docs, you can also see that some facets (face properties) *do* support direct Red expressions. Data and extra are examples:
o: object [a: "test"]
view [
	text data 1 + 1
	button "Path" extra o/a [print face/extra]
]

If you look at https://doc.red-lang.org/en/vid.html#_datatypes, you can see that the *type* of a value may determine the target facet in the VID dialect. This helps keep things clear and concise. It also means, as with many design choices in Red, that there may not be a "catch all" behavior, because that rules out future options in many cases. Here, if we said paths should evaluate (it comes up at times, and could change in the future), then later find a great use for paths, we'd have to break code to make that change. So there's a minor inconvenience of using compose today.

Happy Reducing!

proksi21
12:48Studying Red hardly and need help again :D
rebolek
12:48@proksi21 That's why we're here :-)
proksi21
12:49When I try to implement factorial function, I get Math Error: math or number overflow
12:50@rebolek I appreciate that :-) Red has one of the nicest community imo
rebolek
12:50Thanks!
12:50So, for which number do you get it? Red's integers are 32 bit, so with factorial, you' ll hit the roof pretty soon.
proksi21
12:5212! is the last one, 13! causes overflow
rebolek
12:54There's no autoconversion to floats, which cover a greater range, so you would need to convert to float manually.
Something like this should be enough:
>> fact: func [n][n: to float! n either n = 1 [1][n * fact n - 1]]
== func [n][n: to float! n either n = 1 [1] [n * fact n - 1]]
>> fact 12
== 479001600.0
>> fact 13
== 6227020800.0
>> fact 120
== 6.689502913449124e198
proksi21
12:55Yes, that works. Thanks.
rebolek
12:55You're welcome!
proksi21
12:55Btw, how far are we from becoming 64bit?
rebolek
12:56I can answer questions about code, but not this one, I really don't know, sorry!
Phryxe
12:57That is a question for a FAQ :wink:
rebolek
12:58@Phryxe :-D
greggirwin
23:39We're not making release estimates for 64-bit at this time.

proksi21
14:11@greggirwin well, my question mostly not “when 64bit”, but “osx and a lot of Linux distros drop 32bit support, will we implement 64bit in any near future and is there anything I can help with to boost this process” :-)
greggirwin
18:17We will go 64-bit, yes. It's a huge task and all help is welcome. @dockimbel or @qtxie would have to say if there are pieces and research others can assist with at this time.

olivier_lp_twitter
16:32instead of fact: func [n][n: to float! n either n = 1 [1][n * fact n - 1]], fact: func [n][either n = 1 [1.0][n * fact n - 1]] should work, no?
rebolek
16:37@olivier_lp_twitter yes, that should work too
16:38(not should, does)
fergus4
17:24How do you invoke the CLI console instead of GUI when running a script?
rebolek
17:27@fergus4 on Windows? You need to compile your console with target MSDOS instead of Windows.
fergus4
17:29Thanks. I want to call a script that uses "forever" and "wait" but wait has an issue with GUI console. What is the best way around the bug?
toomasv
17:35Just joking:
view/options [on-time [unview]][visible?: no rate: 00:00:5]
greggirwin
17:37Running red --cliforces it, or run a built console directly from C:\ProgramData\Red.
fergus4
17:41Thanks Gregg. That's what I was looking for!
dsunanda
18:36Any clues when FTP might be available in Red?

And is it premature to report what might be a premature FTP-related bug? The line below crashes the console. The culprit is the "@" in the password - without it, Red correctly reports that FTP is an unknown scheme (rebol has no problem with an @'ed password)

read ftp://user-name:password-that-contains-an-@-sign@ftp.example.com/
greggirwin
18:47FTP will come after ports. I've used it a lot, so understand the need, but the protocol itself is a pain. Has to be SFTP today as well. So it may be a lower priority than, say, great support and tooling for modern API use cases.
fergus4
22:26Rebol would convert a MySQL date stamp to rebol with to-date but red balks at it. Am I missing something?
rebol
>> to-date "2020-02-27 11:53:58"
== 27-Feb-2020/11:53:58

red
>> to-date "2020-02-27/11:53:58"
*** Script Error: cannot MAKE/TO date! from: "2020-02-27/11:53:58"
*** Where: to
*** Stack: to-date
22:44load seems to convert from string ...just have to replace space with "/"
newDate: load replace "2020-02-27 11:53:58" " " "/"
== 27-Feb-2020/11:53:58
greggirwin
23:16Yes, that behavior change is by design.

Oldes
08:31@greggirwin why to-date "2020-02-27/11:53:58" errors and load "2020-02-27/11:53:58" not?
08:35It looks to me like _not yet implemented_ instead of _change by design_.
08:41@dsunanda FTP will be [only if you write it](https://trello.com/c/BW1SPeOU/48-i-o-support#comment-5411286d8ff7224f76041a52). I guess it would be easier to write a curl binding for that.
GiuseppeChillemi
12:39Does anyone know a method in Rebol to write on an existing Image or PDF either lines/circles or text and then print the final result ?
rebolek
12:43there's PDF-maker.r for Rebol.
GiuseppeChillemi
13:01@rebolek I haven't made the connection it accepts images as backgroud.... thanks. Sometime simple things are invisible to our minds.
13:02And what about Red ? How would you write over a pdf or image ?
meijeru
13:02There is currently some discussion about random (issue #4308). In that connection I did some tests, and one thing that may be obvious to some, but not to others, is that for random, false < true, therefore random false is uniformly false; to get an equal chance of false and true one has to do random true.
13:03Where should this observation go, if anywhere?
hiiamboris
13:04> And what about Red ? How would you write over a pdf or image ?

draw image [commands]
GiuseppeChillemi
13:07@hiiamboris But PDF should be first converted to an image....
13:10Ok, a last one: how do I get x and y coordinates of a mouse click in Rebol and if it happens in a specified area ?
13:11The purpose is to draw an X on the image and also record a certain area has been clicked.
rebolek
13:14event/offset
GiuseppeChillemi
13:15Grazie !
fergus4
15:06How do you "package" an asset like an icon pic with a release version binary?
hiiamboris
15:31@fergus4 https://github.com/red/red/commit/61f90c07af9670296ae3812f956e1fbd505cc639 may help
dsunanda
21:05Thanks for the replies, Gregg and Oldes....I've just converted an old R2 application, and the loss of ZIPing (via Rebzip,r) and FTPing (with native READ and WRITE) are annoying (and easily bypassed by shelling out to 7-Zip and WinSCP). Red's GUI and compliation capabilities make it worth the conversion effort.

proksi21
04:58Hey guys, I need help again :-)
04:59https://hastebin.com/gehuwatuvo.red
04:59In this piece of code, why z becomes visible in global scope?
05:32I tried func, function and has, but z keeps appearing in global scope :-(
toomasv
05:54@proksi21 By do to-block string is loaded and new words are global. You need to bind the block to func context do bind to-block y :f (On phone now and cannot check).
05:55And in fresh console.
proksi21
06:05@toomasv thank you! Binding works with “func [/local y z]”, but if I use “function []” - z still becomes visible
06:07But if I initialize it inside function with “z: 0”, everything is ok
06:08I still have to learn so much about Red :-)
toomasv
08:31@proksi21 Yes, that's because function collects declared words from its body and makes these local. But as z is not declared during function initialization, it is not bound to function context when created. See:
>> f: function [][y: copy "" append y ["z: 12 print z"] do bind to-block y :f]
== func [/local y][y: copy "" append y ["z: 12 print z"] do bind to-block y :f]

To have z catched with function you need either to declare it (as you did in your comment) or make it explicitly local:
>> f: function [/local z][y: copy "" append y ["z: 12 print z"] do bind to-block y :f]
== func [/local z y][y: copy "" append y ["z: 12 print z"] do bind to-block y :f]
>> f
12
>> z
*** Script Error: z has no value
08:35And, please forgive me, this function is awfully convoluted :) I hope/guess it is strictly for learning only.
ne1uno
10:27script: make string! 10000 then in view layout, f-script: area script 600x600
10:27from [Didier "Red basic Editor" 2017 (https://gist.github.com/DideC/61138fe905a6950359087a07a374e0d4)]
10:27is this some undocumented buffer scheme or just alias for 'f-script/text` ?
rebolek
10:49@dsunanda If you need ZIP, just look here - https://github.com/rebolek/red-tools/tree/master/packers . There are currently two versions, zip-debug.red and zip.red, they will be merged soon. Debug version is development version and supports UTF8 filenames.
proksi21
12:42@toomasv yes, this function is for learning purposes. Part of brainfuck interpreter :-)
I translate bf code to red block and then execute it. And those local variables from example are bf memory and bf pointer. I can share the code for review, it would be very helpful for me :-)
toomasv
12:46@proksi21 You want to f my b too? Be my guest! :smiling_imp:
proksi21
12:52Ahah, here it is https://hastebin.com/umiyedexot.red
12:55So it’s basically just validation (using parse dialect), translation and execution
toomasv
13:38@proksi21 Nice, thanks! Have you compared it to another implementation in the end of [Parse article](https://www.red-lang.org/2013/11/041-introducing-parse.html)? (I suggest to add | skip (or whitespace charset) to script, then you can use whitespace interrupted multiline commands.)
proksi21
14:16No, I didn’t read that article:D Thanks for pointing.
14:20Hah, they differ a lot in fact. The version from article is more clean and utilizes parse features. My version is ugly a little bit, but translates bf to Red code. So it can be used as reader macros I guess.
toomasv
15:00But your version has advantage: it does handle nested brackets, version in article doesn't. E.g. your version cracks ++++++++[>++++[>++>+++>+++>+<<<<-]>+>+>->>+[<]<-]>>.>---.+++++++..+++.>>.<-.<.+++.------.--------.>>+.>++. but the other one hangs. :+1:
dsunanda
18:17@rebolek re Zip - thanks!
greggirwin
20:20@fergus4 to narrow it down a bit, the last file, hello.red example shows you. Just put an icon: %myico entry in the header, and red does the rest.
rebolek
20:39@dsunanda you're welcome, I'm glad to help!
greggirwin
21:19@Oldes on date conversion, you could be right, though it's something to think about.

- What is the purpose of to? We also have make, load, and as.
- Many values can use to, but not all, date! and map! being examples. Some use their own logic, some call their own make internally.
- A few values (integer, float, tuple) have fast-access tokenizers, because their rules are simple, as are their numeric range constraints. We'll see if they're still used when fast-lexer is merged.
- Dates are a special case in many ways, when it comes to flexibility versus consistency. Time! only has one syntax, and calls out to the tokenizer. Same for pair!

So we have conversion, creation, coercion, and evaluation as modes, each with (potentially) different constraints. This is a balancing act, between PoLS, efficiency, and consistency. Very much in the "art" part of language design. (Thanks for bearing with me as I think through this myself)

The most flexible and slowest is evaluation (load). Anything goes, if it's a Red form. Next comes creation (make), which can take specs in varying forms, and which requires you to know some details about value you're creating, so your spec is valid. Then we have conversion (to), where you have an existing value, but you want a different type, which *may be* possible to do, but is not guaranteed to work. Finally, there's coercion (as), which is the most restricted form of conversion, and also the most efficient.

With all but load, you specify the type you want.

Then there's round-tripping. Not all types do.
>> to time! [1 2 3]
== 1:02:03
>> to block! to time! [1 2 3]
== [1:02:03]


And then there's date!, its unique interaction with humans due to how many ways we spec and talk about them, variances due to things like today (leap day), etc. Red added many new date forms, so there's no way it can round trip (e.g. 2020-060 == 29-Feb-2020, 2020-W01 == 30-Dec-2019). Dates also change to canonical syntax when formed.

To the simple question of why not just let to work on strings, we can, and it can just load. But it doesn't really *solve* anything. It just pushes issues around a bit.
Oldes
23:00@greggirwin it is interesting that you don't mention the higher level variants like to-date. I think that these should be more like a shortcut to to date! and could handle various types.
greggirwin
23:07to-* funcs are simple wrappers for to, generated automatically. I have mentioned in the past that I think they can go away entirely.
23:08If it has the same name, effectively, the behavior shouldn't be different.

stmungo
14:11 @toomasv
toomasv
14:29:question:
14:54@proksi21 Added my [version of bf](https://gist.github.com/toomasv/25c6c5e80905913942937de2649d71e2), building on previous work.
cloutiy
16:08Having some trouble understanding why object doesn't get initialized. I created an object, then a function that, taking in parameters, creates an object initialized with those values. However the result is not as expected:

Person: object [  name: none  age: none]
Person.new: function [ name age ] [
    make Person [ name: name age: age ]
]

>> pete: Person.new "Peter" 35
== make object! [
    name: none
    age: none
]
16:10p.s. I know I the normal way to create objects is with make, however the question is more about understanding language behavior.
toomasv
16:21@cloutiy You need to give some values to the make Person:
Person: object [  name: none  age: none]
Person.new: function [ name age ] [make Person compose [name: (name) age: (age)]]
pete: Person.new "Peter" 35

== make object! [
    name: "Peter"
    age: 35
]
pekr
16:28Why does not it work without a compose, e.g. reducing a block?
toomasv
16:35@pekr Because simple reducing will make it inappropriate:
>> Person.new: function [ name age ] [make Person probe reduce [name: name age: age]]
== func [name age][make Person probe reduce [name: n...
>> pete: Person.new "Peter" 35
["Peter" 35]
== make object! [
    name: none
    age: none
]

But you can do it with reducing too:
Person.new: function [ name age ] [
    make Person probe reduce [quote name: name quote age: age]
]
cloutiy
16:36aaaaah darn reduce always gets me.
16:39Sorry, I meant compose. Well, both really. It's still not a natural instinct. Thanks Toomas.
toomasv
16:47There is one interesting way more:
Person.new: function [ name age ] [out: make Person [] set out reduce [name age] out]
pete: Person.new "Peter" 35
== make object! [
    name: "Peter"
    age: 35
]
cloutiy
16:56Interesting yes. But happy with the simple compose ;)
greggirwin
18:36I added a little extra info [here](https://github.com/red/red/wiki/%5BDOC%5D-Object-Notes).
endo64
18:57And of course you can use different words to avoid above issue:
>> Person.new: function [name* age*] [make Person [ name: name* age: age* ]]
== func [name* age* /local name age][make Person [name: name* age: age*]]
>> Person.new "Peter" 35
== make object! [
    name: "Peter"
    age: 35
]
greggirwin
19:34Excellent point.
toomasv
19:57@endo64 :+1:
GiuseppeChillemi
23:05I need to build a small app for android with gui. Is it possible to use it on mobile?

fergus4
21:55Is there a way to prevent console window from opening when running a red .exe that was compiled with MSDOS target . I want to put it in startup folder.
hiiamboris
21:59@fergus4 why won't you compile it for Windows target?
fergus4
22:01I'm using a wait statement...Bug with GUI
hiiamboris
22:01What bug?
fergus4
22:02wait does not work with GUI
hiiamboris
22:03can you report this bug for us to fix?
rebolek
22:03It somehow does at least on Windows, but it's a black magic.
fergus4
22:03I assumed its reported. Many here knew about ti.
endo64
22:04@fergus4 Can you share a minimal example script to test the issue?
fergus4
22:08
Print "hi" wait 5 print "Bye"

Will not print for 5 seconds then print HI and Bye at same time
hiiamboris
22:09I see. But without the console, where do you expect to print to?
22:10Besides, this happens only in GUI console, not in your compiled program. So I don't yet understand how it stops your program from working
fergus4
22:10I want to use wait for a forever loop...I'm not printing anything. That was an example of the wait bug not my program
22:11My program works compiled to MSDOS...My problem is I do not want the cosole window opening when the program is launched
hiiamboris
22:12So, what's happening to your program with wait and forever, when you compile it for -t Windows?
endo64
22:12it should work when compiled with -t Windows
fergus4
22:13Let me try again...
22:17Seems to work...I misunderstood...I guess its just the GUI console with problem...
22:17Thanks guys...
hiiamboris
22:17:+1:
endo64
22:17Good to know, thanks for testing.

loziniak
10:44@fergus4 it looks similar to #4191 . If it's so, there's a workaround in comments to the issue.

viayuve
06:17any document on connecting geany with red binary?
ne1uno
06:21help describes it but I've only had limited success adding more than one interpreter
viayuve
06:22any editor+red that you recommend for linux ubuntu
rebolek
ne1uno
06:36in %Geany\data\filedefs\filetypes.Red.conf or wherever the shared version is, clone the filetypes.Clojure.conf
06:38then add Red and filetypes in %Geany\data/filetype_extensions.conf like Clojure, comment out #R= add Red=*.red;*.ren;*.r;*.r3;*.r2;
06:39scintilla has a rebol mode but it's not built by default
06:40their lua plugin is using Lua5 which isn't utf8, so mangles text.
07:39kate or kdevelop might have rebol mode enabled?
viayuve
09:26libcurl3 why this?
09:27@ne1uno I will download it and try,
rebolek
09:33@viayuve can you be more specific? liburl3 is needed on some ancient system.
viayuve
09:35i was setting red on my old laptop debian 7
rebolek
09:36I see. Then you need libcurl3 for http(s)
viayuve
09:38okay but i don't need http or https will red work without it?
rebolek
09:39You would need to remove that dependency in source code.
viayuve
09:40means recompile no i will install it. thanks buddy
rebolek
09:40you're welcome
viayuve
09:40what distro @rebolek prefer.
rebolek
09:41I use Manjaro on my Thinkpad.
09:41on rPi I have raspbian
viayuve
09:43cool i am hooked on mx will try manjaro on my desktop. thanks again
proksi21
15:13For me vscode + red plugin works perfect on Debian

GiuseppeChillemi
12:07If I have MYARG in FUNCTION1 and I call FUNCTION2 without passing MYARG via the interface and code of FUNCTION2 uses MYARG word, how could I bind it to FUNCTION1?
rebolek
12:07do you have any simple example to show what you want to do?
GiuseppeChillemi
12:57

function1: func [myarg1] [
	function2

]

function2: does [
	print ["Function1 myargs: " myarg1] ;<<<<------ 
]


I want to have the local words of function1 in function2 but it seems the only way is to bind body-of function2 'myarg1 or pass the words via the interface as arguments.

>
rebolek
12:59passing as an argument is one option, or you can do something like
context [
    var: none
    f1: func [arg][
        var: arg
        f2
    ]
    f2: func [][something with var]
]
GiuseppeChillemi
13:01contex is there for isolation of VAR, isn't it ?
rebolek
13:02set 'f1 ... would be better to export f1 to global context (same with f2).
GiuseppeChillemi
13:03Not having a hierarchical scope led to extra code in some situations.
rebolek
13:04and to lot less of code in others :-)
GiuseppeChillemi
13:04Also, I have to investigate if bind body-of function2 'myarg1 could be done when the context of function1 is not available, I mean it externally.
rebolek
13:05I wouldn't go that path.
hiiamboris
13:06
function2: does [
    print ["Function1 myargs: " get/any bind 'myarg1 :function1]
]
GiuseppeChillemi
13:07Just to learn. We are in a homoiconic language and I need to know the limits of manipulating function blocks words from outside functions.
13:11@hiiamboris I don't undestand

get/any bind 'myarg1 :function1
13:15I have tried it on the console and I get the function in its "reduced" form. I expect bind to work on words or objects. Should I think a function is an object ?
loziniak
15:02Hi! Is there a way to hide *"root: 3585/4916, runs: 0, mem: 3302356 => 2057388, mark: 2.9ms, sweep: 5.2ms"* messages other than disabling GC?
15:03Or could they be printed to stderr?
9214
16:56@loziniak that's what GC [prints](https://github.com/red/red/blob/master/runtime/collector.reds#L307) during marking phase. You can make it dependant on verbosity level (e.g. above 1) if @dockimbel is OK with that.
meijeru
22:34@GiuseppeChillemi A function is not an object, but it does have a context, like an object does. My spec document explains it the following way:

Every object (value of type object!) gives rise to a context, containing the field-name/value pairs of the object. From an implementation viewpoint, an object is just a combination of a context and a class. Every error (value of type error!) and port (value of type port!) is a specialized object, and therefore also has a context associated with it. Every function (value of type function!) also gives rise to a context, which contains the pairs of formal argument name and actual argument value to be used by the body of the function when it is executed.
GiuseppeChillemi
23:21@meijeru Thanks Rudolf, I was aware that functions had a context but I wasn't aware it could be used in bind and with the notation of hiiamboris example. Now I have gone back to command line and in the help of bind have found function!!
USAGE:
     BIND word context

DESCRIPTION: 
     Bind words to a context; returns rebound words. 
     BIND is a native! value.

ARGUMENTS:
     word         [block! any-word!] 
     context      [any-word! any-object! function!]


Also your explanation let me think that I can bind to ports too.

Your help answered my question: I can bind the words of a function context to another function without exporting or using any words other than function name.
23:21(And thanks @hiiamboris )

proksi21
11:52Hey guys! Is there a way to load dll at runtime?
rebolek
11:53Not yet, you need to compile such script.
proksi21
pekr
12:17It was originally planned for 0.6.5, but the release date or if the feature is going to be there, is not know to public.
loziniak
15:19@proksi21 I'm kinda working this around by compiling my routines, red/system and lib imports to a binary, and using call at runtime.
proksi21
15:29@loziniak ah, that’s clever

proksi21
08:19Morning!
08:19I'm trying to make camera face to work, but with no success
08:21Here's the code
view [cam: camera 300x300 select 1]
08:23Get only empty window
08:40Also, this code works on Windows, but crashes on Linux with "Access Error: invalid UTF-8 encoding: #{A02830EF}"
Red []

endpoint:  https://coinmarketcap.com/currencies/bitcoin/
btc-data:  read endpoint
btc-price: copy ""
parse btc-data [thru {price__price">$} copy btc-price to {</span>}]
alter btc-price #","
print ["Price:" btc-price]
GalenIvanov
09:13@proksi21 view [cam: camera 300x300 select 1]works for me - Win 8.1, Asus K550J laptop
GiuseppeChillemi
13:59When creating functions, which logic do you use for the list of arguments? For example, if you have a function that runs a query, which sequence would you use for connection-data , query-string, placeholders? Have you a general rule to select the sequence?
hiiamboris
14:061) subject that you're working on, then items used for that, then options - this order is dictated by Redbol langs having refinements
2) small items first, long or multiline items at the end - for readability
GiuseppeChillemi
15:30run-query satisfies the "subject first" requirement but with long queries , options disappears overscreen.
run-query (on) (with-values) (subject) satifies the requirement of having long items at last but there is an additional entry in the argument list: "additional-placeholders" which is used to overwrite and extend those provided, so:
run-query (on) (subject) (and apply) (and extend/replace) is more fluent when <query> is a word which contains the query. But it would be terrible if you write there the query string.
15:30(parens texts are artificial fillers coming from my mind ;-)
15:40Being verbose using a dialect, as @henrikmk likes, would let you change the words order.
rebolek
15:45server is your subject, not a query. put thing you are modifying first
GiuseppeChillemi
15:51I am already using this solution but also investigating the alternatives.
15:52Actually I use Munge approach: server = ["connection-string" "database"]
15:54PH and PH+ are refinements, so they should remain in the last position.

15:57The only change to have <query> at the end as string and all the options before is to create another function or use @hiiamboris trick of providing using the PH refinement arg to store the query string and vice versa.
rebolek
16:13my take would be , this is most redbol-like
GiuseppeChillemi
16:15Yes, until query is not a word but the query string itself. In this situation, <options> would go offscreen or multiple lines down.
hiiamboris
16:19Then either use refinements /query, /options, and then user can reorder them as he sees fit. Or an object [query: .. options:..] or a dialect. Even your run-query on query ... approach does the trick as it contains cues ("on", "query", etc) on what the next argument is.
GiuseppeChillemi
16:40Yes, that's the reason I like the idea of a dialect with explicit identifiers before values. Your solution also mimic this working. run-query/server/ph/ph+/query provides the sequence of arguments and you can change it. As someone has recently written to me: this is thinking out of the box! Nice one!
rebolek
17:07If your query string is multiple lines, it's probably good idea to assign it to a word anyway

proksi21
11:57Hey guys! It's me again :-)
11:57Trying to get Red macro system
11:59Am I correct that Red macro returns one of Red values (not just replaces macro like Lisp does)?
12:02For example, I want to implement "aif" macro. Is there a way to replace
aif [x = 1][print it]

with
it: x = 1
if it [print it]
12:12And second question: is there anything like "expand" function that prints expanded macro (for debugging)?
hiiamboris
12:13https://doc.red-lang.org/en/preprocessor.html#_pattern_matching_macros is what you need
12:14and there's expand and expand-directives in Red
proksi21
12:17Thanks! I'll try again with pattern matching and share the results :-)
12:18BTW, can't figure out how to make expand work
12:19I define aif in Red console, than try to expand but the result is unexpanded
9214
12:20
text
expand [
	#macro ['aif block!] func [[manual] start end][
		skip insert start [it: x = 1] 2
	]

	aif [x = 1][print it]
]
12:21Now ask yourself if you really need a macro for that. The answer is — you don't. The same can be achieved with code transformations at runtime. Red is not a Lisp in this regard.
12:21> I define aif in Red console, than try to expand but the result is unexpanded

And how do you do that?
proksi21
12:26@9214 The same way I do in source code - it doesn't cause any warnings
12:26
>> expand [
[        #macro ['aif block!] func [[manual] start end][
[            skip insert start [it: x = 1] 2
[        ]
[    
[        aif [x = 1][print it]
[    ]
[it: x = 1 
    aif [x = 1] [print it]
]
== [it: x = 1 
    aif [x = 1] [print it]
]
9214
12:26So, what's the problem? Macro got expanded.
proksi21
12:28Well, it's actually not. Have a look at my code above.
aif [x = 1][print it] should be expanded to it: x = 1 if it [print it]
9214
12:30Ah, you're right, my bad. Still, the macro got expanded.
12:34
text
expand [
	#macro ['aif block!] func [start end][[it: x = 1 if it]]

	aif [x = 1][print it]
]
proksi21
12:35Vladimir, thank you so much!
12:36Now I get it - I can use "parse" inside macro to modify input
hiiamboris
12:37or just return a new code block
12:38yes, that's it ;)
12:401 block! in this case though ;)
9214
12:42@proksi21 the only time you should use macros is if there's a lot of compilation boilerplate. All the other use-cases are covered by the regular language.
proksi21
12:44@9214 yes, I understand that. Just wanted to try Red macro system and compare it to Lisp one.
hiiamboris
12:44here's a nice use case too: https://gitlab.com/hiiamboris/red-composite-macro
9214
12:46@proksi21 IIRC Red macro system was inspired by Shen, which uses ML-like pattern-matching.
proksi21
12:49@9214 can you send me the previous version of macro example, with pattern-matching and parse?
9214
12:50@proksi21 try to write it yourself, as an excercise :wink:
proksi21
12:50Ahh, ok :-)
13:23Ok, here it is (basic, without hygien)
#macro ['aif 2 block!] func [[manual] start end][
    parse start [change ['aif][it: do] block! insert [if it] block! mark:]
    mark
]
13:36Strange, compiler returns "preprocessor error", but in interpreter mode everything is ok
hiiamboris
13:51Compiler runs preprocessor's code in R2. Interpreter - in Red.
9214
14:06@proksi21 compiled macros need to be R2 compatible, so e.g. you cannot use insert in Parse, not to mention all the subtle differences between R2 and Red to account for. One more reason to avoid them.
proksi21
14:56Oh, thanks, I didn’t know that
greggirwin
19:31@proksi21, please add notes to https://github.com/red/red/wiki/%5BNOTES%5D-Macro-Notes, based on what you learn using macros. Thanks!

bferris413
00:36(moved my post)
00:37
view [
    button "Add one" on-click [
        box: layout/only [box 0.100.0]
        print ["size:" box/size "offset:" box/offset "box:" box]
    ]
]
00:37Can anyone tell me the probably glaringly-obvious reason why box/size and box/offset are none?
00:43"Because it returns a pane block." Splendid, just read the docs...
toomasv
05:15You haven't inserted it into layout. And when you insert it you have to give offset and size values yourself.
bubnenkoff
14:57how to divide 1 / 5 and get 0.2 ?
14:57
>> 1 / 5 
== 0
>> 1 // 5 
== 1
Oldes
15:00
>> 1 / 5.0
== 0.2
bubnenkoff
15:01
>> 1 // to float! 5 
== 1.0


is it's good?
15:02And if I need percentage?

>> to percent! 1 // to float! 5 
== 1.0

?
Oldes
15:07Do you want to divide / or reminder //?
bubnenkoff
18:31I want to divide small digit to big and get float and than convert it ti percent
hiiamboris
18:35100% * x
Oldes
18:47
>> tpf: func[n d][100% * (n / to float! d)]  tpf 1 5
== 20%
greggirwin
20:28Note that we have an open design change, so / will coerce, and // will be integer divide.

@dockimbel, can we make https://github.com/red/red/issues/2433 happen?

dockimbel
14:44@greggirwin Yes, but it might break a lot of existing code, so we should plan it and let everybody know when that change will be happening.
greggirwin
20:08We'll put it in the blog announcement. The longer we wait, the more code it will break.
rebolek
21:36Red is still in alpha, so code breaks are expected. I agree with @greggirwin , the sooner, the less damage is done.

viayuve
08:43how to print on printer ?
13:33how to add gtk+red any guide
rebolek
13:34not sure what you are asking about, but if you want to try GTK version of Red, download GTK branch and build it, it's really easy
viayuve
13:35never done that yes i was asking about gtk version red
rebolek
13:36I see. Do you have git installed?
viayuve
13:37i dont think so new laptop
13:38yes i have
rebolek
13:38great, then it's easy:
viayuve
13:39mx linux ships with git hmm never knew that part
rebolek
13:40clone Red repo: git clone https://github.com/red/red.git
go to red dir: cd red
checkout gtk branch: git checkout GTK
13:40now you are in GTK branch and you can build Red with GTK support. You need Rebol for it
13:43download Rebol from here http://www.rebol.com/downloads.html into Red directory, run it and type:
do/args %red.r "-r environment/console/CLI/view-console.red"
wait some time and you have GTK-ready console
viayuve
13:44rebol view or rebol core
rebolek
13:45I use Rebol/Core
viayuve
13:47which one in core
rebolek
13:48http://www.rebol.com/downloads/v278/rebol-core-278-4-10.tar.gz
viayuve
13:52 do/args: No such file or directory
rebolek
13:52you need to run Rebol first
13:52and type it in Rebol console
13:53also your rebol executable must be in the Red directory, or you would need to cd to it before compiling
viayuve
13:54Script: "Red command-line front-end" (none)
Script: "Encap virtual filesystem" (21-Sep-2009)
Cannot access source file: /media/john/5977afdc-a895-47a9-8f6d-fdbd693604e5/red/program/red/environment/console/CLI/view-console.red
rebolek
13:55I see. Please check if you have view-console.red in the described directory. It's possible you would need to create it (it's easy, don't be afraid :)
viayuve
13:58Script: "Red command-line front-end" (none)
Script: "Encap virtual filesystem" (21-Sep-2009)

-=== Red Compiler 0.6.4 ===-

Compiling /media/john/5977afdc-a895-47a9-8f6d-fdbd693604e5/red/program/red/environment/console/CLI/view-console.red ...
*** Red Compiler Internal Error: Script Error : copy expected value argument of type: series port bitset
*** Where: rejoin
*** Near: [mold copy/part pos 40]
hiiamboris
13:59I think you should copy console into view-console and add needs: view to it's header to proceed
14:00Why is this file not in the distribution, I wonder? I'm always creating it, just as everyone else it seems
rebolek
14:02It was in the original repo, IIRC.
viayuve
14:04what is it needs: view or needs: 'view what is the difference
hiiamboris
14:04no difference
viayuve
14:05done
14:08error while loading shared libraries: libgtk-3.so.0: cannot open shared object file: No such file or directory
rebolek
14:08you need to install 32bit GTK
14:10something like apt-get install libgtk:i386 (I'm not on Debian, so I don't know exact library name, sorry)
viayuve
14:19Failed to load module "canberra-gtk-module"
14:20apt-get install libgtk-3-0:i386
14:20that installed it but now module not loading
loziniak
14:20You'll find most of the info here: https://github.com/red/red/wiki/[NOTES]-Gtk-Bindings-Development
viayuve
14:26thanks this worked https://github.com/rcqls/reds/blob/master/README-RedGTK.md
rebolek
14:29:+1:
viayuve
14:40@rebolek how to do like separate function and data collection
14:41data collection in with view
rebolek
14:42@viayuve you mean some list?
viayuve
14:43what i am trying to do is use Atomica program and put it in GUI form
14:43so like this view [
title "AtomicaAtom"
s1: field
p1: field
v1: field
button "InsertAtom" [insertatom s1/text p1/text v1/text]
]
rebolek
14:44I'm not very familiar with AtomicaDB, but something like that should work.
viayuve
14:44it definitely works but like have to run in separate gui cosole first drop Atomica program in and than load vid after that
rebolek
14:45Ah, I see. Well, that's not very easy to do.
viayuve
14:46i can perform all function with vid I created
14:46how you suggest should i go?
14:47but i like to do something like this red -c atomica.red and load data plus gui
rebolek
14:47you can start the view-console you compiled, open atomica there and then load your gui
viayuve
14:47any small example i can look and learn from it.
rebolek
14:48or do you want console and gui running at the same time?
viayuve
14:49i don't want console at all just gui to interact with
14:50i created small loan servicing app in red want to combine it with Atomica so store data.
14:52what my app doing is just temp data holding once closed it destroy temp .
14:53you told me something in windows but don't remember now
14:53or someone else did
rebolek
14:54If you want some GUI on top of Atomica, it's as easy as
Red[]
do %atomica.red ; or how it's called
view [] ; your gui here

loziniak
14:56Or if you intend to compile the app, perhaps it's better to #include istead do.
rebolek
14:56right
ne1uno
14:57#include fails if you later have to encap
viayuve
15:30Red [
File: %atomica.red
Version: 0.2.3
needs: view
]

if not exists? %data/atomica.db [make-dir %data write %data/atomica.db ""]
Atomica here

if flagit = true [atomica: head atomica saveit]
]

loadit

view [
title "AtomicaAtom"
s1: field
p1: field
v1: field
button "InsertAtom" [insertatom s1/text p1/text v1/text]
]
15:31@rebolek it do not open gui
rebolek
15:36@viayuve it should, is there any error?
viayuve
15:36no error at all
rebolek
15:37how do you run that script?
ne1uno
15:37there is no module system, you have to do' or #include`
viayuve
15:38using vs code "/media/john/5977afdc-a895-47a9-8f6d-fdbd693604e5/red/red" "/media/john/5977afdc-a895-47a9-8f6d-fdbd693604e5/red/program/atomica.red"
rebolek
15:39then you are using non-view Red and need to run it using view-console you compiled
viayuve
15:39i renamed it
rebolek
15:40ok, so run try running the script from your console directly to see any error messages
viayuve
15:41it runs in console thats i am trying to say not running like red red.red but if i drop it in console it works
15:44everything works in console no errors even i can perform all functions with gui
15:46@ne1uno what module system
ne1uno
15:46I wasn't sure if you inlined the script or didn't include it
viayuve
15:48its one file everything in same file
ne1uno
15:57probe system/options/boot check which executable
viayuve
15:59>> probe system/options/boot
"./red"
== "./red"
ne1uno
15:59from script in vs code?
viayuve
16:02"/media/john/5977afdc-a895-47a9-8f6d-fdbd693604e5/red/red" --cli "/media/john/5977afdc-a895-47a9-8f6d-fdbd693604e5/red/program/probe.red"
{/media/john/5977afdc-a895-47a9-8f6d-fdbd693604e5/red/red}
16:04that is a same console app that i compiled with the help of @rebolek and @loziniak
16:04Lets try #include
16:14wow its working with #include not in same file but why?
16:18one more question once we close gui terminal still shows in gui console have to manually do ctrl +c to break in any solution for that?

temperfugit
01:46@viayuve I may be misunderstanding what you want---is it that the console isn't closing after you close the View window? As long as you're not using View with the no-wait refinement then you can just add "quit" (without quotes) to your script after the view block and the console should close after the GUI does. If you are using no-wait then I think you can put "on-close [quit]" near the top of the view block for the same results.

GiuseppeChillemi
17:50Hi,
I have this one:

f1: does [f2: does [print "Hello"] :f2]


Expected do f1 or reduce f1 or do reduce f1 to output Hello
hiiamboris
17:54No. It's do reduce [f1].
GiuseppeChillemi
18:02trying
do reduce insert copy [] f1

No result...
hiiamboris
18:09
>> f1: does [f2: does [print "Hello"] :f2]
== func [][f2: does [print "Hello"] :f2]
>> do reduce [f1]
Hello
18:11You should use probe to check intermediate results, to not act randomly ☺
GiuseppeChillemi
18:18@hiiamboris I know it worked this way, I was trying to find a syntax to let this work.

>> library: reduce ['f1 does [print "Hello"]]
== [f1 func [][print "Hello"]]
>> myselector: func [arg] [select library arg]
== func [arg][select library arg]


>> myselector 'f1
== func [][print "Hello"]
>> do reduce myselector 'f1
== func [][print "Hello"]


Expected Hello

I used this working scheme to have in Rebol libraries of functions accessed by custom selectors but actually it seems to me impossible to use it in Red.
18:22Note: I know I can use the path syntax library/f1 but I wish to use an intermediate function accessor to decouple the library from the end user.
hiiamboris
18:22Are you telling me that you are unable to figure out how to combine do reduce [f1] and do reduce myselector 'f1 ? ;)
GiuseppeChillemi
18:24Yes, I am not! (imagine it using Simpson's "Bo" voice)
18:24But wait a minute, if there is a way I will find it...
18:24Please don't write the solution !
hiiamboris
18:25That's the spirit! ☻
GiuseppeChillemi
18:35Well:

>> do reduce [myselector 'f1]
Hello


.. but

>> a: [x [myselector 'f1]]
== [x [myselector 'f1]]
>> do select a 'x
== func [][print "Hello"]


Selecting a code block to does not work.
hiiamboris
18:37do by design does not evaluate functions given to it
GiuseppeChillemi
18:37To whoever will ask "why are you doing this: I am trying to understand the possibilities and limits of Red into manipulating bricks of code.
hiiamboris
18:37that's why you should use reduce **with a block**
GiuseppeChillemi
18:39do reduce select a 'x
18:39Does the work
18:41Why has it changed from Rebol2? Is it the **unpredictable arity** problem you have talked with me in the past ?
hiiamboris
GiuseppeChillemi
18:43Also, does reduce pose some limits into code sequences stored in blocks?
hiiamboris
18:45What do you mean?
GiuseppeChillemi
18:48Pardon my ignorance but I have not gone deep into the reduction mechanisms so I don't know if a code block reduced and then executed by do has to be different from a code block excuted by x: load %code.red do x
hiiamboris
18:50reduce is basically do/next until it meets the end of block
18:53Since you're lazy to insert probe I'll upload you a more fun tool.
GiuseppeChillemi
18:54Oh, I have discovered something new:

>> a: [x: [myselector 'f1]]
== [x: [myselector 'f1]]
>> probe reduce a
[[myselector 'f1]]
== [[myselector 'f1]]


Set words of a reduced block disappears !
hiiamboris
GiuseppeChillemi
18:56As you can see I am not so lazy... but I confess having a great fear of learning wrongs things as it happened in the past. This is why I ask here, to have the hidden details and rules that I may be learing in a bad way)
18:57These things are only know by the masters.
hiiamboris
19:14@GiuseppeChillemi https://gitlab.com/hiiamboris/red-trace-mezzanines try this. I'm lazy too and I need testers anyway ;)
I will only work correctly with recent builds though
GiuseppeChillemi
20:38When I'll be back in front of my PC I will try. I am so excited waiting to see your tool!
20:42(I am not an English speaker but this phrase sounds with a double meaning in my head.. 🤔)
hiiamboris
GiuseppeChillemi
22:33@hiiamboris few notes:

>> show-trace [do reduce [myselector 'f1]]
reduce [myselector '  =>  [func [][print "Hello"]]
Hello
do [func [][print "H  =>  unset


More characters on the left would be welcome, at least 20 more...
Having the result in the second line confuses me. It should be at the end of the sequence
Final note: fantastic tool !
hiiamboris
22:35Find 20 20 at the end of the script, increase ;)
22:36> Having the result in the second line confuses me

What do you mean? It executed print so it inserted a line inbetween.
22:39(it can't know the result of code execution.. without executing it)
bferris413
23:56why doesn't red --cli support history, or moving the cursor with arrow keys?
23:56on Windows

endo64
09:15@bferris413 Are you using Windows Terminal (beta), ConEmu or similar? it works for me with normal cmd but not with others.
hiiamboris
10:33Works with ConEmu on W7 for me. Just normal arrow keys rather than those on keypad.

bubnenkoff
11:57"A word is a variable if and only if it is bound to a context (has a context, is in a context)"
What kind of context? If context is function word is variable?
9214
12:16Word is always bound to a context, and it's never a "variable". And I think I already explained to you dozens of times that context is essentially a namespace, a mapping between symbol and a value, word and its "meaning", a 2-column table. Values of datatypes any-object! and function! are the only ones that provide contexts (but they are not contexts themselves), they are also called "context constructors" because of that.
Re-git
12:24Is it possible to use Red to bundle few files together into one file, something like a zip archive?
toomasv
12:53@Re-git https://github.com/rebolek/red-tools/tree/master/packers
rebolek
13:02@toomasv thanks! @Re-git yes, *exactly* like a zip archive:-) or tar, if you prefer. If you have any question about those functions, I'm happy to help.
bubnenkoff
13:26is it's correct to say that all code elements are words?
rebolek
13:27it's correct to say that all code elements are values
13:27look at this code:
13:271 + 1
13:28there are three values, two integers and one word
bubnenkoff
13:29one word? Where is word?
13:29+ is word?
rebolek
13:30Start with simple steps:
>> code: [1 + 1]
== [1 + 1]
>> foreach value code [print type? value]
integer
word
integer
bubnenkoff
13:31so maybe it's more correct to say that Red is consist from words and digits?
rebolek
13:31certainly not. What about strings? And other types?
13:32Everything is a value and every value has specific datatype.
9214
13:57@bubnenkoff there are around 50 datatypes in Red, and every value you interact with has one. Consider to re-read a lengthy explanation that I gave (exclusively) to you in a Github gist some time ago, it's all covered there.
bferris413
14:04@endo64 Thanks for the notes, was using in Windows Terminal
bubnenkoff
14:06@9214 I am rereading your explanations time to time. But still not have proper mental conception for understanding such details. If + is word what is :? It's not word, right?
9214
14:13It's not a word, it's not even a value, it's a lexical part of a get-* or set-* values, like e.g. ,:very/long/get/path or set-word:. And that part was also explained to you personally.
rebolek
14:37values are (usually) separated by space. If there's no space, it's (ussualy) one value. There some understandable execptions to this rules, like [no space]
bubnenkoff
15:11Why event do not rise? view [button "sdf" on-alt-up [print "sf"]]
15:12I am pushing keyboard button and do not get any effect
rebolek
15:12IIRC, alt-up is right mouse button
Re-git
15:54@toomasv @rebolek thank you! That is exactly what I was looking for.
17:08I'm trying to compile my program for macOS with ./red -c -e -r -t macOS MyProgram.red
as a result i get MyProgram.app file but its only 748 bytes in size. It does not run.
It's basically just empty package with only 'Info.plist' file inside. I'm using the most recent red binary and there are no errors during compilation.
9214
17:14@Re-git -c and -r are mutually exclusive options. Try -t Darwin also.
Re-git
17:20@9214 i have removed -c and the result is the same. Looks like compilation with macOS target is not working.
17:24-t darwin works but then it opens terminal window in addition to the view GUI. Is there a way to stop that?
9214
17:36I cannot reproduce the bundle issue on Mojave.
Re-git
17:39That's interesting. I'm also on Mojave 10.14.3.
18:00Thank you @9214 . Thanks to you I kept trying and figured out that compilation indeed works as long as I do it inside my user folder. I was having the issue with compilation because i was trying to compile inside /Library/Application Support folder and then the last step with making a bundle was failing. Maybe there is some issue with path or permissions. Interesting thing is that when I was compiling with -t darwin then everything was working ok.
9214
18:09@Re-git you're welcome. Yes, sounds like you didn't have writing permissions. Worth to jot down a note about this for future reference, maybe [here](https://github.com/red/red/wiki/%5BDOC%5D-Guru-Meditations).

bubnenkoff
10:39>Word is always bound to a context, and it's never a "variable"

So what is the principal difference? Variable can be declared but may have not value, but word always should have value? In many dynamic languages variable can be value or function
meijeru
11:13A function is also a value!
bubnenkoff
11:21word is more height level abstraction? And in comparison of variable it continue store as key:value, when variable become only address in memory?
9214
11:23@bubnenkoff this and all the other questions were [already](https://gitter.im/red/Russian?at=5e42c13e1d23aa47aa09a816) answered to you many, many times.
bferris413
14:05@9214 is that diagram posted somewhere permanent? Handy
GiuseppeChillemi
14:06@bferris413 Save it on your PC, it is really precious. I have at least 3 copies.
rebolek
9214
14:08@bferris413 not yet. It should be tattooed on ones forehead for lasting effect though.
GiuseppeChillemi
17:17@bubnenkoff Start with simple concepts. A word can exist in different contexts. It has an independent value in each context where it is "declared". When you write: a: 22 in the main code block, it is like you "declare" it to have value 22 in the system/words context (the default one). If you also create another context using myobj: make object! [a: 555 x: 33] you declare that in the context myobj also it has value 555. You can get the value of a in one or another context any time you want:

Try this:

a: 22
myobj: make object! [a: 555 x: 33]

>> get in myobj 'a
== 555
>> get in system/words 'a
== 22

17:56A question about VID/VIEW: if you have not stored womewhere the label assigned to a face, there is no way to know the name of it from the inside of the event handler code. The face tree has no list of the used labels, has it ?
hiiamboris
18:01no, it has not
GiuseppeChillemi
18:12Indeed, it is a tree of objects and they are anonymous.
I am trying to map a group of words to their respective edit face label, there are a lot of available ways like storing the label name in face/extra, creating an object with word/label couples. Have you any other good suggestions?
hiiamboris
18:17what's stopping you from just searching for a face with a certain "text"?
GiuseppeChillemi
18:20Because I prefer to use a path syntax for many reasons. They are the columns of a table and the end-user should see its dedicated name and not a short csdesc in place of Customer Description.
hiiamboris
18:23hard to advise without seeing the full picture
18:23just trust your own judgement ;)
greggirwin
20:28@GiuseppeChillemi if you use small wrapper funcs, e.g. find-face, get-face you can extend it to find in various ways. You can also generate your VID spec programmatically, inserting set-words to reference faces, or set refs when building a view tree yourself.
20:29The use cases are finding a single face by ID, and finding all faces that match a spec.
GiuseppeChillemi
20:38@greggirwin
Actually I am using naming conventions: if I have a database field called user-id its edit field will be composed to lbl-user-id, but I don't like this approach. Instead of relations defined naming rules I prefer relations defined by structure.
I don't undestand what you mean for "small wrapper functions" as to me get-face is well defined VID instruction, so I could extend it ?
greggirwin
20:45Get-face is in R2, but not Red, but it was just a quick name that came to mind.
get-face: func [spec][
	switch/default type?/word spec [
		word! [get spec]
		string! [] ; search via face/text
		issue!  [] ; search via face/extra
	][] ; default, search via face/data
]

If you only need to select a face, that's all you need. A Find* alternative can let you find a face in a pane block, which may have a fixed set of faces following it, so you just name key faces and get others based on that.
GiuseppeChillemi
20:50@greggirwin Thanks, get-face confused me.
21:05Gregg, I admit I am not understanding the purpose of your code and what it should return
greggirwin
22:22It should return a face.
>> view [x: button]
>> get-face 'x
== make object! [
    type: 'button
    offset: 10x9
    size: 78x27
    text: none
    image: none
    color: none
    men...
GiuseppeChillemi
23:27Is it safe to assume any face has face/extra ?
endo64
23:48Yes, because base face! object has extra, you can see it by ? face!.

beenotung
06:12How do you look for libraries ?
06:13I'm trying to find a way to build web server in red only found this example so far.
06:13http://www.rebol.net/cookbook/recipes/0057.html
greggirwin
06:21@beenotung Red doesn't have ports yet (due in 0.7.0), so you can't write a web server with it right now.
abdllhygt
17:41hello!
17:42is there a function for list matrix block by higher number
17:43for example;
[
["a" 2]
["b" 3]
["c" 2]
]

i want to replace it like this;
[
["b" 3]
["a" 2]
["c" 2]
]
greggirwin
17:54You can use a custom comparator with sort. e.g. sort/compare/reverse blk func [a b][a/2 < b/2]
17:55You could also reverse the comparison itself, sort/compare blk func [a b][a/2 > b/2], though I like to use /reverse to denote descending sorts.
abdllhygt
18:03@greggirwin thank you!

rsheehan
17:02With parse is it possible to use alternatives to "[" and "]" when using "into" to enter a recursive parse?
In particular I would like to use different tags e.g. <begin> and </begin> bracket the recursive parse.
The following code works but I would rather not have to include the "[" and "]" with the begin and end tags.
re: [ 
    collect [
        set name word! keep (reduce ["name:" name])
        [
            <begin> into re </begin>
            |
            end
        ]
    ] 
]

probe parse [a <begin>[b <begin>[c]</begin>]</begin>] re

9214
17:21@rsheehan into is intended to be used with series! values. If you want to parse a linear structure and match opening/closing elements, then you need to maintain the stack yourself.
rsheehan
17:24@9214 Thanks. I suspected as much.
giesse
18:52@rsheehan I don't see why you'd need into in your provided example.
>> re: [collect [ahead word! keep (first [name:]) keep word! <begin> re </begin>]]
== [collect [ahead word! keep (first [name:]) keep word! <begin> re </begin>]]
>> parse [a <begin> b <begin> c </begin> </begin>] re
== [name: a [name: b [name: c]]]

dsunanda
12:09Is there a way to have newlines in the text of a button? This does not work:
view/no-wait [button 100x100 "hello^/goodbye"]
hiiamboris
12:32looks like we're missing something there
12:32https://stackoverflow.com/questions/42937984/multiline-button-in-winapi
12:32@qtxie ^^
abdllhygt
13:14how can i add block into block?
13:18i want;
blk: []
newblk: [1 2]
append blk newblk ; i want the result is [[1 2]] but [1 2]
rebolek
13:18@abdllhygt Hi!
>> append [1 2 3] [4 5 6]
== [1 2 3 4 5 6]
>> append/only [1 2 3] [4 5 6]
== [1 2 3 [4 5 6]]
pekr
13:18append/only blk newblk
rebolek
13:19:mouse: :speedboat:
pekr
13:19@rebolek ... never sleeps :-)
rebolek
13:19at 14:19 almost never :-)
abdllhygt
13:19@rebolek thank you!
Nomarian
16:09I'm in #red-lang in freenode, someone is asking if its possible to use red in openbsd
rebolek
17:32@khwerz I noticed that, thanks, I'll answer in 1-2 hours, once I'm free.
greggirwin
18:03For the multiline button, should that be tied to an as-is flag? Otherwise all buttons will start wrapping. It can be worked around via manual sizing, but this is a new feature, so better not to break things if we can avoid it.
hiiamboris
18:17Wouldn't it be better to wrap the button text rather than just clip it?
18:18In any case, wrap flag is unused for it.
greggirwin
18:31:+1:
fergus4
18:44Not exactly a Red questions but it is a Cheyenne question so I hope its ok...
(for those not in the know, Cheyenne is a rebol based web server developed by Nenad (Doc))
I'm getting a repeating error that seems to knock out RSP eventually...Based on the following is there a way to track down the offending script...
From trace-80.log
20/3-10:48:48.669-## Error in [task-handler-54776] : Make object! [
    code: 903
    type: 'internal
    id: 'globals-full
    arg1: none
    arg2: none
    arg3: none
    near: [either pos: find/skip out name:]
    where: 'decode-cgi
] !

From chey-pid .log
20/3-14:20:57.331-## Error in [uniserve] : On-received call failed with error: make object! [
    code: 311
    type: 'script
    id: 'invalid-path
    arg1: 'root-dir
    arg2: none
    arg3: none
    near: [cfg/root-dir req/in/path req/in/target]
    where: 'rejoin
] !

18:45Sorry for the post but Rebol Altme chat seems to be down...
dockimbel
19:02@fergus4 Hi Alan! globals-full means you have exhausted the number of words Rebol2 can handle. You can just kill the worker tasks to spawn new clean ones. If that happens often, then you need a suicide code that will quit if the number of words in system/globals grows too close to the limit (IIRC, R2 has a limit around 32k).
19:05The second error seems related to a missing root-dir directive in the config section of the site or webapp. That's odd because IIRC, Cheyenne will auto-inject that property if not present already. So it might be a rooting problem leading to cfg not pointing to a valid configuration block.
19:06@x8x is a heavy Cheyenne user, so maybe he can give more insights about those errors as I haven't used Cheyenne since many years.
fergus4
19:27Thanks Doc, Hope all is well. Looking forward to 2020 Red!
dockimbel
19:38So far, we are fine, thanks.

qtxie
02:39> looks like we're missing something there

Yes. We should add this flag when detect newline in the text of a button.
dsunanda
09:08Newline in button text - thanks for the replies....I'll add it as a GitHub issue

meijeru
10:01A small contribution to the better understanding of why/when is copy needed:
>> a: [1 2 3 4]
== [1 2 3 4]
>> b: next a
== [2 3 4]
>> c: copy b
== [2 3 4]
>> index? b
== 2
>> index? c
== 1
>> head b
== [1 2 3 4]
>> head c
== [2 3 4]
rebolek
10:41:+1:
endo64
11:51And a few more:
>> same? a b
== false
>> same? a head b
== true

>> equal? b c
== true
>> same? b c
== false
bubnenkoff
13:20
>> view [s: slider [print s/data] text to-string s/data]

*** Script Error: VID - invalid syntax at: [to-string s/data]
*** Where: do
*** Stack: view layout cause-error


Why I am getting error?
rebolek
13:20Because you are mixing VID dialect with Red code.
bubnenkoff
13:23Which part is red code here?
rebolek
13:24to-string s/data
13:24view accepts block with VID dialect
13:24See the documentation for VID to understand what you put there
bubnenkoff
13:25Is there any difference between to string! and to-string ?
rebolek
13:25Basically no
13:25The point is that it's *not* valid VID dialect.
9214
13:38
text
view [s: slider text react [face/data: round s/data]]
bubnenkoff
13:43What purpose of face here?

Why I need to use it instead accessing in this way:
view [s: slider [t/text: to-string s/data] t: text]
rebolek
13:45face points to current face, so you can use it even if your face has no name: input [print face/text] vs i: input [print i/text].
9214
13:46It's all in the documentation, FYI.
rebolek
13:46Both versions (your and Vladimir's) should work same, but @9214 used reactive features.
bubnenkoff
14:19Am I right understand that in VID code always look:
word block or another word. So first variant syntactically 100% correct, but not working? How to debug such cases?
>> view [s: slider t: text [t/text: to-string round s/data]]
>> 
>> view [s: slider [t/text: to-string round s/data] t: text] ; that's right!

14:21Why for example this code not working?
view [slider [t/text: to-string round face/data] on-change [print "change event"] t: text]

hiiamboris
14:21When do you think [t/text: to-string round s/data] will be evaluated, in all three cases?
bubnenkoff
14:23> When do you think [t/text: to-string round s/data] will be evaluated, in both cases?

hm... in first case after t: text that will not happen. right?
hiiamboris
14:24What does t: text mean in VID?
bubnenkoff
14:24bind word with widget
hiiamboris
14:26Yes. So how can you discover if the widget gets created or not?
bubnenkoff
14:28eghm... by next block []?
hiiamboris
14:29There are simpler ways, like giving it a distinctive color...
bubnenkoff
14:39I am not understand the logic. For example why in next code text do not changing?
view [slider [t/text: to-string round face/data] on-change [print "change event"] t: text]


hiiamboris
14:40[t/text: to-string round face/data] what does this part mean in VID?
bubnenkoff
14:41set widget text to data from slider converted and rounded to string
hiiamboris
14:42That's what the code in the block does. Yes. But what a block in VID code after a face (slider) means, in general?
14:43Or like I asked earlier,
> **When** do you think [t/text: to-string round s/data] will be evaluated?

bubnenkoff
14:44when slider will raise any event?
hiiamboris
14:44Not any, just one specific event.
bubnenkoff
14:44on-change?
hiiamboris
14:44Yes ;)
14:44And you're overriding it just after
bubnenkoff
14:44oh! Thanks!
hiiamboris
14:44You're welcome
bubnenkoff
14:55Does my logic is correct?
view [
    slider [
        t/text: to-string round face/data 
            [
                if face/data = 100% [print "Hello"]
            ]
         ] t: text
    ]


I am trying to print Hello at 100%
hiiamboris
14:59I see a block of data.
bubnenkoff
15:02it should be bind with event?
hiiamboris
15:02No, it just should be evaluated somehow
bubnenkoff
15:02for example how?
hiiamboris
15:03With do?
bubnenkoff
15:04works!
hiiamboris
15:04Fantastic ;)
bubnenkoff
15:08When we are writing
widget block like: foo []
do is calling under the hood?

Example: view [button [print "Hello"]]
hiiamboris
15:08Yes.
bubnenkoff
18:31is there any difference between: >> x: [1 2 3]
>> y: copy x

and:
>> y: copy :x

hiiamboris
22:58
>> bin: to binary! mold system
>> length? bin
== 5111365

>> length? compress bin
== 4064159
>> length? compress/zlib bin
== 4064147
>> length? compress/deflate bin
== 4064141

>> i: make image! 5111x1000 / 1x4
>> i/argb: bin
>> length? save/as #{} i 'png
== 2663158

...
22:59Assuming we don't want people to use images to store data - is LZO or LZ4 or LZMAT compressor planned for Red?
23:04LZO gives 3163811 bytes, LZ4 and LZMAT just slightly more. LZMA (slower) - 2260512
greggirwin
23:12What we include as standard depends on overall usefulness versus size added. Better compression is great, but if a format isn't in widespread use, it has less value.
hiiamboris
23:25Even more Interesting... gzip (Deflate algo) gives worst result of 2597500, whereas Red implementation of the same - 4064141

fergus4
02:15Is Red able to 'Post to URL? or is that planned for i/o update?
greggirwin
05:04[Here](https://github.com/red/red/wiki/%5BDOC%5D-Guru-Meditations#how-to-make-http-requests) is a short answer. @rebolek can chime in and point you to his much richer tools in that area.
rebolek
07:08@fergus4 I wrote [http-tools](https://github.com/rebolek/red-tools/blob/master/http-tools.red) where you can find make-request function to simplify this stuff. It handles stuff like autoconversion to/from JSON or URL-encoding, authentication and other things. Feel free to ask about usage details.
qtxie
11:34@hiiamboris The current implementation uses a static Huffman table. It just works, not optimal. We don't want to waste time to port zlib or other similar libs. We'll be able to static link with them later.
hiiamboris
11:35I see. Thank you.
fergus4
14:32@rebolek Thanks for the link Bo. I looked it over but let me just ask before a dig too deep, if what I want to do is possible with it. Here is the curl statement I want to implement in red:
curl -X POST https://fax.twilio.com/v1/Faxes \
--data-urlencode "From=+1631999999" \
--data-urlencode "To=+1631444444" \
--data-urlencode "MediaUrl=https://www.twilio.com/docs/documents/25/justthefaxmaam.pdf" \
--u My_ID_cfwsedfwefewf:MY_PW_dewfdewcswf

14:35Ironically I can't get it to work in curl either...Not sure what I'm doing wrong but if I can't do it in red yet I could call curl...if I can get that to work...
rebolek
14:43@fergus4 This should be possible. URL encoding and basic authentication are both supported. I'll write an example query for you later.
fergus4
14:45Awsome, thanks

rebolek
09:23@fergus4 sorry for the delay, here's the query:
ret: send-request/data/auth https://fax.twilio.com/v1/Faxes 'POST [From: "+1631999999" To: "+1631444444" MediaUrl: https://www.twilio.com/docs/documents/25/justthefaxmaam.pdf] 'basic [My_ID_cfwsedfwefewf MY_PW_dewfdewcswf]

09:30Few details:

/data field is just a Red block. Conversion to URL encoding is done automatically. If you provide map! instead of block!, data are converted to JSON. If you want full control over data type, provide a string! instead and no conversion is done.

/auth takes two args, type - basic in your case (I believe, that's what -U does in curl) and block of user and pass. Again, conversion to an appropriate format is done automatically.

As you can see, send-request does a lot of work for you. You can add /verbose refinement to see what's send (good for debugging). send-request returns map! with four keys: [code headers raw data]. code is HTTP return code, headers are self-explanatory, raw are raw data and data are decoded data. If it receives, for example, JSON, it converts it to map! automatically, so there's again less work for the user.
09:36If you don't care about additional details (e.g. you're sure your query is well-formed and you can't get an error), you can use /only refinement. /raw turns off auto-conversion of returned data and returns raw binary data.

If you want to provide additional headers, use /with refinement.

These are the basics, if you have any questions, feel free to ask. There's still lot of room for improvements, for example I've done some initial work on automatic cookie management, but that's still in an early phase.
fergus4
13:09@rebolek It worked like a charm!!! Thank you very much, Bo"
rebolek
13:10Great news, I'm happy to help!
fergus4
13:11Can it be used to send a binary?
13:13Is that what /raw does?
rebolek
13:13Yes, although there may be some limitations related to max. size. I was working on a solution, but hadn't finished it yet due to lack of time.
13:14No, /raw is for returning data. Let me find my notes.
13:16It seems that the limitation is not related to send-request but to using Red as CGI. So it should work.
13:18But maybe you need to uuencode your binary first.
bubnenkoff
14:06How to get know context of the word?
meijeru
14:16Use context? this gives you an object; the global context is equal to system/words.
14:17Have you ever taken a look at [this document](https://github.com/meijeru/red.specs-public/blob/master/specs.adoc)? It is not a tutorial but contains precise descriptions of many features of the language.
14:18For instance, have a look at sections 2.4 and 6.
cloutiy
15:39Hello, I'm playing with some ideas but not sure of the approach I should take.

I want to make a function that converts a function into an operator with the same name.

For example a . function. In example below I would like it to make the function filter (which takes 2 args) and convert it into an op so that it can be used as infix. So that it can be called like this:

[ 1 2 3 4 ] . filter { |n| n % 10 = 0 }


rather than like this:

filter [ 1 2 3 4 ] { |n| n % 10 = 0 }

Is this something that is at least possible to do? Something like:

.: function [ f ] [ make op! :f ]

??
hiiamboris
15:50not without macros or additional reduce, or custom dialect preprocessor
15:51it's not like you'll have hundreds of functions like filter anyway, so isn't it easier to make those operators in advance? like .filter: make op! :filter
15:53wait, I have an idea
15:54you can make filter return a thunk, sort of, that . operator will accept and process
15:55but that will render filter itself useless probably, and is too much complexity (for what?)
cloutiy
16:13@hiiamboris Basically I'm trying to see if possible to reproduce something similar to Elixir or F# where the output of function a is piped as first argument to function b. For example:

[ 1 2 3 4 ]
   |> multiply-by 3
   |> sort

where multiply-by takes 2 args - a list and a value to multiply by, and sort takes 1 arg.

To form a sequence of actions where the output of one is sent to the input of the other. When the function takes more than 1 arg, the output of the previous one becomes the 1st arg of the next one (for example multiply-by: function [ a-list a-multiplier ] [ ... ]
hiiamboris
16:25Yes, I understand. Almost everyone (including me) tackled with this exercise ;)
16:25There's even a wish for it https://github.com/red/REP/issues/49
16:28I personally settled on a most lightweight approach, coined by @9214. Not exactly chaining of expressions but faster and even more flexible. Looks like this:
stepwise [
		skip r 8  insert . "-"
		skip . 6  change . "-"
		skip . 3  clear .
	]
16:28. holds the result of last expression
16:33The only issue with it is that it traps return & exit ;)
9214
16:44Writing an opinionated version of threaded macro is a rite of passage at this point.
->: make op! func [○ body][
	body: bind body 'body
	get/any also '○ until [
		set/any '○ do/next body 'body
		tail? body
	]
]

3 -> [
	○ * ○ + ○
	form ○
	reverse ○
	load ○
	○ << (○ / ○)
]
hiiamboris
16:45I also plan to make a rewrite-macro that will solve return problem, and allow usage in loops. But so far I used it like 2-3 times ;)
greggirwin
18:18Create a threaded macro wiki page? Anyone, anyone, ...?
hiiamboris
18:27"[GUIDE] Threaded macro epic quest walkthrough"
greggirwin
18:34"Macro Quest" sounds like a great game.
hiiamboris
giesse
18:40Just write a Forth dialect at that point?
greggirwin
18:51I have an old func for walking series actions, and @rebolek did one called dot at one point. Ended up not using mine nearly as much as I thought when I created it. And there's something funny about using advanced functional approaches to emulate imperative code. :^)
cloutiy
19:05lol threaded macros...ok I think I'll just call functions the old-fashioned way ;)
9214
19:07@cloutiy it's a Lisp term ([Clojure](https://clojure.org/guides/threading_macros), [Racket](https://docs.racket-lang.org/threading/index.html)).

bubnenkoff
08:45Can we talk about context how about list of words?
context_1: [word_1, word_2, word_3]

And context binding is way to bind word with another context. Like:
context_1: [word_1, word_2]
context_2: [word_3] ; word_3 was re-bind with another context?
meijeru
10:07I must again refer you to the document I mentioned earlier. A context is an object! value, not a list (block!) value. That being said, the answer to your question is that each _occurence_ of a word! value in the program text has its own context, and this can even be changed by the bind function.
bubnenkoff
11:35
>> obj: object [a: 1]
== make object! [
    a: 1
]
>> 
>> context? 'a
== make object! [
    datatype!: datatype!
    unset!: unset!
    none!: none!
    logic!: logic!
    block!: block!
    par...
>>


a should be context of obj?
9214
11:51@meijeru that's not entirely correct. object! (among other values), provides a context to bind to, but is not a context itself.
>> fifth spec-of :bind
== [any-word! any-object! function!]

In that light, phrases like "bind block to an object" or even context [...] are synechdoches that we use in everyday speech.
bubnenkoff
12:30> Use context? this gives you an object; the global context is equal to system/words.

Could you show an example? I post my code above, but I do not see mantion about context
hiiamboris
12:44Don't you see that in your own example context? gave you an object, just like @meijeru said?
Oldes
12:59@bubnenkoff isn't this what you want?:
>> context? in obj 'a
== make object! [
    a: 1
]
meijeru
13:04It is true that the result of context? is _either_ an object! value, _or_ a function! value (for arguments of functions). This is by the way explained in the spec document to which I referred in an earlier answer. I only mentioned object, in order to contrast it with block.

viayuve
13:32pre built arm
13:35@rebolek down
bubnenkoff
14:40how to view all available contexts?
hiiamboris
14:45no way
bubnenkoff
14:50Every dialect (do, parse, VID) have own context, right?
9214
14:50@hiiamboris OTOH, one can deliberately list all object! and function! values currently reachable, if that makes sense at all.
hiiamboris
14:52like GC does?
14:53I think it cheats though, as it also knows what's unreachable
14:55@bubnenkoff you're mixing things
9214
14:56@bubnenkoff no. Please stop playing guessing games and start listen to what other people say to you.

Word is a pair of a symbol (spelling) and a binding to a context (meaning). Context, in turn, is a list of pairings between symbols and values. object! and function! values provide such tables for words to bind to. That's all there is to it, and that's what I keep repeating and rephrasing to you for months.
14:58Dialect can utilize contexts and bindings if it needs to, but conceptually they are completely unrelated to each other.
16:13Here, look at this simplified model:

* Each word consists of two parts: spelling and meaning. Both should be present for the word to be formed, both are mandatory.

[<spelling> <meaning>]


* Spelling is a string that gives word a distinct look. In the example below there are 3 words with the same spelling and the same context.

[foo :foo 'foo] → [["foo" <global context>] ["foo" <global context>] ["foo" <global context>]]


* Meaning is a link to a "thesaurus" that gives word a precise definition. This thesaurus is not directly embedded in a word but stands separately. What thesaurus does is simply listing of spellings and things that they denote.

"car" is a vehicle
"cat" is an animal
"one" is an integer
...


* So, taking [pi tail zero?] as an example:

all are bound to the same (global) context (thesaurus)
[pi tail zero?] → [
    ["pi" ["pi" is 3.14159265353897932384 ...]]
    ["tail" ["tail" is an action that gives you the tail of a series ...]]
    ["zero?" ["zero?" is a predicate that returns true if value is zero ...]]
]


* If you want to change the entry in a thesaurus to which word refers, you use set or set-word!. In our model that would the same as taking the spelling, taking thesaurus, searching for spelling in it and putting a new value.

>> thesaurus: ["pi" 3.141592653589793]
== ["pi" 3.141592653589793]
>> pi
== 3.141592653589793

>> put thesaurus "pi" "pie"
== "pie"
>> pi: "pie"
== "pie"

>> thesaurus
== ["pi" "pie"]
>> copy/part find body-of system/words 'pi 2
== [pi: "pie"]


* Now to the interesting part. Spelling and meaning are mandatory parts of the word. But can they be changed? Spelling cannot (although in Rebol you could use alias for that), but meaning can. This is what bind does, it changes the meaning of a given word by *changing the link to thesaurus that it contains*.

>> word: ["pi" ["pi" 3.141592653589793]]
== ["pi" ["pi" 3.141592653589793]]
>> pi
== 3.141592653589793

>> word/2: ["pi" "pie"]
== ["pi" "pie"]
>> word
== ["pi" ["pi" "pie"]]

>> bind 'pi context [pi: "pie"]
== pi
>> get bind 'pi context [pi: "pie"]
== "pie"


* It should be really stressed out at this point that, while two words can have same spelling and the same meaning, they are nevertheless *different* word values. In the example above, the first 'pi and the second 'pi are different, and binding one does not affect the other (or any other pis you might have in your code).
16:21Two words can share the same spelling. Two words can share the same meaning. Meaning can be changed. It follows that you can have two words with the same spelling but different meanings.
>> cutlery: [spoon spoon spoon spoon]
== [spoon spoon spoon spoon]
>> phrase: split "there is no spoon" space
== ["there" "is" "no" "spoon"]
>> forall cutlery [bind cutlery context [spoon: take phrase]]
== [spoon]
>> cutlery
== [spoon spoon spoon spoon]
>> print cutlery
there is no spoon

Here's how cutlery looks like under the hood:
[
    ["spoon" ["spoon" "there"]]
    ["spoon" ["spoon" "is"]]
    ["spoon" ["spoon" "no"]]
    ["spoon" ["spoon" "spoon"]]
]

>> forall cutlery [print context? cutlery/1]
spoon: "there"
spoon: "is"
spoon: "no"
spoon: "spoon"
16:38
text
make*: func [spelling [string!] meaning [block!]][
	reduce ['spelling spelling 'meaning meaning]
]

set*: func [word [block!] value [any-type!]][
	put word/meaning word/spelling value
]

get*: func [word [block!]][
	select word/meaning word/spelling
]

bind*: func [word [block!] meaning [block!]][
	word/meaning: meaning
]

global-context: ["spoon" unset!]

cutlery: reduce [
	make* "spoon" global-context
	make* "spoon" global-context
	make* "spoon" global-context
	make* "spoon" global-context
]

phrase: split "there is no spoon" space

forall cutlery [bind* cutlery/1 reduce ["spoon" take phrase]]

probe new-line/all cutlery on

print collect [forall cutlery [keep get* cutlery/1]]
hiiamboris
16:43Pictures were better, @9214 ;) We need a bindology comic book!
9214
16:47@hiiamboris I tried pictures, apparently to no effect. "Bindology" IIRC is a term coined by Ladislav Mecir, to make it look like something that it isn't — a scary, serious science that required PhD and a bushy beard to comprehend. The principle itself is dead simple, I'm honestly running out of words to explain it even more plainly.
hiiamboris
16:57I think the issue in teaching is sometimes not in the lack of proper words, or illustrations. To imagine how a mechanism works one has to be able to command a certain amount of one's attention, just enough to hold all the items pertaining to this mechanism. But that amount isn't always available. Sometimes never ☻

In this case the only way forward is to familiarize oneself with each item first, then try to picture them in groups. The more precise and detailed is the meaning of each word in the mental context the better those words will align.
17:03I can imagine how your words are being interpreted on the end point. Some *fuzzy something* is *somehow related* to *this scary something else* ;)
9214
17:18If verbal explanations are not helpful, one can just take the model I gave above and implement it in his language of choice, with lists, dictionaries and custom formatters. Or rather use it as a reference when learning Red directly.
GiuseppeChillemi
22:22@9214 I don't think you are running out of words. This time you have added the "thesaurus" element to your explanations, it has a great value here. Nice!
23:03I have thought about an illustration based on the concept of thesaurus, words and meaning. Hope I could work on it tomorrow. Currently my spine is on flame and it's 3 days I can't move from my bed.

MichaelCMcCann
01:09@henrikmk I have been using your wonderful “relations.r" script for several years in a program I wrote in REBOL, and I am trying to port it to RED. I get the following error message when attempting to add a new relation:

** Script Error: get does not allow none! for its word argument
*** Where: get
*** Stack: add-relation get-relation

Unfortunately, I don’t understand RED well enough yet to determine why it fails in the new programming language, or what other parts might fail as well. I’m hoping you might be able to point me in the right direction.

Any help or hints you could provide would be much appreciated. Thanks!
giesse
05:59That comes from the following difference between R2 and Red:
REBOL/Core 2.7.6.4.2 (14-Mar-2008)
>> get none
== none

--== Red 0.6.4 ==-- 
>> get none
*** Script Error: get does not allow none! for its word argument
*** Where: get
*** Stack:

R2 allows none because of the common idiom get in object 'word - if object has no word then in returns none.
In Red it could be replaced with something like:
>> select object [a: 1] 'a
== 1
>> select object [a: 1] 'b
== none

depending on the situation
pekr
06:27get in object word is one of the nicest sentences in Rebol. I like it fonetically :-)
MichaelCMcCann
07:40@giesse Thanks, that's a good starting point.
bubnenkoff
11:46 https://drive.google.com/file/d/1XfHvQiJn-NTlIB87YfJU5ZyhKM2KNulf/view

Is it's correct visualization?
11:47I did it's in draw.io
11:49so when we are writing: name: "Mike" we are add word and it's value to context table. right?
hiiamboris
12:02I see why you thought dialects support only one context. No it isn't true. Parse keywords are not bound to some 'parse context'. In fact parse ignores the binding of it's keywords, it just reads the word name (e.g. "some") and acts accordingly.
12:03> so when we are writing: name: "Mike" we are add word and it's value to context table. right?

That's mostly correct.
bubnenkoff
13:19And binding will be simple changing name from Mike to Jow?
hiiamboris
13:20No, binding doesn't change the name.
bubnenkoff
13:21So what it will do on my scheme?
hiiamboris
13:22Point it to another context-table
9214
13:36@bubnenkoff have you read any of the explanations I gave you?
meijeru
13:59Or mine?
GiuseppeChillemi
14:06@bubnenkoff beware Dmitry, waters are becoming hot here! It's better you read their explanations line by line or things will become terrible here! 😉
14:10@9214 Vladimir, I have read your post where you have written (pardon, I am on mobile) :
14:11>> @meijeru that's not entirely correct. object! (among other values), provides a context to bind to, but is not a context itself.
14:13I stopped to your words for a couple of days: do you mean an object is an composite structure which also has a context, or is it a derived one, or an independent with a context? How would you describe it?
14:42@giesse why, in your opinion, Red has been designed to give a error on 'get none'?
meijeru
15:22On this subject: I was checking the definition of get, and it is applicable to objects, where it gives the same result as values-of. This seems redundant. The only reason I can think of is the symmetry with set which can set the values of object fields to the contents of a block...
bubnenkoff
16:15I think I got it. We can have multiple context (thesaurus) and bind only change context (thesaurus) for a word. So we can for example re-bind word from one context to another.

like on global context x: 123 but in function context it can be x: [some block]. And we can bind word from one context to another from 123 to [some block]
hiiamboris
16:16Yes! My congratulations :clap: ;)
bubnenkoff
16:16Really sorry for my stupidness. But it very hard for me to make mental model. I hope that now I am right
16:16ooooh!
GiuseppeChillemi
17:02@bubnenkoff your are near
17:10You have understood exactly how contexts and words works. Have you also acquired the knowledge that a word in a block can appear multiple times having different bindings?
17:13I have this exercise for you: create a block with the same word repeated different times but bound to different contexts and when you probe reduce [aword aword aword] you should have a block with 3 different values.
17:14This is you *there is no spoon* exam first test.
17:20@9214 your alumn seem to have acquired the knowledge you have tried to transmit to him over the course of the last months. So this final rewording was the right one. My congratulations for having never abandoned him and always changing your approach.
giesse
20:19@GiuseppeChillemi I don't know if Red's behavior is intentional in this case. It may have been simply overlooked.
But, there are downsides to being more lenient wrt to "errors" - some bugs may go unnoticed.
20:21@meijeru aside from symmetry - keep in mind that values-of etc. were added much later to R2, so get behavior is more legacy than anything else.
dsunanda
22:51@giesse Re NONE -- Earlier versions of REBOL (when still capitalized) errored on GET NONE:
REBOL/Core 2.5.0.3.1
Copyright 1997-2001 REBOL Technologies
 
>> get none
** Script Error: get expected word argument of type: any-word
** Near: get none

I remember the change breaking a lot of code - mainly mine. Time to decide once and for all!
TimeSlip
23:29I just spent the last three hours trying to place little circles on the ends of arc points... Went back to rebol and then realized that cos != cosine in Red. cos = cosine/radians (Same behavior for sin/sine). :-)

TimeSlip
01:31BTW, how do you clear the buffer for the command line?
giesse
05:48@dsunanda right, it was added due to popular demand. :)
endo64
17:54@TimeSlip clear system/console/history ?
TimeSlip
17:55@endo64 Thank you. It's been a long time.
endo64
17:56Additionally it is under C:\Users\\AppData\Roaming\Red\Red-Console\console-cfg.red on Win10.
TimeSlip
17:59@endo64 And so it is. Thank you.

dsgeyser
05:08@GiuseppeChillemi Sorry to hear about your medical condition. Hope you get well soon.
greggirwin
05:14I missed that somehow. Feel better @GiuseppeChillemi.
TimeSlip
05:15@GiuseppeChillemi Praying you get well soon.
GiuseppeChillemi
07:39@dsgeyser @greggirwin @TimeSlip Thanks, everyday I am getting better. I have spent my "free time" reading Red and Rebol documentation and your chat messages.
endo64
10:17Get well soon @GiuseppeChillemi
GiuseppeChillemi
21:14@endo64 I hope!

GiuseppeChillemi
09:47I'm thinking about a way to assign to the main code of a script a word, to later access and modify it. I see the only possible way is to enclose it in a block and RUN this block via DO. From your point of view, is there any danger in this operation? (I think about subtle variations from the standard load/do phase of objects, functions an words)
hiiamboris
10:50Well, there's #include hell, as I call it ;) But if you're not including any other scripts or changing directories, and not relying on macros, then fear not ☻
GiuseppeChillemi
11:08Now you have triggered my curiosity. What could happen in your "if you are not doing" hypotesis?
hiiamboris
11:10Better not to know ;)
GiuseppeChillemi
11:14Oh my God.
12:30@hiiamboris and if we could provide a word at startup as option, and associate it to the main, invisible, block, do you think it would be equally dangerous?
hiiamboris
13:09Yeah
GiuseppeChillemi
13:23I really don't want to discover why. Under the hood you have seen things that would surely scare me!
hiiamboris
13:26:+1: :D

dsgeyser
10:27Why did Rebol/Services dev stopped, seeing that 'serverless' etc. are is latest buzzwords?
rebolek
10:52@dsgeyser because Rebol dev stopped. There are however alternatives.
dsgeyser
10:55@rebolek Thanks. Is the same idea still viable today? Will Red concurrency model be based on Erlang or Akka Actor model?
rebolek
11:01@dsgeyser I belive that Red/Services are still viable. Nothing against JSON, but Red is a much better messaging format. I can't comment about Red's messaging concurrency moel, as I don't know anything about it, sorry.
giesse
19:21@dsgeyser in 2007 'serverless' was not the latest buzzword. In any case, going from REBOL/Services to a 'serverless' system is hardly trivial.
GiuseppeChillemi
20:40@giesse But is Rebol/Service available somewhere ?

githubnyn
04:22any Red developer available for hire ?
giesse
05:50@GiuseppeChillemi no idea, though, it was never really finished, so I'm not really sure how useful it would be.
pekr
07:23I think that it was Robert or Gregg, who worked with Rebol/Services more extensively and I do remember some notes, that it was not without a problems. The docs still seem to be available at http://www.rebol.com/docs/services/index.html .... not sure the code was part of R3 open-sourcing?
GiuseppeChillemi
07:42We have sources too
07:42http://www.rebol.com/docs/services/source.html
Rebol2Red
11:34Why do we have modulo and mod but not absolute and abs?
Ofcourse i could do:
abs: :absolute

But every character to type counts :)
meijeru
13:32:+1: We also have sqrt and square-root, so why not? You will find sqrt is a routine with a Red/System call to the native square-root. So for efficiency one could make abs a routine that calls the action absolute....
bubnenkoff
14:34 > Two words can share the same spelling. Two words can share the same meaning. Meaning can be changed. It follows that you can have two words with the same spelling but different meanings.
>
text
> >> cutlery: [spoon spoon spoon spoon]
> == [spoon spoon spoon spoon]
> >> phrase: split "there is no spoon" space
> == ["there" "is" "no" "spoon"]
> >> forall cutlery [bind cutlery context [spoon: take phrase]]
> == [spoon]
> >> cutlery
> == [spoon spoon spoon spoon]
> >> print cutlery
> there is no spoon
>

> Here's how cutlery looks like under the hood:
>
text
> [
>     ["spoon" ["spoon" "there"]]
>     ["spoon" ["spoon" "is"]]
>     ["spoon" ["spoon" "no"]]
>     ["spoon" ["spoon" "spoon"]]
> ]
>

>
text
> >> forall cutlery [print context? cutlery/1]
> spoon: "there"
> spoon: "is"
> spoon: "no"
> spoon: "spoon"
>


thanks a lot for this example. But I have one question. What is real use case for this future? Or this future is more like side-effect from language design?
hiiamboris
15:56> Why do we have modulo and mod but not absolute and abs?
> Ofcourse i could do:
abs: :absolute


I always do abs: :absolute too ;) Should we PR it? @greggirwin

15:58@bubnenkoff It's just a shiny illustration of design of course. Unlikely you'll be building blocks like that ;)
endo64
18:22But mod and modulo are not the same:
>> a: -5 b: -6 reduce [mod a b modulo a b]
== [-11 1]
rebred
18:54@greggirwin We are in need of Red scripts to automate our workflow. Could you refer me to a developer who is available for freelance work ?
18:55on Upwork apparently no-one works with red/rebol
loziniak
19:54That's a niche to fill!
greggirwin
19:54@rebred @githubnyn we can offer consulting and contract services, yes.
19:55Message me directly with your needs, and we'll start a conversation.
19:56Redlake Technologies is the commercial arm of the Red ecosystem for this.

bubnenkoff
16:11
>> words: [a b c]
== [a b c]
>> fun: func [a b c][print bind words 'a]
*** Script Error: func is missing its c argument
*** Where: func
*** Stack: func


what's wrong?
meijeru
16:15In my console (W10):
>> words: [a b c]
== [a b c]
>> fun: func [a b c][print bind words 'a]
== func [a b c][print bind words 'a]

16:16Did you (a few lines before, perhaps) redefine func ???
9214
16:20@bubnenkoff you probably evaluated func: func [a b c][print bind words 'a] somewhere down the line.
bubnenkoff
18:31Vladimir, You are right.
"BIND will modify the block it is given"
So this code should modify original words:
words: [a b c]
    fun: func [a b c][print bind words 'a]
    fun 1 2 3
    fun "hi" "there" "fred"


words at first step should become 1 2 3
hiiamboris
18:35@bubnenkoff nice to see you exploring this fundamental concept :+1:
GiuseppeChillemi
20:00The matrix has been conquered
20:01He entered in our world from *parse* door and now he is at the core of Red concepts
hiiamboris
greggirwin
20:07I believe I asked Nenad about abs some time back, and it was decided not to include it. It's a nice shortcut, and probably used more than sqrt, which I am surprised to learn is there. My 2012 function counts, from various R2 scripts, show abs count at 500, and absolute | square-root at 10 each. For comparison, if is ~29K and func ~26K in that list.

My first thought is to remove sqrt. It's not used in the codebase today. Aliasing abs to absolute is easy enough, and people may reach for it. I don't care about the typing as much as the reading. But it's also not a showstopper.

I vote to remove sqrt, leave abs for later, and let @dockimbel weigh in.
20:13I also think we need to look at the abbreviated trig funcs, as the subtle difference is almost guaranteed to lead to hard-to-find bugs because people think of them as aliases.
hiiamboris
20:26Do you really find absolute more readable than abs?
20:26Besides, how this helps readability if everyone (50:1 = 98%) does use abs despite your efforts? Oh I see, it was included in R2, so the numbers will be lower than 98% ;)
9214
20:45> everyone

So far I've counted only 2.
hiiamboris
20:46See the above stats ;)
9214
20:47> stats

You surely meant "anecdotal evidence".
hiiamboris
20:49> My 2012 function counts, from various R2 scripts, show abs count at **500**, and absolute | square-root at **10** each. For comparison, if is ~29K and func ~26K in that list.

Obviously, we can't extrapolate that to Red but also obviously this hints us at users preferences (as well as agreement of 3 people here - me, @meijeru and @Rebol2Red)
20:51Okay, let me stat the R2 scripts library...
21:02Whole R2 library: absolute: 36 abs: 133 (21 to 78%) (from what I can tell 5 absolute hits are if absolute where absolute is a refinement flag)
GiuseppeChillemi
21:16@hiiamboris what are you using to extrapolate stats? I need something to extract all functions names in a Rebol script, objects, their elements and words and words assigned to blocks
21:19Also it would be good to have something to navigate an object tree
hiiamboris
21:19Sorry, it's a few-liner that won't help you ;) I'm only extracting words (from text, unloaded), ignoring comments.
GiuseppeChillemi
21:21@hiiamboris The simplest needing is words associated to functions or object in a text file. But maybe you are just statistically coutig only words..
21:22I have to build my own solution.
hiiamboris
21:24https://gist.github.com/meijeru/2665add5f9e72378c7ffdb3fda3adddf#file-word-finder-red-L153 may help you start, but needs to be ported to R2
9214
21:41And what's the ratio per script, and how many unique authors are behind these scripts?
greggirwin
21:54> Do you really find absolute more readable than abs?

Note that I didn't say "readability", though I can see how that meaning could have been taken. But we can and should consider that.

This isn't an easy call, as there are conflicting aspects. Abs seems comfortable, even spreadsheets use it. But it's not a complete word, which Redbol langs favor over abbreviations. It's better than absolute-value, if anybody wants to go there. ;^) On readability, though, abs is nicer in formulae, but is it *always* better? Here are some examples of its use in Red right now:
a: absolute a
r: mod a absolute b
if hours [hours: absolute hours]
mins: absolute mins
n: absolute end-idx - start-idx


If we choose abs, then we should probably remove absolute. Means about a half dozen uses in the code base to change. Then do we also use abbreviated names for all trig funcs? Is consistency important there, and as a future precedent?

My stated preference was not based on abs v absolute, but how many abs cases there are rel to other funcs. I had another thought, but it would be a tan.
hiiamboris
21:58200 +/- 10 authors, 1223 scripts @9214 (that makes it 0.13 per script avg)
22:02> If we choose abs, then we should probably remove absolute.

Did it hurt R2 to have both? ;)
greggirwin
22:03How can we know? ;^)
22:03It's a constant game of "Do we need this?"
9214
22:15I asked how many people actually used abs in the scripts you've found. Are you saying it's 210?
hiiamboris
22:25About 30 people in ~50 scripts.

laue727
03:21 is there a way for Red to write to a SQlite DB ?
toomasv
06:21@laue727 You can try [this](https://github.com/red/code/tree/master/Library/SQLite)
loziniak
07:49having tan and tangent as separate implemetations is hoffific, thanks @greggirwin for giving attention!
bubnenkoff
08:08> @bubnenkoff nice to see you exploring this fundamental concept :+1:

So what I am doing wrong this time?
08:21> is there a way for Red to write to a SQlite DB ?

If you will get any db work give me know please.
toomasv
08:22@bubnenkoff Function's context is accessible at functions execution, so values of a, b, c are printed from inside function. After exiting function, they are not accessible anymore. To access a, b, c after function has finished you need to assign their values in glogal context, e.g.
>> fun: func [d e f][print set words reduce [d e f]]
== func [d e f][print set words reduce [d e f]]
>> fun 1 2 3
1 2 3
>> a
== 1
>> fun "hi" "there" "fred"
hi there fred
>> print words
hi there fred

But simpler is just
set words [1 2 3]
08:34@laue727 @bubnenkoff Some time ago I played with it:
[![DB-demo](https://toomasv.red/images/DB/demo1.gif)](https://toomasv.red/images/DB/demo1.gif)
bubnenkoff
08:40@toomasv it's based on SQLite? Could you give an example of how to setup driver?
toomasv
08:46Yes, on SQLite3. Did you look at [link](https://github.com/red/code/tree/master/Library/SQLite) I posted above? Test files there show how to set it up.
pekr
09:26As can be seen, we really miss a data grid component :-( I am using an area to display data too :-)
GiuseppeChillemi
09:49@bubnenkoff
> > @bubnenkoff nice to see you exploring this fundamental concept :+1:
>
> So what I am doing wrong this time?

Nothing. It seems you are undestanding the concept quite well !
meijeru
10:04@pekr :+1: :+1:
bubnenkoff
18:53I am reading bindology and there is example there:
a-word: second first context [rebol: 1]


It's do not work in Red:
>> a-word: second first context [rebol: 1] 
*** Script Error: first does not allow object! for its s argument
*** Where: first
*** Stack: second first
hiiamboris
18:56Yes, by design ;)
18:57That first reflector was far too esoteric to keep
toomasv
19:02@bubnenkoff In Red you may do something like this instead:
>> a-word: first words-of context [red: 1]
== red
bubnenkoff
19:08In what moment value become context?
19:12For example I create function. It have own context. Than I can bind it's context to another word. function body is context. But who can produce context except functions?
19:13With big help from Vladimir I mostly understand how bind is work. Still have some question, but at last I understand main idea correctly.
hiiamboris
19:19> who can produce context except functions

objects
9214
19:19> Than I can bind it's context to another word.

You bind words to contexts, not the other way around.

> But who can produce context except functions?

Both me and @meijeru [told you](https://gitter.im/red/help?at=5e7de8c87f06b57bd8227487) that already, apparently to no avail.
>> next fifth spec-of :bind
== [any-object! function!]

bubnenkoff
09:03
>> bind 'pi context [pi: "pie"]
== pi

In this example 'pi is bind with context of object. Right?

>> bind 'x context [x: 123]
== x
>> context? x
*** Script Error: x has no value
*** Where: context?
*** Stack:

09:25
>> get bind 'x context [x: 412]
== 412

>> get 'x ; why this do not work?!
*** Script Error: x has no value
*** Where: get
*** Stack:
hiiamboris
10:00bind does not (and *can not*) modify the word given. It returns a new word.
10:01Same way as you can't expect 1 + 2 to modify 1 to become 3
9214
10:45@bubnenkoff are you sure that x that you bind and x that you probe are the _same_?
10:47> bind does not (and can not) modify the word given

It's in the very nature of bind to modify a word given. The problem is that people confuse one particular instance of the word with other words that look the same.
10:52@bubnenkoff what you did is roughly this:
>> stack: []
== []
>> append stack bind 'x context [x: 1]
== [x]
>> context? stack/1
== make object! [
    x: 1
]
>> get stack/1
== 1

>> append stack 'x
== [x x]
>> system/words =? context? stack/2
== true
>> get stack/2
*** Script Error: x has no value
*** Where: get
*** Stack:


Words can have same spelling but different meaning. Each word is a value on its own, and if you bind one it won't affect binding of the others (how could it?).
toomasv
11:20@bubnenkoff Notice also that
>> get bind 'pi context [pi: "pie"]
== "pie"
>> pi
== 3.141592653589793

>> insert x: [] bind 'x context [x: 123]
== []
>> x
== [x]
>> reduce x
== [123]
greggirwin
18:49The doc string for bind says

> Bind words to a context; returns rebound words.

But we don't say, explicitly, for the word param that the arg is *not* rebound. Should we?
hiiamboris
18:55No that should come from general Red knowledge ;)
9214
19:15> But we don't say, explicitly, for the word param that the arg is not rebound. Should we?

How is it not rebound if it is?
19:36Actually, _sometimes_ it is and sometimes it's not (when there's no such word in a context).
greggirwin
19:48That's something to note then, as it's an important subtlety.
rebred
22:09@toomasv when trying to compile the Sqlite binding, it seems the file %definitions.reds is missing
Compiling to native code...
*** Loading Error: file access error: %definitions.reds

greggirwin
01:43@rebred did you clone the whole repo? It's a relative path reference to another dir in it, not in the SQLite sub dir.
rebred
02:21@greggirwin thank you I found it
greggirwin
03:26@9214, what I meant about the arg not being re-bound is what we see in the above pi examples. That is, bind's result is a "use it or lose it" proposition, isn't it?
9214
10:48@greggirwin it was rebound, "use it or lose it" is a secondary matter. Same with 1 + 2, if it doesn't modify either argument to 3 and if you don't use the returned sum, then would you say that it "doesn't add"?
GiuseppeChillemi
11:31Why is so difficult for Red to have the context of a function available outside of it. Rebol seems to let you access word values defined in function context even of the function is not online in the stack.
hiiamboris
11:33Optimization probably
loziniak
12:28Hi! Does #include work differently in **encap** mode? I get *** Compilation Error: include file not found error.
hiiamboris
12:38https://github.com/red/red/issues/3464 or https://github.com/red/red/issues/2484 ?
loziniak
12:45Gosh, thanks. I should've searched for bugs first.
12:54it's more #2484 , because id does not even compile.
hiiamboris
12:55If it doesn't fit any of our collection of #include-related bugs, please report it or comment under the most relevant issue with a minimal example ☻
loziniak
13:53Here you are: #4390 !
13:53And thanks :-)
hiiamboris
13:56:+1:
13:57Crazy bug ;)
rebred
15:59@greggirwin trying to set up the SQLite drivers

when I try to do

prompt$ red.dms SQLite3-test.red
*** Internal Error: contains Red/System code which requires compilation
*** Where: do
*** Stack: do-file


which are the files that need to be compiled ?
9214
16:00@rebred the one that contains Red/System code, it's literally in the error message.
rebred
16:03@9214 thank you
bubnenkoff
18:16@rebred if you get it work could you share compiled version of project with all needed dlls
18:22I need step by step manual to get it work. I do not have enough of experience with red to get SQLite binding work
18:28
> red -c SQLite\SQLite3-test.red

-=== Red Compiler 0.6.4 ===-

Compiling C:\red\SQLite\SQLite3-test.red ...
...using libRedRT built on 8-Apr-2020/18:24:41
...compilation time : 125 ms

Target: MSDOS

Compiling to native code...
*** Compilation Error: undefined symbol: zerofill
*** in file: %/C/red/SQLite/SQLite3.red
*** at line: 9567
*** near: [
    zerofill dbs-head dbs-tail
    close-dbs: func [
        /local
        p [pointer! [integer!]]
    ] [
        p: dbs-head
        while [p < dbs-tail] [
            if p/value <> 0 [
                print-line ["closing db: " as pointer! [integer!] p/value]
                sqlite3_close as pointer! [integer!] p/value
                p/value: 0
            ]
            p: p + 1
        ]
    ]
    get-db-ptr:
]

Dima@MACHINE-FCGCTD2 C:\red
greggirwin
18:35> it was rebound, "use it or lose it" is a secondary matter. Same with 1 + 2, if it doesn't modify either argument to 3 and if you don't use the returned sum, then would you say that it "doesn't add"?

@9214, I'm looking at it in the context of words. That is, as a relative of set and in.
18:36Set being the key comparison.
9214
19:15@bubnenkoff you can start by compiling in release mode (-r flag).
rebred
21:00@bubnenkoff
I downloaded the @toomasv files from:
https://github.com/red/code/tree/master/Library/SQLite


I also downloaded the file
definitions.reds

that is in the OS folder

I put all the files in the same folder:

definitions.reds
SQLite3-test-basic.reds
SQLite3-test.red
SQLite3-test.reds
SQLite3.red
SQLite3.reds


then I updated
SQLite3.reds

with:

#include %definitions.reds ;common aliases and defines

so it can read definitions.reds from the same folder

then I compiled SQLite3-test.red with:
red.dms -r SQLite3-test.red


it created a compiled file:
SQLite3-test


then from the terminal I ran:
./SQLite3-test

and it created a test.db, test2.db and showed columns and stuff
21:08how do I read / execute a compiled file and pass response values from it back to Red?
hiiamboris
21:10with call
rebred
21:16@hiiamboris thank you
endo64
22:51About the context discussion, I had the same confusion years ago, "Words carry their binding" ™
Here is how I thought:

>> x: 1
>> o: context [x: 2]
>> b: [x]
>> reduce b
== [1]
>> bind b o
>> reduce b
== [2]
>> get b/1
== 2
>> x
== 1


x is the same x which bound to o, so I get 2 each time.

On the REPL, when I type x, it is not the same x with the above one in the b block.
It is the one that lives in the global context.

>> bind 'x o
>> x
== 1
>> get bind 'x o
== 2


I get that.
But then I thought if I put these lines in a file and execute it, the result should be as in the first example, because I thought, a script file, when loaded, is a block and words inside a block keep their bindings, so both xs are same, hence they should bound to o.
But they were not:

Rebol []
...
bind 'x o
print x
; expected 2, but it was 1.


greggirwin
23:17Good note @endo64. This is all spelled out clearly [here](https://github.com/red/red/wiki/%5BDOC%5D-Guru-Meditations#bind-in-contexts-and-words-versus-symbols), which @9214 may have written. His points and comparisons about operating on the stack are accurate, but non-obvious, and blocks add to the subtleties.

toomasv
04:14@rebred :point_up: [April 9, 2020 12:00 AM](https://gitter.im/red/help?at=5e8e3b7ffea5216d6968132f) Please note that all credit for SQLite3 binding goes to @Oldes. I only gave a link to his files.
bubnenkoff
10:49What is wrong with follow code:
>> view[t: text-list data["aa" "bb" "cc"] on-select [print [pick t/data t/selected] ]]
none
aa
bb

selected return -1 index so all work incorrect
hiiamboris
10:54https://github.com/red/red/issues/3809
10:54use on-change
bubnenkoff
11:14is it correct approach to use one view inside another?
view[t: text-list data["aa" "bb" "cc"] on-change [ view [ b: button do [ b/text: pick t/data t/selected ]  ]] ]

?
hiiamboris
11:15Sure. Although in some cases you might wanna use view/flags [] 'modal (to disable the lower windows until one closes the top one) but that's glitchy right now, so not advised.
bubnenkoff
11:43@rebred big thanks, for detail explanation. Is it possible to run app without compilation?
12:24Or is it possible to increase compilation speed? I do not need any optimization when developing
12:25> @laue727 @bubnenkoff Some time ago I played with it:
> [![DB-demo](https://toomasv.red/images/DB/demo1.gif)](https://toomasv.red/images/DB/demo1.gif)

Could you please share source code of this tool? I want to learn how it's code organized
rebolek
12:26@bubnenkoff of course you can run everything interpreted. Just run Red executable or self-compiled console and do %your-script.red
12:27Or have you been compiling everything all the time?
bubnenkoff
12:34@rebolek I am playing with SQLite driver. with do I am getting message:
>> do %app.red
*** Internal Error: contains Red/System code which requires compilation

Is there any way to compile it one time and interpreted other part?
rebolek
12:36@bubnenkoff Ah sorry, I see. Anyway, you can compile SQL driver into yur own custom console and run other stuff from there.
12:37> Is there any way to compile it one time and interpreted other part?

Yes, the easiest way is to use current Red console and add your custom stuff to it.
12:39For start, add print "hello world!" on line 31 here https://github.com/red/red/blob/master/environment/console/CLI/console.red and compile it. Then replace hello world with anything you want.
bubnenkoff
12:55So I would have all red futures from this console? What is the other ways? Just interesting...
13:35@rebolek I tried your way in red source code tree. It's work. But when I tried to move code to my project folder I faced with include path problem. I specified paths manually, but it's seems that some of import use relative paths
13:35[![изображение.png](https://files.gitter.im/red/help/DIFC/thumb/izobrazhenie.png)](https://files.gitter.im/red/help/DIFC/izobrazhenie.png)
13:36is there any standard way to fix it? It's seems that it's popular issue
rebolek
13:48@bubnenkoff setting up proper paths is currently up to you, there's no standard way yet.
bubnenkoff
13:56I tried to move all SQL libs to console, than compile it to have access to SQLite functions. Than I copy-paste code that already worked and than I got error:
13:56[![изображение.png](https://files.gitter.im/red/help/Cfg4/thumb/izobrazhenie.png)](https://files.gitter.im/red/help/Cfg4/izobrazhenie.png)
13:58it's seems that something wrong with open:
>>  db1: open %/D/code/fas_2020/parser_gui/test.db
*** Script Error: open does not allow file! for its port argument
*** Where: open
*** Stack:
13:59but this code worked as standalone app
rebolek
13:59compiling in debug mode could help you to find the problem
bubnenkoff
14:01thanks! But could it be something wrong with open? Maybe I should specify path to db in another way?
toomasv
14:43@bubnenkoff When you have compiled it once with update mode (i.e. with -u -c), you can henceforward compile it in development mode (i.e. with -c only) which is much faster.
bubnenkoff
15:42I want to handle function that extract data to word. The problem that function execute immediately:
result: [] ;preallocating block for results

test: SQLite/do [
    db1: open %test.db
    result: exec "SELECT name FROM Cars ORDER BY name"
]
print result ; should not have any data before I will do: `do test`

toomasv
16:21You are calling SQLite/do already. Of course result is filled. To call it on demand, put it into function and call when needed.
meijeru
16:32Its because test: DOES evaluate the , and that means calling SQLite/do.
bubnenkoff
16:46is it normal code or adding data could by done more elegant?
SQLite/do [
    db1: open %test.db
]

result: [] ;preallocating block for results

view[
    button "load" [
        SQLite/do [
            result: exec "SELECT name FROM Cars ORDER BY name"
        ]
        append t/data result
    ]
    t: text-list data []
    ]

SQLite/free ;closes all opened DBs and frees SQLite resources
toomasv
17:07@bubnenkoff Does it work?
bubnenkoff
toomasv
17:12Great! Congratulations!
17:13If you click "load" several times what happens to list in t?
bubnenkoff
18:03it grow. Same data appends again and again
toomasv
18:30So, why does it grow? And what to do to avoid it?
bubnenkoff
18:50I do not red-way, but maybe to:
1. disable button after first append 2. to compare current new and existent data and add only new items
toomasv
18:51It's easier not to append but to set it.
9214
18:51copy might also work. Or setting t/data directly.
bubnenkoff
18:54thanks!
I am missing docs or there is no build-in function for removing elements from block by it's index?
x: [1 2 3 4 5]
I want to remove second element to get
x: [1 3 4 5]
toomasv
19:01remove at x 2

Rebol2Red
07:17@bubnenkoff
print head remove at x 2
07:43How about this?

x: [1 2 3 "" 4 "" "" 5]
I want to remove "" to get
x: [1 2 3 4 5]
I could do it this way:
x: copy [1 2 3 "" 4  ""  ""  5]
temp: copy [] repeat i (length? x) [if x/(i) <> "" [append temp x/(i)]] x: temp
probe x

But is there a direct way to manipulate x?
pekr
07:56
>> x: [1 2 3 "" 4 "" "" 5]
== [1 2 3 "" 4 "" "" 5]
>> remove-each val x [val == ""]
>> x
== [1 2 3 4 5]

07:58remove-eachis a native and as I remember from R2, it was also nicely fast. I really like the function and wished to have a keep-eachcounterpart, thought it might be easy to get as a mezzanine wrapper ....
Rebol2Red
08:01Great, Thanks!
ingvast
08:14In rebol you can do replace with am empty block. I also think there is an replace/all.
Rebol2Red
08:29Yep, this seems to work too.
x: [1 2 3 "" 4 "" "" 5]
probe replace/all x "" []

Now i'll have to find out which one is faster. I think foreach but i could be wrong.

After testing i can answer my own question: remove-each is significantly faster!
08:34Wanted (dead or alive :) fstk-logo (or any other picture for testing purposes which is included inside Red).
view [image fstk-logo]

*** Script Error: VID - invalid syntax at: [fstk-logo]

If i'm not mistaken this used to work in the past.
bubnenkoff
08:41> remove at x 2

I tried this. It's stay not what I want:
>> x: [1 2 3 4 5]
== [1 2 3 4 5]
>> 
>> remove at x 2
== [3 4 5]

But I need:
[1 3 4 5]
Rebol2Red
08:43@bubnenkoff try:
head remove at x 2
bubnenkoff
08:48Yes that's work, but how?
Rebol2Red
08:49Don't ask me :)
ps: i really do'nt know but it makes sense to place the index at the head. Maybe the index is moved somehow.
meijeru
08:52@bubnenkoff As you have been told a few times already: read the documentation.
>> help remove
USAGE:
     REMOVE series
DESCRIPTION: 
     Returns the series at the same index after removing a value. 
     REMOVE is an action! value.

The result of remove is the series at the point where you did the remove. If you want to go back to the beginning, use head.
pekr
10:20I am trying to write a small conversion utility - Mikrotik wireless Winbox UI does not support international chars for the SSID wireless network name. So I want to encode it for its console, using simple script. How do I cycle thru the bytes of binary?

>> ssid: "FOTOATELIÉR Jana Marková"
== "FOTOATELIÉR Jana Marková"
>> bin-ssid: to-binary ssid
== #{464F544F4154454C49C38952204A616E61204D61726B6F76C3A1}
>> foreach byte bin-ssid [prin byte]
7079847965846976731951378232749711097327797114107111118195161

I simply need the following output: "\46\4F\54\ ...."
hiiamboris
10:23like prin to-hex/size byte 2 ?
GalenIvanov
10:26@pekr
pekr
10:27Now I see, why the binary is longer by two "bytes" than a string :-)

>> foreach char ssid [prin to-binary char]
#{46}#{4F}#{54}#{4F}#{41}#{54}#{45}#{4C}#{49}#{C389}#{52}#{20}#{4A}#{61}#{6E}#{61}#{20}#{4D}#{61}#{72}#{6B}#{6F}#{76}#{C3A1}
GalenIvanov
10:27
>>repeat n length? bin-ssid[prin rejoin[to-hex/size bin-ssid/:n 2"\"]]
46\4F\54\4F\41\54\45\4C\49\C3\89\52\20\4A\61\6E\61\20\4D\61\72\6B\6F\76\C3\A1\

toomasv
10:29
collect/into [foreach byte bin-ssid [keep to-hex/size byte 2 keep #"\"]] out: clear ""
== {46\4F\54\4F\41\54\45\4C\49\C3\89\52\20\4A\61\6E\61\20\4D\61\72\6B\6F\76\C3\A1\}
pekr
10:30Nice one liners ... not liking the to-hex/size aspect of the code much though, dunno why :-) Will try to strip the binary back to string and using my belowed foreach
toomasv
10:33@bubnenkoff You need head if you want to use result of remove as argument to another func or set something to it. If not, you can just use x further without head. (That is if you haven't done x: remove at x 2)
pekr
10:36Trying a bit different aproach :-)

>> mold bin-ssid
== {#{464F544F4154454C49C38952204A616E61204D61726B6F76C3A1}}
>> str: "464F544F4154454C49C38952204A616E61204D61726B6F76C3A1"
== {464F544F4154454C49C38952204A616E61204D61726B6F76C3A1}
>> foreach [high-byte low-byte] str [prin rejoin ["\" high-byte low-byte]]
\46\4F\54\4F\41\54\45\4C\49\C3\89\52\20\4A\61\6E\61\20\4D\61\72\6B\6F\76\C3\A1
10:36now how do I effectively go from molded binary to just a string, without ugly remove remove and then removing from the tail again :-)
10:37hmm, maybe some copy/part at ....
hiiamboris
10:38parse s: enbase/base ssid 16 [any [insert "\" 2 skip]] s
pekr
10:39Cool, I have struggled with enbase/base conversion back then ... now I will go get a popcorn and have few bits thinking about your code :-)
10:44Did it ugly, but yet another way :-)

>> str: head remove back tail remove remove mold bin-ssid
== {464F544F4154454C49C38952204A616E61204D61726B6F76C3A1}
>> foreach [high-byte low-byte] str [prin rejoin ["\" high-byte low-byte]]
\46\4F\54\4F\41\54\45\4C\49\C3\89\52\20\4A\61\6E\61\20\4D\61\72\6B\6F\76\C3\A1
10:46The "solution" stems from my past trying to do some binary conversion back at R2 times, struggling with debasing, enbasing and trying to get string converted on a byte by byte basis .... Have to admit your solution are more elegant ....
10:48Hehe :-)


>> foreach [high-byte low-byte] enbase/base ssid 16 [prin rejoin ["\" high-byte low-byte]]
\46\4F\54\4F\41\54\45\4C\49\C3\89\52\20\4A\61\6E\61\20\4D\61\72\6B\6F\76\C3\A1
bubnenkoff
10:51Why next code do not display fail when parse rule is false?
It's display only true. But I do not see any reason why. true\false are logical type:
view [
    f: field b: button "Parse" [
        x: parse f/text ["aabb"]
        t/data: to string! x
        print x
    ]
    t: text
]

I fixed issue with to string! but I do not understand why it's needed
9214
10:51> foreach [high-byte low-byte]

That would be nibbles, not bytes.
pekr
10:51I thought so :-)
10:55@bubnenkoff here it displays and prints false too.
bubnenkoff
10:56if remove to string!
view [
    f: field b: button "Parse" [
        x: parse f/text ["aabb"]
        t/data:  x
    ]
    t: text
]

it will not display false in interface, but only true
9214
10:58@bubnenkoff because View interpretes false as a signal to clear the text. Probably an oversight, as it should happen only with none.
10:58See [here](https://github.com/red/red/blob/master/modules/view/view.red#L446).
10:59A simpler way to reproduce:
view [t: text button [t/data: random true]]
11:00That's a one-line fix, maybe you can even submit a PR for it.
bubnenkoff
11:01oh! thanks!
11:30Parse rules should always be quoted and placed in block like: parse "aa" ["aa"].
I need to /text return quoted data. How I can do it?
I tried:
view [
    f-data: field 
    f-rule: field 
    b: button "Parse" [
        result: parse f-data/text [{"}f-rule/text{"}] ; this line
        print  f-data/text
        print  f-rule/text
        t/data: to-string result
    ]
    t: text 
]

but it's do not work.
9214
11:38What do you mean by quoted data? A string?
bubnenkoff
11:38Yes, wrap any input data to quote
9214
11:39f-rule/text is already a string, why do you need extra quotes around it?
11:39And bear in mind that putting literal string and path that refers to it inside Parse rule are two different things.
bubnenkoff
11:40I am getting error: invalid rule or usage of rule: f-rule/text
9214
11:41That's what I just said: putting literal string and path that refers to it inside Parse rule are two different things. IIRC Parse doesn't even recognize paths as valid rules.
bubnenkoff
11:42can it be converted to string that parse is accept?
9214
11:43Yes, but that's for you to figure out, since I have no idea what goal you have in mind with all that.
11:44
text
view [data: field rule: field button [face/text: form parse data/text rule/data]]
11:44Or maybe you want to parse data/data instead, dunno.
bubnenkoff
11:45I am trying to make two field one for rule other for text for checking. thanks, I will try
12:59
result: parse f-data/text reduce [  f-rule/text ]

that what it is!
9214
13:09@bubnenkoff but how is it different from f-data/text = f-rule/text?

rebred
11:58I compiled the following script and I now have a
test1
file:

Red[]
total: 1 + 2
print ["total: " total]


from Red I am calling it like this:
a: ""
call/shell/output {./test1} a
print a


how do I get
total
as a variable back to Red (or get
total
into a )?
hiiamboris
12:00do a? ;)
rebred
12:20@hiiamboris
I think I fugured it out!
compiled script named
test1
:

Red[]
total: 1 + 2
print total


from Red I am calling it like this:
total: ""
call/console/output {./test1} total
print ["total: " total]
fergus4
14:14I notice that my view apps will crash and close the window and the console too so I see no error message for a clue to what went wrong. Rebol console would always appear with an error message. Is this a bug or feature?
hiiamboris
14:27Run it with red --cli from cmd.exe to see the output
bubnenkoff
14:48How to create 5 buttons in loop? I am trying something:
view[
     do [repeat y 5 [ button "hi" ] ]
    ]


But it have wrong syntax
hiiamboris
14:50Use collect and keep to build the block you give to view
fergus4
14:59getting this error:
*** Runtime Error 1: access violation
Is there a resource to look up what that might mean?
hiiamboris
15:00No ;)
15:01Best thing you could do is isolate the issue. Cut your code until you get to the minimal snippet that still crashes, then report it to our [issue tracker](https://github.com/red/red/issues/new?template=bug_report.md) so we can fix it
bubnenkoff
15:11@hiiamboris how to use repeat with collect?
x: repeat y 5 [collect [keep 'a]]

I want to get a five times
hiiamboris
15:14Good start ;) Just think on it a bit more. You want your collect to include a five times. How would you do that?
bubnenkoff
15:14
collect [repeat y 5 [keep 'button] ]

I did it!
hiiamboris
15:15Nice ☻
9214
15:51@fergus4 it means [segmentation fault](https://en.wikipedia.org/wiki/Segmentation_fault). Compile with -d flag to see the detailed stack trace, and make sure that you use the latest automated build rather than an outdated one.
15:54@bubnenkoff I believe what you actually want is loop, not repeat.
bubnenkoff
16:16Vladimir, yes you are right!

How to change text on first button?
v: []
    append v collect [ loop 5 [ keep [ b: button "hi" ] ] ]
   ; v/1/b/text: "aaa" ; do not work
    view v
hiiamboris
16:18use probe v to see what it is
bubnenkoff
16:22that's work!
v: []
    append v collect [ loop 5 [ keep [ b: button "hi" ] ] ]
    probe v/3: "aaa"
    view v


But is there any way better than calculate index every time? not calculate but multiple every element number to 3
rebred
17:49
a: "test1"
b: "test2"
form reduce [a {"} b {"}]

gives me:
== {test1 " test2 "}


is there a way for reduce not to add the spaces?

like:

{test1 "test2"}

9214
18:04@rebred well, think about it. What reduces and joins the result together?
rebred
18:10@9214
form rejoin [a { "} b {"}]
18:11@9214 thank you!!
20:28I compiled the following script and I now have an executable test1 file:
Red[]
total: 1 + 2
print total

from Red I am calling it like this:
a: ""
call/shell/output {./test1} a
print a


a
should be
3
but it's not printing anything
hiiamboris
20:34Windows does not support forward slashes
rebred
20:35@hiiamboris I am on a mac
hiiamboris
20:35I see
20:36Well, it works for me as {.\test1} on Windows, so.. you sure you have the rights to execute test1?
20:37chmod 777?
rebred
20:37it prints 3 correctly if I do this:
call/console {./test1}

hiiamboris
20:38Smells a call bug to me
20:38And if you do not specify /shell?
rebred
20:43@hiiamboris
a: ""
call/console/output {./test1} a
print ["a: " a]

it's working now - thank you
hiiamboris
20:44What about just call/output?
rebred
20:45@hiiamboris it works
hiiamboris
20:47Can you make an issue on the tracker that it doesn't work for you with /shell? Maybe the shell does not properly inherit the current working directory, or it's broken totally on Mac.
rebred
20:48 @hiiamboris it is working now on shell too. strange I have been trying for an hour everything but it's working ok now
hiiamboris
20:51Curious indeed ;)
rebred
20:53
a: ""
b: "./test1"
d: form rejoin ["{" b "}"]
append d { a}
print ["d: " d]
; it gives me d:  {./test1} a



call/output d
and
call/output reduce d
gives me an error

*** Script Error: call/output is missing its out argument

which is the correct syntax ?
hiiamboris
21:00/output needs a string obviously
21:02I can tell you're fighting the language ;)
21:02What is it you want to achieve?
rebred
21:03@hiiamboris
after trying all kind of scripts now even these ones don't work:
z: copy ""
call/output {./test1} z
print ["z: " z]

call/console {./test1}

event after I restart Red
hiiamboris
21:04does ls say you have test1 in that location?
rebred
21:05@hiiamboris you are right. It kicked me off that directory
21:06@hiiamboris now it's working again

rebred
00:02test.txt is the file below:
["1" "test1" "test2" ]
["2" "jenn1" "jenn2" ]
["3" "rob1" "rob2" ]
["3" "cast1" "cast2" ]

file1: read/lines %test.txt

file1/2

is:
["2" "jenn1" "jenn2" ]

-----
if I do:
a: {
["1" "test1" "test2" ]
["2" "jenn1" "jenn2" ]
["3" "rob1" "rob2" ]
["3" "cast1" "cast2" ]
}
b: read/lines a


I get an error
*** Script Error: read does not allow string! for its source argument

greggirwin
00:02@rebred, to add to @hiiamboris' note that you're fighting the language, and for @bubnenkoff too, as you're newer to Red, listen carefully to how @9214 and @hiiamboris guide you to try things. e.g. d: form rejoin ["{" b "}"] can be broken down into pieces, to see what form and rejoin each do, as well as using help. Also, where other langs force you to use strings or numbers everywhere, remember to leverage Red's datatypes as much as possible. For example, look at the help for call, and you'll see it can also take a file! type.
00:03@rebred use help read. What does that tell you?
00:03And how does that relate to the error message you got?
rebred
00:08@greggirwin
read/lines
converts a file into lines. is there a command that converts a string into lines ?
greggirwin
00:09Now think about other functions that load or convert data to Red values. And keep in mind that Red doesn't care about newlines, so if you need to treat things as strings that way, you may need to use another approach to split the data, but that may lead to other issues.
00:11And if you want to poke around, you can use strings with help to find where something is mentioned anywhere in the spec for functions. e.g. if you do ? "lines" what funcs show up?
00:12Now that you and @bubnenkoff aren't complete newbies anymore, you'll find that we may offer less direct answers, and more hints about how you can learn on your own.
00:13Because that's more fun for everyone. :^)
00:15You'll also need to understand the difference between a new-line marker in a Red series, compared to a newline character in strings. Once you do, it opens a lot of doors in how you choose to process data, making it easy to work with Red values, then format them easily for writing to files and such.
rebred
00:38@greggirwin
On a text file with a 1 million lines, it takes over 4 minutes for ```load``` to read it and convert it (sometimes it even crashes), when with ```read/lines``` only a few seconds

right now I am using read/lines to search and when I find the line I need, I then convert it with ```Load```
read/lines
is very fast and works great with files. I was looking for the equivalent command that would convert a string to a block of strings

here is what I found when searching for
line

linen tuple! 250.240.230
new-line native! Sets or clears the new-line marker...
new-line? native! Returns the state of the new-line ...
newline char! #"^/"

`
greggirwin
00:41Note that I used help "lines" where the arg is a string. Use help help to learn more. And the new fast lexer will make a big difference for you, but if you're dealing with that much data, you may want to process on demand. Look at my message above, and the highlighted words, like split. You can also use parse as you learn more.
rebred
00:46@greggirwin
read
only reads from a file, URL, or other port
greggirwin
00:51Correct.
rebred
01:04@greggirwin
I used
b: split a #"^/"

to separate the string into blocks
thank you!!
greggirwin
01:07You're welcome.
bubnenkoff
17:31How to make faced reactive? I want to change it's color depend on value.
view [f: field on-change [if f/text = 123 [ f/color: red]  ] ]
9214
17:41@bubnenkoff take a look at [examples](https://doc.red-lang.org/en/reactivity.html) and proceed from there.
toomasv
17:52@bubnenkoff "123"
rebred
22:22
suffix?
gets the suffix of the file. is there a command that gets the name (string before suffix)
greggirwin
22:24Not standard.
22:26It's a fun exercise to look at the different ways to do it.
22:27Playing with path and file names is a great area for experimenting with string processing.
rebred
22:27@greggirwin I am thinking about getting the suffix first and then subtracting it from the name of the file
greggirwin
22:28Try it. Set up a list of file values to work with, including those that have no suffix, and duplicate or intermixed "suffixes".
22:29Why this is a good area for exercise is that there are existing rules to follow, which seem easy at a glance, but may trip up naive approaches.

rebred
01:43@greggirwin
a: "test.pdf"
either find/last a "." [
	in: index? find/last a "."
	name: copy/part a in - 1
	][ name: copy a ]
print name

greggirwin
01:57Be careful to redefine in. Perhaps use idx as the var name.
01:59Use help find, and note the /tailrefinement. Just for future reference, not needed here.
02:00Help copy, note that /part can take a series, so you can copy from one offset to another, without having to convert to integer indices.
02:02You're using name: twice to reassign. A key element in Red is that functions (expressions) return useful results, so you can use name: either [..., which also makes the intent clearer.
02:07So it could look like this:
f: %test.pdf
name: either pos: find/last f %. [
    copy/part f pos
][
    copy f
]
print name

Which may be more confusing to you at first, so I may think it's more idiomatically Red, that doesn't mean you have to use it. Use Red how it works for you.
rebred
02:09@greggirwin WOW!! that's amazing!!!!!
greggirwin
02:10Another approach, which eliminates either and two different types of calls to copy.
f: %test.pdf
name: copy/part f any [find/last f %.  tail f]
print name

The key element to understand here is any. Any and all are some of your best friends in Red.
02:10You may need to take some time to break that up and understand each piece, but you're making good progress! :+1:
02:11Reading Red can be very different, but once you get used to it, well written code can be both dense and very clear.
rebred
02:24@greggirwin amazing thank you!
greggirwin
02:26You're very welcome.
bubnenkoff
10:35I can't unserstand how to use react?
>> x: reactor [a: 0 b: 0 c: is [a + b]]
== make object! [
    a: 0
    b: 0
    c: 0
]
>> 
>> 
>> 
>> x/a: 5
== 5
>> 

>> react? x
*** Script Error: react? is missing its field argument
*** Where: react?
*** Stack: react?  

>> react? x/c
*** Script Error: react? does not allow integer! for its reactor argument
*** Where: react?
*** Stack: react?  
>>
11:09> @bubnenkoff take a look at [examples](https://doc.red-lang.org/en/reactivity.html) and proceed from there.
> view [f: field on-change [if f/text = "123" [ f/color: red] ] ]

I looked at them. But can't understand how to be in my case. Should I use any function inside of react?
view [f: field react [] ]
11:28
view [f: field react [f/color:  [ ] ] ]

I do now figure out know how to change color depend on value
endo64
11:49You can check the examples in the repo (https://github.com/red/red/tree/master/tests) find the react-test*.red files.
toomasv
12:39@bubnenkoff
>> x: reactor [a: 0 b: 0 c: is [a + b]]
== make object! [
    a: 0
    b: 0
    c: 0
]
>> x/a: 5
== 5
>> x/b: 2
== 2
>> x
== make object! [
    a: 5
    b: 2
    c: 7
]
>> react? x 'a
== [a + b]
>> react? x 'b
== [a + b]
>> react?/target x 'c
== [a + b]
bubnenkoff
12:41thanks! What difference between reactor and react from VID dialect?
toomasv
12:42Try
? reactor
? react

And [react in VID](https://doc.red-lang.org/en/vid.html#_react)
bubnenkoff
13:17Thanks! That's work:
fun: func[value] [either value = "123" [red] [none] ]
view [ f: field react [face/color: fun face/text] ]
14:27I have learned examples, but not fully understand how dynamic react works:
view [f1: field f2: field f3: field react/link :fun [f1 f2 f3] ]

Here I am trying to apply fun for all fields. But this code cause error
15:40it's seems that I should do something like this:
controls: layout [f1: field f2: field f3: field]
foreach c controls/pane [
	react/link :fun [c/text]
]

But I am getting error: REACT - reactive functions must accept at least 2 arguments
toomasv
15:53@bubnenkoff No, this is enough:
fun: func [o1 o2 o3][print rejoin [o1/text lf o2/text lf o3/text]]
view [f1: field f2: field f3: field do [react/later/link :fun [f1 f2 f3]]]

Remember to distinguish between [react in VID](https://doc.red-lang.org/en/vid.html#_react) and [react in Red proper](https://doc.red-lang.org/en/reactivity.html#_react)

bubnenkoff
10:42I can't figure out how to specify few property for faced. For example I want to specify text and offset for button.

view [b: button b/text: "text" offset ...  ]

before I placed all in action block [] like:
view [b: button [b/text: "text" b/offset ...  ]
but I want to do it without any actions
11:42I found that I can specify faced property after faced like: view [button 50x50 "text"] but what is their order?
>> ? b
B is an object! with the following words and values:
     type             word!         button
     offset           pair!         10x9
     size             pair!         78x27
     text             none!         none
     image            none!         none
     color            none!         none
     menu             none!         none
     data             none!         none


in my example second params is size, but in dump above it's offset
meijeru
12:39Read the View and VID documentation. View describes the face object (model is called face!) and VID describes the dialect which allows the system to construct the objects. The VID interpreter sees a pair! value somewhere, and concludes it is intended as the size field of the face being constructed. That's how it works.
12:40In any case, your dump and your VID text do not correspond. How did you define b?
bubnenkoff
13:52view [b: button]
greggirwin
14:08@bubnenkoff, as @meijeru suggests, the docs should make it all clear. If not, it can help to tell us what part of the docs you're using as a guide, so we know what isn't answering people's needs.
Oldes
15:30@bubnenkoff
>> view [at 100x200 b: button "hello"]
>> ? b
B is an object! with the following words and values:
     type             word!         button
     offset           pair!         99x199
     size             pair!         62x27
     text             string!       "hello"
...

100x200 is the offset.
meijeru
15:44In this case, the VID interpreter has rightly understood that 100x200 is the offset, but has applied internal rules for positioning. There was no other pair for the size of the button, so the size was taken from the defaults. What else do you not understand?
Oldes
16:17@bubnenkoff if you wonder why the offset is 1x1 off, than it is counting with the system's button border width.
16:18
>> system/view/metrics/margins/button
== [1x1 1x1]
bubnenkoff
19:30> In this case, the VID interpreter has rightly understood that 100x200 is the offset, but has applied internal rules for positioning. There was no other pair for the size of the button, so the size was taken from the defaults. What else do you not understand?

1. How to specify size and offset together
2. How it select what is it size or offset? What is internal logic of selection?
hiiamboris
20:03at is the key
bubnenkoff
20:03Is there any way to add slash at the end of path except using rejoin?
>> to-file "D:\folder"
== %D:\folder

I looked docs but did not find nothing for this case. I need path %D:\folder\
endo64
20:04to-file "D:\folder\" ?
20:05Just joking :) append to-file "D:\folder" "\"
20:06If you are using the result in your Red script then dirize can work with to-red-file
>> dirize to-red-file "D:\folder\a"
== %/D/folder/a/
toomasv
20:08Also:
>> normalize-dir %folder
== %/C/Users/Toomas/Documents/Red/folder/
>> to-local-file normalize-dir %folder
== "C:\Users\Toomas\Documents\Red\folder\"

bubnenkoff
11:30thanks! How to display count of files?
xml-files: ["1.xml" "2.xml"]
view [
 text to-string do [length? xml-files]
]

*** Script Error: VID - invalid syntax at: [to-string do [length? xml-files]]
*** Where: do
*** Stack: view layout cause-error
hiiamboris
11:36don't you know from the docs I'm sure you've read that to-string is not a VID keyword?
bubnenkoff
11:40I missed this... I tried compose
xml-files: ["1.xml" "2.xml"]
view [
 compose [ text (length? xml-files) ]
]

But got syntasic error
hiiamboris
11:49Point me to a place in VID docs, where compose is mentioned
bubnenkoff
12:07http://helpin.red/Helpin%27%20Red.pdf

page 227
hiiamboris
12:15Does that example work for you?
bubnenkoff
12:27Yes it's work, but I can't understand if it suitable for my situation
hiiamboris
12:37Try to find out what's the difference between that example, and yours.
bubnenkoff
12:37The difference that compose is passing to view?
hiiamboris
13:03Before [ you're in a Red context, after [ you're in VID context. It's like a fence - if you're trespassing, be prepared ;)
toomasv
14:03@bubnenkoff Use data keyword:
>> xml-files: ["1.xml" "2.xml"]
== ["1.xml" "2.xml"]
>> view [text data length? xml-files]
bubnenkoff
14:09thanks!
14:13I want to check field if it's text is dir. dir? is seems to be ok. But how to check both cases in one expression (to reduce code size). dir? do not accept empty field with none so I need to write two if expressions. if dir? folder and if folder not none (not sure about syntax). What is the short way to check both?
Oldes
15:00
if all [folder dir? folder][...]
15:02@bubnenkoff it is important to note, that dir? expects file! or url!... so you should check it too. I don't know what is your input and if you expect just files or also urls.
15:03Also it does not check, if it really exists, only if it ends like dir.
greggirwin
18:33@bubnenkoff I think I've said this before, but *please* take some time to get *very* comfortable with Red at a basic level. How different values work, functions, blocks, and big fundamental functions like [reduce compose find select append insert], objects, maps, and more. This will make your life *so* much easier. Then move back into View and VID, understanding that dialects can offer different semantics, including keywords, than Red itself.
bubnenkoff
20:16@greggirwin your are right, but theory and practice are different. When I am reading theory I understand it more or less, but on real project I am facing with problems. So only practice here...

How to prevent GUI from freeze? I run insert few thousands of files to SQLite DB and now app GUI is frozen.
20:21Here is my first more or less working GUI App https://gist.github.com/bubnenkoff/fb201803460c6e2c430fe94b5ba2c5b0 please give me any critic about code (I have got UI freeze here)
greggirwin
20:21Practice is playing in the REPL, at least it's a good way to start.

When you have problems, it can help enormously to post your complete code in a gist. Otherwise we have no way of knowing what is really going on, or any way to reproduce issues to help solve them.

Red is single threaded, so the GUI won't respond while your DB calls are running. You can often use do-events/no-wait in loops, to let the system breathe.
20:21That way updates to faces and such will show.
20:29@bubnenkoff, one of the first things I'll suggest is to break code from face actions out into functions, calling those from the face action. That way you can test the functions more easily without the GUI. Next, see how long a single insert takes. Here's something you can use to do that: https://gist.github.com/greggirwin/908d44dc069ed84cf69f053e1308390d
20:32From there, you can look at using a rate on a face, which gives you a "timer" event that you can use to trigger processing. You can also try adding do-events/no-wait (maybe 2-3 times even) inside your foreach xml-file loop, which should let the UI refresh.
GiuseppeChillemi
23:14@hiiamboris Here is my first attempt to get a printout of all the functions defined in a block of code as I have requested before

fwords: [
    'func | 'function | 'funct | 'has | 'does 
]

get-functions: func [
	"Recursively search for all funcions in a block of code and prints them with associated specs"
	code [block!]
	/into
]
[
	if into [code: first code]
	parse code [
		any [
			[to set-word! copy fname thru set-word! 1 fwords copy specs block! (prin [first fname " "] probe first specs)] |
			[thru 'set copy fname [word! | lit-word!] fwords copy specs block! (prin [first fname " "] probe first specs)] |
			[copy a-block 1 block! (get-functions/into a-block)] | skip
		]
	]
]


The function is recursive and seems to work quite well but I am open to criticims.
23:16*Note: I did it in Rebol2 but it should be RED compatible. (It's too late here to try it)
hiiamboris
23:29As you might know, does has no spec ☻
23:29Although you're only using those for debugging so I guess it's okay
GiuseppeChillemi
23:47I need to study others analize code.
23:48Pardon
23:48Analize other developers codd
23:48*code
23:48(I am on mobile)

GiuseppeChillemi
04:22@hiiamboris can't we change does to accept a specs block, so I don't have to modify my code? 😁
hiiamboris
bubnenkoff
09:39I am playing with console. I want to retrieve file with it's folder name.
>> find/last "/d/folder/subdolder/sub2/sub3/foo.txt" "/"
== "/foo.txt"`

But I need sub3/foo.txt

I read docs about find but I can't think of any variants how to mix it with skip or second (I think I thould use them)
hiiamboris
09:41just repeat the same thing you're doing, again
09:41although, you'll have to prepare the string a bit ;)
bubnenkoff
09:46Call find/lasttwice?
09:47in origin I need to do same with path, but I decided that string is ok for start
hiiamboris
09:48Type ? find and study what options it provides. And think how can you go from your find/last into another find call that would return exactly what you need.
Oldes
09:57@bubnenkoff
>> f: "/d/folder/subdolder/sub2/sub3/foo.txt"
== "/d/folder/subdolder/sub2/sub3/foo.txt"
>> find/reverse find/reverse tail f "/" "/"
== "/sub3/foo.txt"
>> find/reverse/tail find/reverse tail f "/" "/"
== "sub3/foo.txt"
bubnenkoff
10:02Oh thanks!
Oldes
10:02
>> p: tail split f "/" rejoin [p/-2 #"/" p/-1]
== "sub3/foo.txt"

there is many ways.
hiiamboris
10:05Beware though that copy-pasted solutions won't let you learn Red.
bubnenkoff
10:05ok! I will try to rewrite it. To better remember
hiiamboris
10:09Also, as a parse rookie you can try applying parse to this task, as an exercise ;)
Oldes
10:16@bubnenkoff don't listen to him, that is too heavy calibre... I think that using 2x find/reverse is the lightest variant. And you could use just #"/" instead of "/"
hiiamboris
GiuseppeChillemi
10:33Is there a way to probe without newline?
hiiamboris
10:33prin mold
GiuseppeChillemi
10:38Grazie !
toomasv
11:21@bubnenkoff Also
f: tail "/d/folder/subdolder/sub2/sub3/foo.txt"
f: next loop 2 [f: find/reverse f #"/"]
== "sub3/foo.txt"
bubnenkoff
11:59look really cool!
12:09I am continue to play with VID. I want make it's easier to group UI elements. I want to assign groups of elements to words and than pass them to panels. Is it good idea? This code is not working because panel accept blocks but not words
view [
	buttons-group-1: [button button]
	buttons-group-2: [button button]
	
	panel red buttons-group-1
	panel blue buttons-group-2
]
toomasv
12:30Why don't you experiment a bit? Ask yourself "Hmm! Something like that might work... May be I can arrange things a bit differently? Let's try this... Nope. But may be this... Yehuu.."
buttons-group-1: [button button]
buttons-group-2: [button button]
view [
    panel red buttons-group-1
    panel blue buttons-group-2
]
cloutiy
13:47I have a question related to call. Is it possible to create a red prog that on exiting returns something (like a string or a block) that can be used by another red program which initiated the call?
hiiamboris
14:41Indeed. Just print it and capture the /output.
meijeru
14:42@bubnenkoff I think that you have still not grasped the difference between the VID dialect (all the words and other values that are within view [...]) and the regular Red programming (all the words and other values that are outside of view [...].
bubnenkoff
14:47Yes, sometimes I am confuse when one dialect is ending and other beginning.
cloutiy
15:06@hiiamboris ok thanks. I will try that.
meijeru
16:14@bubnenkoff But it is vital that you do distinguish, because the same word can have different meanings. Please also read [this piece of documentation](https://github.com/meijeru/red.specs-public/blob/master/specs.adoc#dialects), in connection with [this one](https://github.com/meijeru/red.specs-public/blob/master/specs.adoc#values-and-types). It will hopefully improve your understanding.
GiuseppeChillemi
19:44@bubnenkoff in Red dialects are not signalled in the help of a command but you can discover them reading the documentation. I know about 2 dialects in Red:
the specs block of a function
func **[arg]** []
and
*VID* (Video interface dialect).
There can be more but more experienced developer should intervene here.
19:48In VID you have to remember just this:

VIEW [**anything there is interpeted by a dialect** [*here is a normal
Red code which is BOUND to VID*]]
19:49That's all !
GaryMiller
21:23This probably a pie is the sky wish but would it be possible to write a RED program and then pass it through another RED piece of RED code that would convert as much of it as it could to RED System. I was thinking if the console had a menu command for compile it could translate as much of the program that was loaded to RED system and then invoke the compiler to make the executable. The final executable would run a lot faster then because a higher percentage of codee hopefully would be executing as RED system code.
Respectech
22:02@GaryMiller I think that might be the idea behind Red JIT.
22:02Or maybe something along those lines.
greggirwin
22:20@GaryMiller there's a CLI switch, --red-only that will show you just that. The analysis, figuring out what would benefit from conversion to R/S, could be done at the Red level though. Don't expect much speedup though. If you're using Red "properly", you're making use of the runtime, rich datatypes, etc., none of which exist at the R/S level. R/S is great if you're doing repetitive math on basic numbers, or old-school string processing. Beyond that, you'll be implementing your own special purpose code in R/S for specific needs.

bubnenkoff
09:40Wow guyes! Look at my first Red component that do real task! It's generate valid SQL!
Really big thanks for help! Without your help I was not able to develop it!
https://gist.github.com/bubnenkoff/d1cd11a59543e03fe78b4ff267337478
rebolek
10:30@bubnenkoff congratulation!
10:31btw, you can remove line 2, it servers no purpose.
10:32instead of (length? something) = 0 you can use empty? something
hiiamboris
10:32print("Please select Order") funny style ;)
rebolek
10:33if not none? something [...] is same as if something [...]
bubnenkoff
11:51thanks! Does anybody have ready to use function for recursive dir list that return full paths to files. I googled and found one but it's limited in depth. Only two level nesting.
rebolek
12:08@bubnenkoff for example:
>> tree: func [path /local full dir][dir: read path foreach file dir [print full: rejoin [path file] if dir? file [tree full]]]
>> tree %./
bubnenkoff
12:21The red-cosnsole is hanging than I am getting error:
/D/zak_data/Moskva/notice/notification_Moskva_2020030400_2020030500_001.xml/fcsNotificationZK504_0373200006620000042_23063229.xml
*** Script Error: reset-buffer does not allow vector! for its <anon> argument
*** Where: reset-buffer
*** Stack: tree tree tree tree
rebolek
12:25Probably some gui.console problem, I am using CLI console on Linux and it works fine
bubnenkoff
12:38It work only if dir have few files
12:38On 1000+ files it hang
9214
12:47Deeply recursive calls seem to corrupt the call stack.
https://github.com/red/red/issues/4184
hiiamboris
12:58> thanks! Does anybody have ready to use function for recursive dir list that return full paths to files. I googled and found one but it's limited in depth. Only two level nesting.

@bubnenkoff https://gitlab.com/hiiamboris/red-junk/-/tree/master/glob
Rebol2Red
14:24@bubnenkoff Maybe not the best but it's easy to follow
read-folder-recursive: function [ 
	dir-
][
	file-list: []
	dir-: to-red-file dir-
	foreach file read to-red-file dir- [
	   file-: either dir- = %./ [file][dir-/:file]
	   append file-list to-local-file file-
	   if dir? file- [
			read-folder-recursive file-
	   ]
	]
	new-line/all file-list on
	file-list
]
block: read-folder-recursive %/C/RED/ ; Change the dir to a readable dir, not C:\Windows\ C:\Program Files\, etc
probe block ; do anything you like with this block

or maybe this:
read-folder-recursive: function [
	dir- [file!]
][
    collect [
        foreach file- read dir- [
			file-: rejoin [dir- file-] 
			either dir? file- [
				keep read-folder-recursive file-
			][
				keep file-
			]
        ]
    ]
]
block: read-folder-recursive %/C/RED/
probe block

I have programmed many of them and found a lot everywhere. As an excercise try to make your own one which for ex. filters out unwanted files! It's not difficult at all.
fergus4
14:38I'm 'calling' program that creates qrCodes. The program will display the code in the windows console when run in console but if I try to capture the output in my call I get:
Access Error: invalid UTF-8 encoding: #{89504E47

Anyone know what format console images are in and if they are readable by red or rebol?
hiiamboris
14:41capture it into a binary #{}
Rebol2Red
15:15By accident i deleted this but here it is again.

The basics behind recursivly reading a folder (If you adjust this you can use it for all kinds of recursion)
recdir: function [
	folder
][
	stack: copy []
	foreach item read folder [
		either dir? item [ ; Is it a folder?
			append stack item ; Put folders onto a stack
		][ ; it's a file
			; Here you can put the files into a block defined outside the function!
			; You may change "to-local-file" into "to-file" 
			; or "to-red-file" (which is the same)
			probe to-file rejoin [folder item]  ; Join folder and file			
		]
	]
	; Process folders one at a time
	foreach item stack [
		recdir to-red-file rejoin [folder item] ; Call function with the joined folder and file (this is the recursion)
	]	
]
folder: %/C/RED/
recdir folder
bubnenkoff
15:27Thanks
15:27I want to generate 10 fields and than will them with data. I do not know right way to access to /text field of every field.
aa: collect [loop 10 [keep [f-name: field hint "file_name"  f-date: field hint "xml_date" return]]]
view[
    panel aa
    button "load" [
        foreach a aa [ if word? a  [ print [type? a ] ]] ; Am I thinking right? 
    ]
    t: text-list data []

I want to check field type (name?) and than set value to it.
Rebol2Red
15:32@bubnenkoff
Maybe you want iterative instead of recursive
;-----------------------------------------------------------------------
; READ FOLDER TO BLOCK ITERATIVE
;-----------------------------------------------------------------------
read-folder-iterative: func [ ; do not use function!
	
	"Read a folder iterative" folder [url! string! file!] /filter list [block! string!] /local stack paths

][

	stack:  copy []	fileblock:	copy []	
	case [
		type? folder = url! [folder: to-red-file to-string folder]
		type? folder = string! [folder: to-red-file folder]
	]

	if not(%/ = back tail folder) [append folder %/]
	append stack folder 													; PUSH	ONTO STACK
	while [not (empty? stack)] [ ; stack is empty?
		folder: last stack 	remove back tail stack 				; POP FROM STACK
		read-folder: read folder
		foreach item read-folder [
			either dir? rejoin[folder item] [ ; is it a folder?
				append stack rejoin[folder item] ; PUSH ONTO STACK
			][ ; it's a file
				; apply filter
				either filter [
					foreach filteritem list [
						if find item filteritem [
							append fileblock rejoin[folder item]		
						]
					]
				][		
					append fileblock rejoin[folder item]		
				]
			]
		]
	] 

	; paths and files
	paths: copy []	files: copy [] 
	foreach file fileblock [
		splitted: split-path to-red-file file	
		append paths splitted/1
		append files to-local-file file
	]	

	; create a file-object
	file-object: copy []		
	append file-object rejoin [[filecount:] length? fileblock]
	append file-object rejoin [[mapcount:] length? unique paths]
	append file-object rejoin [[files:] sort files]
	do file-object
	file-object

]
;-----------------------------------------------------------------------

;-----------------------------------------------------------------------
comment {
	; Almost anything goes:

	; FOLDER AS FILE
	read-folder-iterative %/C/RED/DATAFILES 
	read-folder-iterative %/C/RED/DATAFILES/
	read-folder-iterative %\C\RED\DATAFILES 
	read-folder-iterative %\C\RED\DATAFILES\ 

	; FOLDER AS STRING
	read-folder-iterative "C:\RED\DATAFILES"
	read-folder-iterative "C:\RED\DATAFILES\"

	; FOLDER AS URL
	read-folder-iterative C:\RED\DATAFILES 
	read-folder-iterative C:\RED\DATAFILES\

	; even mixed
	read-folder-iterative %/C\RED\DATAFILES 	
	read-folder-iterative %/C\RED/DATAFILES 	

	;FILTER AS FILE
	read-folder-iterative/filter C:\RED\DATAFILES\ [.exe .png]

	;FILTER AS STRING
	read-folder-iterative/filter C:\RED\DATAFILES [".exe" ".png"]
	
	; Except the following:
	read-folder-iterative \c\RED ; this does not work, invalid value
	read-folder-iterative /c/RED ; this does not work, because it is a refinement	
}
;-----------------------------------------------------------------------

;-----------------------------------------------------------------------
; Two examples:
;-----------------------------------------------------------------------
r: read-folder-iterative %/C/RED/INC/
print ["Files:  " r/filecount]
print ["Folders:" r/mapcount]
foreach file files [
	print file
]
;-----------------------------------------------------------------------
r: read-folder-iterative/filter C:\RED\ [.txt]
foreach file files [
	print file
]
;-----------------------------------------------------------------------
greggirwin
19:33@bubnenkoff you're close. Type? will return the datatype, which you've already checked as word?. But set-word! values (ending in colons) won't match that. The main thing is not to confuse the type? function with the /type facet for a face.
19:33
flds: collect [
	repeat i 10 [
		keep compose [
			(to set-word! join 'f-name- i)	; give each a unique name
			field 150 hint "file_name"
			(to set-word! join 'f-date- i)	; give each a unique name
			field 150 hint "xml_date" return
		]
	]
]
view [
    p: panel flds
    button "load by name" [
        foreach fld flds [
		if set-word? fld [
			face: get fld
			face/text: rejoin ["My name is: " fld]
		]
	]
    ]
    button "load by face type" [
        foreach face p/pane [
		if face/type = 'field [
			face/text: rejoin ["I'm at offset: " face/offset]
		]
	]
    ]
    t: text-list data []
]

Be sure to look at what flds contains, when generated from the above.
19:34Notice the two different approaches, and see if you can understand how each works.

rebred
05:22is there way to see if a word has been assigned (exist) ?
Respectech
06:22value? 'word
06:22unset? 'word
GiuseppeChillemi
06:51@bubnenkoff All faces have the same f-name name. They should be different, otherwise you will always reference the lasts one accessing data via f-name
06:52Use a loop with an index and dinamically build it
rebred
09:10@Respectech great thank you!

GiuseppeChillemi
09:31I don't understand what load/next is useful for. Which is its use?
hiiamboris
09:47https://gist.github.com/dockimbel/bffe92eb070b24f5573b677589a94591
09:49https://gitlab.com/hiiamboris/red-composite-macro
ne1uno
09:52appears to be changing in fast-lexer? used to return [item loaded rest of series! any error!] now just item or error?
hiiamboris
09:56I think you're mistaking it with R2 load/next
GiuseppeChillemi
09:59Pardon, I have suppose it was a common refinement. Which is its use in R2?
09:59*supposed
hiiamboris
11:03same ;) I was answering @ne1uno's question
GiuseppeChillemi
11:29Ok, but I don't know where and why use it. This is the reason I am asking.
bubnenkoff
11:39> Notice the two different approaches, and see if you can understand how each works.

big thanks for example! Do it work for you? I understand the idea, but copy-past from your ample do not work
11:51> @bubnenkoff you're close. Type? will return the datatype, which you've already checked as word?. But set-word! values (ending in colons) won't match that. The main thing is not to confuse the type? function with the /type facet for a face.
>

The first error that I am getting:
>> flds: collect [
[        repeat i 10 [
[            keep compose [
[                (to set-word! join 'f-name- i)    
[                field 150 hint "file_name"
[                (to set-word! join 'f-date- i)    
[                field 150 hint "xml_date" return
[            ]
[        ]
[    ]
*** Script Error: join has no value
*** Where: to
*** Stack: collect
12:00it's seems to be:
(to set-word! rejoin ['f-name- i]) ; give each a unique name
instead of:
(to set-word! join 'f-name- i)
12:09I got it work!:
flds: collect [
    repeat i 10 [
        keep compose [
            (to set-word! rejoin ['f-name- i])    ; give each a unique name
            field 150 hint "file_name"
            (to set-word! rejoin ['f-date- i])    ; give each a unique name
            field 150 hint "xml_date" return
        ]
    ]
]

view [
    p: panel flds
    button "load by name" [
        foreach fld flds [
        if set-word? fld [
            face: get fld
            face/text: rejoin ["My name is: " fld]
        ]
    ]
    ]
    button "load by face type" [
        foreach face p/pane [
        if face/type = 'field [
            face/text: rejoin ["I'm at offset: " face/offset]
        ]
    ]
    ]
    t: text-list data []
]
13:59Is it's possible to add index on foreach loop? Like in some C-style language foreach(index, r; result) { }?
hiiamboris
14:32Not *yet*. For now, use repeat or forall
14:33Or just make a counter yourself
bubnenkoff
15:12print probe result show me:
[
    1 "4171" {fcsNotificationEA44_0138200004020000001_22657730.xml} "20200101"
    2 "4172" {fcsNotificationEA44_0148300001519000068_22643157.xml} "20200101"
    3 "4173" {fcsNotificationEA44_0148300001519000069_22643116.xml} "20200101"
    4 "4174" {fcsNotificationEA44_0148300001519000070_22643084.xml} "20200101"
    5 "4175" {fcsNotificationEA44_0148300001520000001_22647833.xml} "20200101"
]


What is the best way to print only filename?
hiiamboris
15:32? extract
bubnenkoff
16:31
x: [
    1 "4171" {22657730.xml} "20200101"
    2 "4172" {22643157.xml} "20200101"
    3 "4173" {22643116.xml} "20200101"
    4 "4174" {22643084.xml} "20200101"
    5 "4175" {22647833.xml} "20200101"
]

>> extract/index x 2 3
== ["22657730.xml" 
    2 "22643157.xml" 
    3 "22643116.xml" 
    4 "22643084.xml" 
    5 "22647833.xml"
]

How to stay only names? The result not exact same as I need.

The digits 1 2 3 etc is seems to be generated by SQLite driver
9214
16:44@bubnenkoff re-read extract docs once again. width is a size of a "row", /index specifies index of a "column" in this "row".
hiiamboris
16:46I didn't even know there's /index refinement ;)
16:47Must be a convenience thing
PierreChTux_twitter
17:00Hello!
I'm wondering if there's a sort of startup script for Red, the equivalent of ~/rebol.r in Rebol.
I've looked into the documentation, unsuccessfully so far.
hiiamboris
17:04I don't think so. You'll have to #include it.
PierreChTux_twitter
17:06That would rather be for my daily use of Red. At the moment, I'm using Rebol 2 (happily), and my ~/rebol.r loads plenty of libraries, so that I can have them handy any time I open a Rebol console.

I'm just missing that feature in Red, and I'm currently trying to convert myself to Red.
17:07I guess that this would be fairly simple to code into the Red interpreter.
hiiamboris
17:07I just defined a batch script that would run red --catch init.red, and start the console with it.
PierreChTux_twitter
17:11Yes, that's cool; but what I find particularly handy with the Rebol 2 approach (just a script named following a conventional name: if it exists, just load it) is that I have the exact same environment (handy functions and words, predefined names pointing to the current database I'm working on, these little things) in my console and in the scripts that are run.

I guess that your approach doesn't cope with this.
Unless you redirect your global red executable to that batch, of course.
hiiamboris
17:12Redirection won't work actually at all, because it only takes a single script from the command line, and init.red is in that place already.
PierreChTux_twitter
17:12Ach.
hiiamboris
17:13It's possible to rewrite init.red so that it would do the next argument I guess ;)
PierreChTux_twitter
17:13So I guess that we must just implement such a feature, don't we?
hiiamboris
17:14I also think that the need exists. But I don't like the silently execute some file approach. I'd rather add a command line option to specify a startup script. Or maybe use an environment variable for that :/
PierreChTux_twitter
17:15Well, frankly, instead of fiddling with this, I'd rather code a default .redrc (or something similar, I'm just referring to the most common way to name init and preferences files on the OSs that I deal with) that is just run by default at startup time, just before executing a script or a REPL.
17:16@hiiamboris you don't like silence? ;-)
hiiamboris
17:18Well, there's a config.red anyway (though auto-generated), so I guess it's an option too.
PierreChTux_twitter
17:19Personnally, I found the Rebol 2 way to be quite perfect. If I don't want anything, I just rename my startup file .vatefairepasvoir or something equivalent. It doesn't exist by default, and if I create it, I'm suppose to act as a consenting adult.
17:19> Well, there's a config.red anyway (though auto-generated), so I guess it's an option too.

Ah, interesting!
hiiamboris
17:24What about the compiler? Should it silently #include this startup script? If yes, it will bloat your programs with the code they might not use. If not, and you write #include manually, then interpreter will evaluate the startup script twice - once automatically, then again following #include directive.
PierreChTux_twitter
17:28Good point. I guess that you would instinctively wish that your compiled executable would behave just like what you've just coded, which works fine.
It depends: if the compiler manages to *not* include all definitions of useless stuff that your init file points to, then it shouldn't make a difference.
Otherwise, it is an issue, yes.

But again, you're supposed to be an adult, and at compile time, you have to wake up and suppress the useless stuff that clutters your init.
hiiamboris
17:30Then using a command line option/envvar is preferable, as you won't have to rename your file back and forth every time.
PierreChTux_twitter
17:32I'm looking for that config.red on my machine, I can't find it. I tried to generate one in my ~ : it hasn't been taken into account by my next Red instance:

locate config.red

  # pierre@latitude: ~        < 2020_04_19__19:19:29 >  [bashpid_9668]
cat > config.red
Red []     
"Tentative de faire un féchier de config, à l'aveugle.
print "Coucou"


  # pierre@latitude: ~        < 2020_04_19__19:20:20 >  [bashpid_9668]
red
GTK VERSION: 3.24.5
--== Red 0.6.4 ==-- 
Type HELP for starting information. 

>> 

  # pierre@latitude: ~        < 2020_04_19__19:20:26 >  [bashpid_9668]
hiiamboris
17:33It's where the command history is kept. Do you have a history when you load a fresh console?
PierreChTux_twitter
17:33> Then using a command line option/envvar is preferable, as you won't have to rename your file back and forth every time.

Or, as you mentioned above, the compiler should just ignore that startup script, which would be dedicated for interactive work and script interpretations.

The one who wants to compile it would just need to think slightly more when he compiles. He deserves that.
17:34> It's where the command history is kept. Do you have a history when you load a fresh console?

No, I don't.
But the interpreter that I use dates from a few weeks, if not months.
17:35I'll fetch the newest Red stuff from github.
hiiamboris
17:35Pardon! It's named console-cfg.red
17:36But it will be overwritten once you exit the console, so won't work for you anyway
PierreChTux_twitter
17:37Given the place where that file is located on my system, I doubt that it's much considered:

# pierre@latitude: ~        < 2020_04_19__19:36:05 >  [bashpid_9668]
locate console-cfg.red
/home/pierre/heaume_pierre/.wine/drive_c/windows/profiles/All Users/Red/console-cfg.red

  # pierre@latitude: ~        < 2020_04_19__19:36:15 >  [bashpid_9668]


luce80
17:38I vote for a %user.red or %red.red
PierreChTux_twitter
17:38Obviously, I had run a windows version of Red, on February 13th, 2017, according to that file's date...
hiiamboris
17:39@PierreChTux_twitter There should be a linux variant too, somewhere in ~/.Red-Console/ or somewhere
17:40Does it look in hidden dirs? Although it did in .wine
PierreChTux_twitter
17:45> I vote for a %user.red or %red.red

Are we in a democracy here?
if democracy [ vote: vote + 1 ]

(I'm currently living in a democratic dictature, not a republic...)
17:48> @PierreChTux_twitter There should be a linux variant too, somewhere in ~/.Red-Console/ or somewhere

I don't have anything like that on my system.
hiiamboris
17:49You got me curious, but I killed my 32-bit linux VM, so can't test :/
Maybe someone else will confirm that. Looks like a bug
PierreChTux_twitter
17:50On my side, I killed all windows-related stuff... and I keep on killing any suspicious thing I can.
hiiamboris
PierreChTux_twitter
17:53I may also kill a few GNU/Linux things, as things are getting a bit messy in that direction too. To switch to a rock-stable, simplistic *BSD.

Not yet.
hiiamboris
17:54Well, it wasn't a religious act for me. It just stopped updating itself and became unable to install anything at all after 2 months of inactivity, and I tried to patch it with some solutions from SO, but in the end it didn't work and I decided it'll be simpler to just download a new image than to fix the mess they made.
PierreChTux_twitter
17:54Oh, sorry to hear that. Which distro was it?
hiiamboris
17:55xubuntu
9214
18:05We have a [dedicated room](https://gitter.im/red/chit-chat) for casual chat, FYI. Please keep this one on topic.
PierreChTux_twitter
18:28Sorry for the noise.
Back on topic => HELP! Is there a red.ini, a .redrc, a startup.red or anything equivalent?
endo64
18:34No, not yet. But you can compile your console with your script included, or make a change to include/do a startup script.
rebol.r and user.r was useful in Rebol2, but it has also a security risk.
PierreChTux_twitter
18:36Security risk?
18:37Doing something being a security risk, why do anything at all?... (oh my bad, off-topic again...)
20:34Back here for some HELP (and I'll do my best to remain on-topic):
I'd like to give it a try, and to implement some kind of initialisation file, in the style of rebol.r or .vimrc or alike.
Therefore, I git pulled the red sources from github, and I tried to compile a Red interpreter, referring to the way I had done it in the past.
Everything went fine until I hit the compilation time; I just corrected a path to match the evolution of the codebase:
do/args %red.r "%environment/console/console.red"
=>
do/args %red.r "%environment/console/CLI/console.red"


However, I came across some b0rdel:

>> do/args %red.r "%environment/console/CLI/console.red"

-=== Red Compiler 0.6.4 ===- 

Compiling /home/pierre/heaume_pierre/developpt/Red/environment/console/CLI/console.red ...
...using libRedRT built on 8-Mar-2019/9:35:43
...compilation time : 563 ms

Target: Linux 

Compiling to native code...
*** Compilation Error: undefined symbol: red/word/duplicate 
*** in file: %/home/pierre/heaume_pierre/developpt/Red/environment/console/CLI/console.red 
*** at line: 339 
*** near: [word/duplicate ~script 
    ~args|361: word/duplicate ~args 
    ~console|362: word/duplicate ~console
]
>>


Line 339 is quite far below the end of file, which only has 32 lines... I guess I should #include manually in my editor, to find out which line is concerned.
greggirwin
20:34Apologies for the typo @bubnenkoff, I have join defined in my local environment.
9214
20:39@PierreChTux_twitter readme file in the project's root folder gives pretty unambiguous instructions on how to compile console from sources.
PierreChTux_twitter
20:52@9214 Yes, I was following the steps I had done a few months ago. I'll refer back to the README.md .
20:53Well, it fails.
20:53Same error message.
hiiamboris
20:55Shouldn't you use -r?
PierreChTux_twitter
20:55Where?
hiiamboris
20:56Before the %
PierreChTux_twitter
20:57
>> do/args %red.r "-r %environment/console/CLI/console.red
** Syntax Error: Missing " at do/args %red.r "-r %environment/console/CLI/console.red
** Near: halt
>>
9214
20:58... just copy a line from readme file verbatim.
hiiamboris
20:58Yes ;)
PierreChTux_twitter
20:58Yes...
20:59That's just what I did... I'll start from a fresh directory, just new born, and git clone there.
9214
21:00You missed a closing double quote, that's what you did. It's even in the error message.
PierreChTux_twitter
21:00I should stop drinking.
21:02
>> do/args %red.r "-r %environment/console/CLI/console.red"
** Access Error: Cannot open /home/pierre/heaume_pierre/developpt/Red/system/red.r
** Near: do/args %red.r "-r %environment/console/CLI/console.red"

I guess I'd better go to sleep...
9214
21:03You should do that from the root folder where %red.r is located, not from /system.
PierreChTux_twitter
21:03Got it: the bugger had cded somewhere during script evaluation, without returning where he started...

>> pwd
== %/home/pierre/heaume_pierre/developpt/Red/system/
>> cd ..
== %/home/pierre/heaume_pierre/developpt/Red/
>> do/args %red.r "-r %environment/console/CLI/console.red"

-=== Red Compiler 0.6.4 ===- 

Compiling /home/pierre/heaume_pierre/developpt/Red/environment/console/CLI/console.red ...
...compilation time : 2003 ms

Target: Linux 

Compiling to native code...


That's taking time and whipping up my CPUs: good sign...
21:05> You should do that from the root folder where %red.r is located, not from /system.

That's exactly what I did! What certainly happened is that the invoked script has cded to system at some points, during the first tries...
21:06Yes!
21:07
...compilation time : 48410 ms
...linking time     : 483 ms
...output file size : 808180 bytes
...output file      : /home/pierre/heaume_pierre/developpt/Red/console 


== none
>> REBOL terminated

  # pierre@latitude: ~/dev/Red        < 2020_04_19__23:05:19 >  [bashpid_25284]
~/dev/Red/console 
--== Red 0.6.4 ==-- 
Type HELP for starting information. 

>> print "Y E S !   I   C A N   S T A R T    P L A Y I N G !"
Y E S !   I   C A N   S T A R T    P L A Y I N G !
>>


Thanks for help!

No thanks to my own stupidity.
greggirwin
22:35We all trip sometimes @PierreChTux_twitter. :^)
PierreChTux_twitter

bubnenkoff
07:15> Apologies for the typo @bubnenkoff, I have join defined in my local environment.

Could you explain for what purpose do you use local define?
rebolek
07:27So when he needs to use join, he has it available.
hiiamboris
10:20@PierreChTux_twitter ~/.red/.Red-Console/console-cfg.red
bubnenkoff
10:34@greggirwin I have got new problem\question (see comment). I have prepared code that emulate DB answer.
result: [ ; db data example
	1 {file1.xml} "2000"
	2 {file2.xml} "2001"
	3 {file3.xml} "2002"
	4 {file4.xml} "2003"
	5 {file5.xml} "2004"
	6 {file6.xml} "2005"
	7 {file7.xml} "2006"
	8 {file8.xml} "2007"
	9 {file9.xml} "2008"
	10 {file10.xml} "2009"
]

flds: collect [
    repeat i 10 [
        keep compose [
            (to set-word! rejoin ['f-name- i])    ; give each a unique name
            field 150 hint "file_name"
            (to set-word! rejoin ['f-date- i])    ; give each a unique name
            field 150 hint "xml_date" return
        ]
    ]
]

view[
    p: panel flds
    button "load" [
        foreach fld flds [
            if set-word? fld [
                ; f-name-n and f-date-n would have same type
                ; but I should separate them
                ; how to do it? to check every fld name?
                ; or there is better way?
                ]
        ]
    ]
]
12:00After some experiments I found only one way to do what I want. Not sure that it's good. But I have not idea how to do it more correct:
view[
    p: panel flds
    button "load" [
        foreach fld flds [
            if set-word? fld [
                fld-name: to-string fld
                if find fld-name  "f-name" [ 
                    ; here I will set f-name-n
                    ]
                ]
        ]
    ]
]
12:25I did it. Not sure that it's correct, but at last it works. If anybody have ideas about improving I would be very grateful
result: [
	1 {file1.xml} "2000"
	2 {file2.xml} "2001"
	3 {file3.xml} "2002"
	4 {file4.xml} "2003"
	5 {file5.xml} "2004"
	6 {file6.xml} "2005"
	7 {file7.xml} "2006"
	8 {file8.xml} "2007"
	9 {file9.xml} "2008"
	10 {file10.xml} "2009"
]

file_names: extract/index result 3 2
file_dates: extract/index result 3 3

flds: collect [
    repeat i 10 [
        keep compose [
            (to set-word! rejoin ['f-name- i])    ; give each a unique name
            field 150 hint "file_name"
            (to set-word! rejoin ['f-date- i])    ; give each a unique name
            field 150 hint "xml_date" return
        ]
    ]
]

view[
    p: panel flds
    button "load" [
        foreach fld flds [
            if set-word? fld [
                fld-name: to-string fld
                if find fld-name  "f-name" [ 
                    face: get fld
                    face/text: rejoin [take file_names]
                    ]

                if find fld-name "f-date" [ 
                    face: get fld
                    face/text: rejoin [take file_dates]
                    ]

                ]
        ]
    ]
]
hiiamboris
12:30:+1:
bubnenkoff
12:32@hiiamboris that's good?
hiiamboris
12:33Sure! If it works, it's good enough
PierreChTux_twitter
15:41> @PierreChTux_twitter ~/.red/.Red-Console/console-cfg.red

Ah, got it, thanks!

Yes, this files contains my (very short) Red command-line history.
But it obviously doesn't behave at all like an init file.

Anyways, thanks for this, I'll dig deeply in that direction.
bubnenkoff
16:35What is proper way to load VID components?
app.red:
Red []
load %abc.red
view [panel ctrls]

abc.red:
ctrls: [ button "Hello" ]

errror:
>> do load %app.red
*** Script Error: VID - invalid syntax at: [ctrls]
*** Where: do
*** Stack: view layout cause-error  

>>
greggirwin
16:41Do is the key here. Go step by step. What is the result of load %abc.red? What value does ctrls refer to after that line?
bubnenkoff
16:42load %abc.red is just load code as data
greggirwin
16:43Correct.
bubnenkoff
16:46So I need to to say to Red that I should execute it. I have only one idea do load but it does not work
greggirwin
16:48Are you using do on that result?
bubnenkoff
16:50It's seems that I should do:
ctrls: [ button "Hello" ]
do ctrls

in my abc.red right?
greggirwin
16:53Have you tried it? What else can you use do on?
bubnenkoff
16:53No. It's seems that I am wrong. It does not work on fresh console
greggirwin
16:54You're close...very close. You know you have loaded code, as data.
bubnenkoff
16:54
Red [needs: 'view]
do load %abc.red

view [panel ctrls]

it's seems that it work. One moment I will try in new console. Sometimes it's very confuse me when code stop working onnew console)
greggirwin
16:55Great! Now...do you need to use load first? What happens if you just do a file!?
bubnenkoff
16:55yes that's work
16:56> Great! Now...do you need to use load first? What happens if you just do a file!?

it's also works...
16:57it's seems that I can run do %app.red directly cut should load every component with do load %abc.red
PierreChTux_twitter
19:45> Sure! If it works, it's good enough

Excellent Principle.
To be carved in stone and repeated (at least) twice per minute by anyone.
20:03@bubnenkoff I have ideas, not really to improve your code; it's rather to make it a bit more elegant, or less human-readable (pick up the option you wish).

The first paragraph of code, where you define result, is way too human-readable. I'd trend to rewrite it as follows:
result: copy []
repeat i 10 [
append result rejoin [ i " {file" i ".xml}" { "} (2000 + i) {"} newline ]
]
`

Now, this is much more cryptic and elegant, isn't it?
The result is not exactly what your code gets, though. I shouldn't have made it a string, I guess.
I'm sure that it's possible to make this even more elegant.

meijeru
08:52@bubnenkoff As concerns do, you may benefit from reading [this explanation](https://github.com/meijeru/red.specs-public/blob/master/specs.adoc#function-do).
bubnenkoff
13:07What can be wrong with next function?
probe db-result show only first getted result that not depend of chaning sql-query
make-db-query: func[sql-query] [ 
    db-result: [] ; some issue here
    SQLite/do [
     db-result: exec sql-query
    ]

    probe db-result

    db-result-id: extract/index db-result 11 2
    db-result-arch_name: extract/index db-result 11 3
    db-result-file_name: extract/index db-result 11 4
    db-result-file_type: extract/index db-result 11 5
    db-result-forced_processing: extract/index db-result 11 6


    foreach cell ui-table-cells
    [
        if set-word? cell [ 
            fld-name: to-string cell
                if find fld-name  "f-id" [ 
                    face: get cell
                    face/text: take db-result-id
                ]
                if find fld-name  "f-file_name" [ 
                    face: get cell
                    face/text: take db-result-file_name
                ]

                if find fld-name  "f-file_type" [ 
                    face: get cell
                    face/text: take db-result-file_type
                ]
                if find fld-name  "f-processed_date" [ 
                    face: get cell
                    face/text: take db-result-processed_date
                ]

                {some code is skipped}                                              
        ]
    ]

]


When I am printing sql-query I see the proper request. But result of it execution look like the first request was executed.
9214
13:42db-result: sqlite/query sql-query.
bubnenkoff
13:45Thanks!!! I spend 4+ hours on this! What is the difference??
9214
13:49Do you understand that SQLite/do is a dialect with different semantics, and that set-word! in it has a different meaning?
13:56OTOH, looking at the code, this particular case looks like an oversight in implementation. It sets the word to the result of a query only the first time and checks DBs status after that.
GiuseppeChillemi
22:21Questions on LOAD
Is it possible to load a block without without binding its word to system context like R3 ?

I ask this because I want to create a
load/select func [code-name [word! block!] source [file! block! url!]][]
function. Its purposes is to load a block of code following a word or a set of code blocks, to have a mechanism of code segments loading. Otherwise the system words context would have too many unnecessary words.
hiiamboris
22:56Does it actually bother you that system/words contains your words? Or is this a purely hypothetical issue?
GiuseppeChillemi
23:06Certain pieces of my coding techniques checks for the existance of a word to take some actions. I have ended defining a working model to have dynamic stacking of code segments and assembling of functions, now I would like to load code parts from files without polluting the system context.
hiiamboris
23:14My question stands ;)

GiuseppeChillemi
00:20I checked using unset? And Value? Of word a couple of times last year. It could interfere with that code but not soo much. So it would not bother me to the point I can't implement something but I think that loading blocks and searching them without filling the system words context is something good to have. (do you like that answer? 😉)
endo64
07:24@GiuseppeChillemi isn't it possible something like: load/part pos: find read %file 'start find pos 'end ?
pekr
08:26Maybe you would be able to even get it without actually reading the whole file into memory, using read/seek?
GiuseppeChillemi
08:46@endo64 using your approach, the file should be parsed to find the starting and ending position of the block. Also loading object like data with nested blocks would also be difficult.
08:47@pekr the answer is for you too.
endo64
09:35I thought read/seek too once available but it would be more difficult. What I was in my mind, having some place-holders in the file like:
... other parts ...
<image-functions>
rotate: func [] [...]
my-constant: 1.0
blend: func [] [...]
</image-functions>


So you could be able to load that part only.
GiuseppeChillemi
18:40Semseddin, having paths support has many advantages like fine control of function loading, subgrouping. but your solution is viable for simple libraries. You have just to index start and ending points, extract and load them. Good !

endo64
14:27@rebolek Why to-csv doesn't put quote chars around the values? It did before IIRC:
>> to-csv/quote [[1 2] [2 3] [3 4]] #"-"
== {1,2^/2,3^/3,4^/}
>> to-csv [[1 2] [2 3] [3 4]]
== {1,2^/2,3^/3,4^/}
>> to-csv [1 2 3]
== "1,2,3^/"
>> to-csv/quote [1 2 3] #"'"
== "1,2,3^/"
14:46I also have a change request for to-csv, would it be better to remove the trailing newline character?
Because in a project I'm generating CSV lines one by one and add them to a block to later build up a file with write/lines, but since each CSV line has also newline.
Not a big deal that I can trim them, but to-csv in R2 doesn't also put newline which looks more useful to me.
greggirwin
17:03@endo64 I can't find a build where it included quotes if they weren't needed.
>> to-csv/quote [[1 2] [2 3] [3 "4 5 6"]] #"-"
== {1,2^/2,3^/3,-4 5 6-^/}

R2 didn't have to-csv AFAIK, so must be from somewhere else. But it's a good question. If you're appending CSV records to a string buffer, including the newline saves you a step. If you do it with write/lines, it adds a step. Since to-csv handles blocks already, it would help to know what benefit you get in your setup from converting first to a block of strings? I can imagine doing post-csv processing on them, but then I think we just need to add notes to https://github.com/red/red/wiki/CSV-codec as a use case.
17:04Doing it line by line can also be a good debugging tool for checking formed data.
endo64
22:34My use case is; I have text files that have lines with comma-separated values. But not all lines have same number of columns:
start,a,b,c
intermediate,1,2,3,4
end,p,"q,r",s,t,u

So I read/lines first, then for each line I use load-csv, then put them in separate blocks according to their types (start, intermediate or end rows have different number of colums)
Then I write them into different files by write/lines.
22:35Why I use blocks instead of appending to string buffer because it is *much* more faster.
greggirwin
22:37Excellent. Good info.
endo64
22:38It is a production script, for parsing CDR (Call Detail Recordings) files that handles millions of rows per day, so that speed is important for me.
22:39I've checked R2's to-csv (don't remember where did I get) it doesn't have quote at all.
23:14Another point, RFC4180 doesn't state a value should be quoted if it has whitespace, but to-csv does that (for spaces only and not for tabs):

> RFC4180: Fields containing line breaks (CRLF), double quotes, and commas should be enclosed in double-quotes

>> to-csv ["a" "b^-c" "d"]
== "a,b^-c,d^/"
>> to-csv ["a" "b c" "d"]
== {a,"b c",d^/}
23:16Ah then /quote comes in handy:
>> to-csv/quote ["a" "b c" "d"] #"|"
== "a,|b c|,d^/"

greggirwin
00:23@rebolek will probably chime in soon, but tab *may* have been omitted because tab separated values are probably the most common, after comma separated. RFC4180 is funny in that the "Interoperability considerations" section basically says "We tried, but really, there is no definitive spec." :^) I think Brian Hawley's CSV was the most complete, but we can't call it definitive either. The biggest question, for me, is where each side of the codec *fails*, in that something from Excel or another major system doesn't load, or can't load our output. That's the reference standard, for better or worse.
rebolek
09:28@endo64 re: quotes - I guess that a good compromise would be that /qoute refinement would enforce quotes for each value, so to-csv/quote [1 2 3] #"'" would result in {'1','2','3'}, what do you think?
10:22Re: newline - IIRC Munge is doing it, so I did the same to pass the Munge test suite. But maybe it can be left out, adding newline is probably easier than removing it :-)
greggirwin
16:14On /quote, the doc string says Use different character for quotes than double quote ("), which says to me that the alternate char is used, but doesn't change the behavior. If we make the refinement mean both *change* and *force*, you can't get the current behavior with an alternate. That may not be an important use case, but it will be a breaking change later if we learn we're wrong. And since it will break data generation for people, we should avoid that if at all possible.

@rebolek, did we talk about having /with take a block or map, to allow specifying both the delimiter and quote values? You could include just one, if that's all you want to override. That leaves /quote to turn quoting on, where it then applies to *all* fields.

For newlines. §2.2 says: "The last record in the file may or may not have an ending line break."

I'm OK with how it is now, trim/tail isn't so bad, but another thing we could do (which needs more thought) is add a refinement to to-csv-line to omit the newline. People can then call that directly. This gets more complicated, though, because to-csv configures the module level quote chars. Dealing with concurrent codec configs is another matter.
rebolek
16:34@greggirwin
16:38> it would be breaking change

Yes, it would. But we are still in alpha stage so breaking changes are expected. And the sooner we do them, the better. But your /with proposal is also interesting. I need to do some testing, but it seems like the way to go.

Newline and to-csv-line - it's not a problem to add a refinement, what's more interesting is to decide what behavior should be the default. I vote for having newline as default and adding /only or something similar to override it.
greggirwin
16:54My concern isn't breaking things now, but changing it, then deciding in a year or two that we shouldn't have.

I thought of /only, but it has a different standard meaning. If we keep the newline, and tell users to use trim/tail, adding a refinement later won't break anything. @endo64's use case is the key. If it turns out that people want to create single CSV lines on a regular basis (say 10% of the time), we want the CSV API to make that easy to do.

We can also profile string vs block scenarios. @endo64, did you try preallocating space in your string buffer, to see how much difference that made in performance?
rebolek
17:03/only was a first guess, maybe /trim would be better?

I also don't want to change stuff in the future. So I think that currently, user feedback is crucial so we can finetune the design.
greggirwin
17:14/trim opens more questions, in how it relates to the trim func. If someone wants to do this, and wants a shorter func than trim/tail, they can wrap that. But we should maybe revisit trim's default behavior, which is not entirely intuitive when it comes to newlines. That is, /tail considers NL whitespace, but trim alone does not.
rebolek
17:27to-csv/tail looks strange and not self-explaning IMO
greggirwin
17:27I meant trim/tail, sorry.
rebolek
17:28I understand, but what refinement do you suggest to omit newline for to-csv?
greggirwin
17:29I think no refinement for now. They can do snip: func [val [string!]][trim/tail val] easily enough.
17:30And adding a refinement later doesn't break anything.
luce80
17:46@greggirwin :point_up: [April 19, 2020 10:34 PM](https://gitter.im/red/help?at=5e9cb5c60480c128efcf5939) How did you defined your local environment? I think I'd like to define one too.
greggirwin
17:47...\red.exe --catch user.red shortcut and put code you want to load in %user.red.
GiuseppeChillemi
19:48I would like to create an "explosive" word, a trap, something that once used as argument for a function it will "explode" and stops the program flow but if encountered all alone it will do nothing. This because sometime, when building nested code parts I miss an argument and what follows it becomes an unwanted argument and would have a way to discover this.

The following program code explains in very simple words what I am saying.

If I repeat executing the f function 2 times but I forgot the second argument of the first one, the code still runs, it outputs code which could seem correct (4 numbers) but they are wrong because I

>> a: 10
== 10
>> b: 20
== 20
>> f: func [arg1 arg2] [probe arg1 probe arg2]
>> f a b f a b ;<----- correct!
10
20
10
20
== 20
>> f a f b a ;<------ without an argument
20 <
10 <
10 < Wrong number but you can't know this
10 <
== 10
>>


To be sure nothing is executed and all arguments have been used on a particular point of the code I would like to write:

f a check-stop f b a

If check-stop becomes an argument of a function the program will stop, otherwise it will be used as a neutral word and nothing will happen (just like a comment, a string or a block).

19:50Is there a way to create this functioning with existing Red elements ?
endo64
23:10About to-csv topic: I don't think a refinement is necessary for trim/tail.
I just checked, to-csv in my user.r doesn't accept a block of blocks, just produces 1 line of CSV, so it is more limited then the @rebolek 's version.
GiuseppeChillemi
23:14Is there a way to have a selective Bind where you bind only some words of a block to a target context and not all the words that are in the context ?
endo64
23:17In my opinion, whitespace is perfectly fine in a value unless there is newline or delimiter character in the value, no need to auto-quoting.
23:19> @endo64 re: quotes - I guess that a good compromise would be that /qoute refinement would enforce quotes for each value, so to-csv/quote [1 2 3] #"'" would result in {'1','2','3'}, what do you think?

I agree on that, if there is /quote then I expect all the values will be quoted.
greggirwin
23:24@GiuseppeChillemi, try writing your own selective bind and report how it works.
endo64
23:26For to-csv, I propose below refinements:
/with  => Quote char to use
/quote => Force quoting
/delim => Delimiter to use


greggirwin
23:29Hmmm, my gut says delim is the thing you'd override before the quoting char, so is a better fit for /with, and if we don't auto-quote, then does /with imply /quote? I'm leaning toward a rich /with arg, which could be defined just once, making all calls cleaner.
23:31It's also a question of how much flexibility we need. If we intend for this to be the only CSV API people ever need, it has to be flexible. If it works with Excel, and what Ashley has in munge (which I think @rebolek tested against), are other cases rare enough that we can keep it simpler?
23:33On auto-quoting, it's a question of which works more reliably across systems. If unquoted works just as well, we can go with that. If auto-quoting makes it even 1-2% better, it's worth keeping.
endo64
23:34I'm for not too flexible (and bloated) internal CSV functions, but changing delimiter and quote char is OK to have.
GiuseppeChillemi
23:37Please forget about my question, I have found Hiiamboris Redbind script he have me time ago.
greggirwin
23:47An advantage of refinement args is that they can be typechecked. If we do something like this, the checking is an extra step (which comes back to dependent types :^):

/with
	spec [block! map!] "delimiter: [char! string!] quoting: [off | on | auto] quote: [char!]"

endo64
00:04/with spec is cool but not sure if it is, for supposed to be a simple function.
I also think that auto quoting can also be removed, some CSV exporters don't do that, it is the responsibility of the loading function.
00:07load-csv already has more than I expect (records, column mode etc.)
greggirwin
00:10I don't think we can say it's a simple func, since even the RFC doesn't nail down a hard spec. :^\ It's a messy area, unfortunately.
00:12It's the most important data interop format there is, though JSON is close, and it's ill-defined. Excel compatibility is 95-98% of the battle. But, oh, that 2-5% is still a lot of data.
endo64
00:13I mean the to-csv function, even without object and map support, could be enough useful.
greggirwin
00:16But that's all about round-tripping. If you can load data into a structure, the ability to just save that structure back out is *really* nice.
endo64
00:18Right, and we already have it now.
greggirwin
00:22I pushed for that flexibility, even though we *could* do that part in other mezz funcs. The extra code is not that much, and gives us some small gains in efficiency. More importantly, to me, as with round vs [ceil floor trunc ...] is clarity of intent. Blocks-to-records or blocks-to-columns then need counterparts, and still need extra information because CSV data may have headers or not.
00:24Only time will tell how much each format gets used, which will be great to know if we can gather stats on that.
xqlab
08:22I would prefer the separate refinements proposed by Endo to the proposal of with with block as argunent
bubnenkoff
14:25Is there any way to clean all data from console without it's restart?
hiiamboris
14:28Ctrl+L
bubnenkoff
14:30Thanks, but what about words that already loaded in current session?
hiiamboris
14:32Do these words bother you?
bubnenkoff
14:55Because I am not totally sure that I am getting actual data, but not previous result
hiiamboris
15:01You can start your session by defining your own function like:
forget: does [unset find/tail words-of system/words 'forget recycle]
and then call it any time to clean the mess you made and also free the unused memory.
dockimbel
16:06@hiiamboris Nice little resetting function. @greggirwin Should we include that in the console's boot sequence?
meijeru
17:48Here is something I can't figure out from the docs: if I drag a face over to another face, and I drop it, the drop event is generated in the dragged face, not the destination face, and the event/offset is relative to the dragged face. How do I find out _where_ the face has been dropped? I mean, the identity of the destination face and the offset of the drop relative to _that_ face?
toomasv
17:54@meijeru See, if [this](https://gist.github.com/toomasv/12a3a1781bc42f23a418aa888be3065b) is of any help. Drag small square into panel and drop. Double-click to get it out.
giesse
20:22@hiiamboris that clears any *added* words but what if one somehow overwrites find or something like that. So I'd say that right now the only way is to restart.
hiiamboris
20:24Well, you can unset words-of system/words for one way to destroy the world ;)
20:25I think the idea here is to clean things up, rather than rescue the broken console :)
20:28I'm using the same approach in my View test system to clean up after each test, to lessen the influence of possible remaining values from old tests onto the new tests.
meijeru
20:34@toomasv Got it!
greggirwin
20:44@dockimbel @hiiamboris @giesse let's broaden the thinking just a bit. In R2 I had a functions called mark-my-words that I used to track down word leaks. Same vein, different goal.
>> ?? mark-my-words
mark-my-words: make object! [
    init: func [][query/clear system/words]
    dump: func [/local val][
...
>> mark-my-words/init
...
>> a: 1  b: "test"
== "test"
>> mark-my-words/dump
Word     Type    Value
a    integer     1
b    string      "test"

These types of functions are useful in more than the console, so let's think about them in the context of tooling and debugging.
hiiamboris
20:58Nice name :D
greggirwin
21:21:^)
21:28I haven't done much with my old Object Browser, but for those familiar with Smalltalk, it was kind of like that. In the original, Celeste Mackert and I also had a set function, so you could tinker with the state of the system. This is, naturally, a dangerous thing to allow, but can also be very nice viewed in other ways. Values in the system are like living, embedded config settings. With a helper system, you can also put custom UIs over them.

giesse
05:51@greggirwin we don't have query on objects in Red though, do we?
05:53IMHO it would be useful to both have a reset native that just... reboots the interpreter, and a way to track changed words like R2's query (which was born as a hack but I think it was useful enough to consider). (And, of course, protect, but I think that's in the pipeline already.
greggirwin
08:03Protect is in the pipeline, and we don't have query on objects. I was just posting the old R2 stuff as an example, with the implementation being...just there.
dockimbel
10:14@giesse I can give a quick look at query later today.
Oldes
14:34@dockimbel I wonder if query/clear on objects is the right name for such a purpose.
hiiamboris
14:51I tried to figure out what it might possibly do (without digging up the docs), but unsuccessfully ;)
cloutiy
16:04I'm trying to make an operator += to be used like a += 3. My initial approach was to create a function increment: func [ a b ] [ set a (a + b) ] then +=: make op! :increment. But There are some pieces here that I'm not understanding 100% of how to bind the word! on left hand side (a) using the set.
meijeru
16:24You need to do increment: func ['a b][set a (get a) + b] This will prevent a from being evaluated before the call, and then get a will retrieve its value.
cloutiy
16:29@meijeru thanks for your explanation. I had tried increment: func [ a b ] [ set 'a (a + b) ] but of course this wasn't working either. I knew I had to prevent the evaluation of a but wasn't doing it in the right place.
greggirwin
18:02@Oldes query/clear might be OK as a name. What's lacking in R2 is any indication of what it does.

I can't find notes on the recent chat about query, but the design should come first in any case, related to how it access external information, while reflect produces internal information (but doesn't expose it directly) and face accessors (*-face*) did things another way in later R2 VID.
18:04http://www.rebol.com/docs/changes-2-6.html#section-14
18:31Ops with literal left args are problematic: https://github.com/red/red/issues/3344
cloutiy
19:51@greggirwin Thanks for the link Gregg. Yes I noticed I was still getting some errors despite trying @meijeru 's helpful suggestion.
giesse
20:06@greggirwin @dockimbel I don't think query is the best name for it, I think it was just the most convenient way to do it back when it was added to R2 - and it wasn't added by Carl. (Carl didn't even remember it was there last time we talked about it - he was surprised it even worked.) reflect would make more sense but then of course there's the question of how to "clear" the "modified bit".
I'd probably generalize the whole thing with all words in a context having a number of flags, like "protected" or "modified" and so on. Might extend into instrumentation and debugging etc.
greggirwin
20:17In brief thinking and searching, I haven't come up with a better word. Different (e.g. inquire) but not better. Accessors used a get/set model. It would be nice to unify this.
hiiamboris
20:20"modified" can have only one listener though.
Oldes
20:33Maybe it is work for evoke http://www.rebol.com/r3/docs/functions/evoke.html
20:35Hm... maybe not.
dockimbel
20:35@giesse I was thinking about using reflect/modify actions for that. modify is already used as a counter-part to reflect.
Oldes
20:36Anyway... I feel that query/clear is bad.

giesse
06:08is modify documented anywhere?
spTorin
06:54Hello. Trying make simple VID app. Make style node and create two object with this style. How I can change some properties in one node (by click button), for example text for header in DRAW block?
Red [Needs: 'View]

win: layout [
    size 400x500
    across
    style node: base 100x60 transparent draw [
        fill-pen blue box 5x5 95x55 5
        fill-pen yellow circle 5x20 5
        fill-pen yellow circle 5x40 5
        header: text 20x15 "HEAD"
    ]
    b1: button "test" [probe node0]
    node0: node loose
    node1: node loose
]

view/no-wait win
toomasv
07:21@spTorin One possibility:
i: j: 0
win: layout [
    size 400x500
    style node: base 100x60 transparent draw [
        fill-pen blue box 5x5 95x55 5
        fill-pen yellow circle 5x20 5
        fill-pen yellow circle 5x40 5
        text 20x15 "HEAD"
    ]
	below
    b1: button "test1" [change skip find node0/draw 'text 2 rejoin ["HEAD-" i: i + 1]]
    b2: button "test2" [change skip find node1/draw 'text 2 rejoin ["HEAD-" j: j + 1]]
    return across
    node0: node loose
    node1: node loose
]
view win
spTorin
07:30A little difficult... but this worked, tnx!
It would be great to do this like node1\text: "New text"
planetsizecpu
07:42Maybe you can play a bit with b0: button "test" [alter last node0/draw ... ] but it's a bit sticky


pekr
07:46Wanted to try with, seems to work nicely. The question though - why does the box have the outline? Do I need to run off pen first?

view [base 200x200 draw [fill-pen green box 5x5 195x195] with [color: white]]
planetsizecpu
08:06> A little difficult... but this worked, tnx!
> It would be great to do this like node1\text: "New text"

In fact you can do it, but it is partially covered by the blue box.
toomasv
08:24That's because the draw is displayed upon face's text. Set fill-pen to glass and give node a text, then you can change this text by node/text: ...
spTorin
08:33Maybe I originally did the task wrong? What is required: several types of nodes are needed - server, database, telecom. Place several instances of each node in the window. Have the ability to change the color and text on the objects by the events. Simple SCADA.
planetsizecpu
08:51Maybe you can make the blue box a bit small to leave room for viewing node/text that belongs to base

dockimbel
09:02@giesse Nothing so far beyond the action [definition](https://github.com/red/red/blob/master/environment/actions.red#L74). It's defined for object!, port! and series!. You can search for modify: in the source code. I consider it experimental so far, though it's already used at mezz level in View.

GiuseppeChillemi
09:33Is there any way to have a GUI Window "always to front"?
ralfwenske
09:34@spTorin How about a function based on @toomasv ' s solution:
b2: button "test1" [node-text   node1   rejoin ["HEAD-" i: i + 1]]
]
node-text: function [n [object!] s [string!]][
    change skip find n/draw 'text 2 s
]

09:37I’ve got a question regarding area:
how can I scroll text inside an area after appending lines so the last line is visible (through code)?
toomasv
09:39@GiuseppeChillemi Use modal flag for window. But then you cannot set focus on other windows of this session until you close the modal one.
spTorin
09:42@ralfwenske Yes, with function looks better. Or just remove draw section and use plain base face.
toomasv
09:44@ralfwenske area's scroller, being native, cannot be manipulated programmatically. At least on Red level. Probably it can be manipulated on system level, I haven't tried. (But you can cheat and jump text's index away from head by lines. This would not adjust scroller though.)
ralfwenske
09:51Thanks @toomasv - that would be way beyond my abilities. Could we perhaps simulate a key entry (may be cursor down) into the area?
Yeah, text index would be sufficient (thinking about logging events - so the cursor doesn’t matter much).
How do I change the index?
toomasv
09:58
i: 0 
view [
   a: area "" below 
   button 80 "Add line" [
      append a/text rejoin [{line } i: i + 1 {^/}] 
      if i >= 10 [a/text: find/tail a/text newline]
   ] 
   button 80 "Top" [a/text: head a/text]
   button 80 "End" [j: i - 9 loop j [a/text: find/tail a/text newline]]
]
ralfwenske
10:02That does it - thank you very much !! @toomasv
toomasv
10:04You are welcome :)! (Added a line ^)
ralfwenske
10:22Works fine for my purpose - I don’t need the buttons.just to let you know: hitting the 'End' button twice seems to set a/text to none. Inserting
if empty? a/text [a/text: ""]

before append … seems to prevent crashing though and magically :) all the lines are still there...
10:35I am guessing that a/text then (after hitting 'end' a few times) points behind the end of the series (a/text) and setting it to "" then returns "" rather then 'none ?
toomasv
10:37Ah, yes, sorry! You can use if found: find/tail a/text newline [a/text: found] there, to make it safer.
dockimbel
18:42@giesse Added query-like feature in the fast-lexer branch https://github.com/red/red/commit/05f996354ecc28eb8bd8ceafd5181126ba1a76b6:
>> obj: object [a: 1 b: 2 c: 3]
== make object! [
    a: 1
    b: 2
    c: 3
]
>> obj/c: 99
== 99
>> reflect obj 'changed
== [c]
>> modify obj 'changed none
== make object! [
    a: 1
    b: 2
    c: 99
]
>> reflect obj 'changed
== []
>> obj/a: 124
== 124
>> obj/c: -1
== -1
>> reflect obj 'changed
== [a c]
bubnenkoff
18:46@Oldes could you help me with your SQLite driver?
I need to select data from one db and insert to another. I looked at driver sources and it's support switching DBs: SQLite/do [use db2]

But what is the correct way of using it? I tried to do something like:
SQLite/do [use db2]
    sqlite/query {INSERT INTO "notice_fz44" ("purchaseNumber") VALUES ('1');}
    SQLite/do [use db1]


But it's stop working after first insert and tnah I am getting out of memory error. So I suppose that there is should be way to specify DB in sqlite/query. I looked sources but I did not understand how to do it
Oldes
21:26@bubnenkoff I'm not sure I can help you.. it was just a proof-of-concept for me... I actually never used it in real life... also your snipped is too short.. it should look somehow like:
; open 2 databases

SQLite/do [
	db1: open %test1.db
	db2: open %test2.db
]

; get some data from db1
result: make block! 32 ;preallocating block for results

SQLite/do [
	use :db1
	result: exec "SELECT * FROM Cars ORDER BY name"
]

; process the result...
; put some data info db2

SQLite/do [
	use :db2
	exec {INSERT INTO "Cars" VALUES(null,'Hummer',null);}
]

; close databases when done

SQLite/do [
	close :db1
	close :db2
]

; release resources if no mome SQLite needed

SQLite/free
21:28But as I said.. it was not supposed to be production ready, just something which may be used for proper implementation.
21:29I mean the Red part of it... the Red/System part (SQLite3.reds) should be full binding, which may be used for the higher level (Red) implementation.
21:41@bubnenkoff if above does not work (if I don't count that the databases must have valid tables), than is something broken. The script is from year 2017!
21:44The line with result: make block! 32 ;preallocating block for results could be removed as [there is internal buffer in the context](https://github.com/red/code/blob/02d4263ff117fc8a75341d90e168d74babf81c9c/Library/SQLite/SQLite3.red#L427-L428)
21:48And theoretically (without testing here) it should be possible to add something like:
query-db: func[
		"Executes SQL query with specified DB"
		db  [handle!]
		sql [string!]
		/into result [block!]
	][
		unless into [result: clear head output]
		do compose [use (db) result: exec (sql)]
		result
	]
21:49But that is just a wrapper for SQLite/do [...]
21:52Also this:
SQLite/do [
    use :db2
    result: exec {INSERT INTO "notice_fz44" ("purchaseNumber") VALUES ('1');}
    use :db1
]

is same like:
SQLite/do [use db2]
    sqlite/query {INSERT INTO "notice_fz44" ("purchaseNumber") VALUES ('1');}
    SQLite/do [use db1]
21:53just more efficient, because you are calling the internal routine just once.

ralfwenske
02:16Red 0.6.4 for macOS built 17-Apr-2020/13:50:14+10:00 commit #ca0a2d5
Red []
do-quit: does [
    res: false
    view/flags  [
        title "test-window.red"
        text "Quit?" return 
        button "OK" [res: true unview] 
        button "Cancel" [res: false unview]
    ][modal popup]
    res
]

view/options [
    title "Test"
    size 400x400
    button "Quit" [if do-quit [unview]]
][
    menu: [
        "File" [
            "Quit" doquit
        ]
    ]
    actors: context [
        on-menu: func [f e][
            if e/picked = 'doquit [if do-quit [unview]]
        ]
    ]
]

When clicking the 'Quit' button the popup dialog works as expected
even though when hitting 'Cancel' the dialog closes but the main view does no longer have focus.
1. How can I activate main view via code?

When clicking on 'Quit' in the menu the popup shows but after clicking 'Ok' or 'Cancel' I get:
*** Runtime Error 95: no CATCH for THROW
*** at: 0001F3F9h

2. What am I doing wrong?

Does it work on Windows?
toomasv
04:12@ralfwenske Give name to some face on main window and then use set-focus on cancel-actor, e.g.:
;popup
button "Cancel" [res: false unview set-focus b]
...
;main
b: button "Quit" [if do-quit [unview]]
...

On Windows menu works as expected.
ralfwenske
06:18Thank you @toomasv Must be a Mac issue: the 'set-focus' works - but whatever the focus is set to can only be seen after clicking somewhere on the window area . Worth a bug report? Actually one for each issue?
toomasv
06:23> Worth a bug report? Actually one for each issue?

I think yes.
07:13@ralfwenske By "menu works as expected" I meant that there is no error generated as you report above. But if you don't explicitly set focus to some face on main window, the main window loses focus on Windows too (I made the remark on your issue also.)
bubnenkoff
07:53@Oldes big thanks for explanation. I will try right now
07:53How to get specified date format?
>> now/date
== 28-Apr-2020

But I need: 2020-04-28
ralfwenske
08:00@toomasv Thanks for clarifying - I have removed (macOS only) from the headline
toomasv
08:01:+1:
08:03@bubnenkoff Seek [here](https://github.com/greggirwin/red-formatting)
ralfwenske
08:16another option diy
>> y-m-d: func [d [date!]][rejoin [d/year "-" next form (100 + d/month) "-" next form (100 + d/day)]]
== func [d [date!]][rejoin [d/year "-" next form (100 + d/month) "-" next form (100 + d/day)]...
>> y-m-d now
== "2020-04-28"
>> y-m-d 2-Dec-2020
== "2020-12-02"
GalenIvanov
08:30@ralfwenske Nice! I've always used the longer pad/left/with d/month 2 #"0"
08:39I have a question about dates: in the [documetation](https://doc.red-lang.org/en/datatypes/date.html#_block_to_date) it's written that when converting a block to date, "the argument block will be converted to a date! value according to the same syntax as for make". My experience shows that to-date accepts a block with 0, 1, 2 or 3 integers:
08:39
>> to-date [2020 4 28]
== 28-Apr-2020
>> to-date [2020 4]
== 31-Mar-2020
>> to-date [2020]
== 31-Dec-2019
>> to-date []
== 1-Jan-0000

08:40Am I wrong, or this is not documented?
08:42In fact to-date [y 3] where y is a year, is useful for finding the last day of February in the given year :)
meijeru
09:52Familiar question: bug or feature? According to the rules, one should first report this in red/bugs, before possibly creating an issue.
GalenIvanov
10:21@meijeru I hope it's a feature.
dockimbel
10:21@meijeru @GalenIvanov From top of my head, it looks like the missing date components default to 0, which results in giving the day before instead of the current intended 1st day. You can open an issue.
10:23@GalenIvanov You can still use a similar formula to find out the last day of February for a given year:
y: 2020
(to-date [1 3 y]) - 1

== 29-Feb-2020
GalenIvanov
10:25@dockimbel Thank you! Yes, I know - I have used this approach. I found the above mentioned behaviour while code-golfing :)
bubnenkoff
10:27
>> if [equal? "2" "1"] [print "equal"] 
equal

Why strings are evaluates as equal?!
dockimbel
10:28@bubnenkoff
>> if [] [print "A block is a truthy value!"]
A block is a truthy value!
>> to-logic []
== true
10:30All values are considered true except for false and none.
bubnenkoff
10:30My mistake!
10:55@Oldes I have more simple problem now. The processing of updating data in DB stops in sqlite/query.
I am running it in foreach loop. The code is here https://gist.github.com/bubnenkoff/80fdbf30ab91ace455d467fe4cba5c42#file-app-red-L42

if line SQLite/query sql-query present in code the single SQL request is execute than all stops like there is no more foreach loop. If comment this line and add simple print all works fine and I am seeing a lot of data print on console.
Oldes
11:18@bubnenkoff I don't know... as I said... it was year 2017 when I was playing with it... maybe you should try to probe sql-query to see, what you are trying to execute... and try to localize the issue in some simple case without need to hack with your project.
11:20To make it short... I don't know what is your id.
11:25And one **important** thing. As I said, the sqlite/query was just a short example. It was not meant to be used like that... note that [it is using internal buffer](https://github.com/red/code/blob/02d4263ff117fc8a75341d90e168d74babf81c9c/Library/SQLite/SQLite3.red#L427-L428), which is [reused in each call](https://github.com/red/code/blob/02d4263ff117fc8a75341d90e168d74babf81c9c/Library/SQLite/SQLite3.red#L452). You don't copy the results in your script! [Like here](https://gist.github.com/bubnenkoff/80fdbf30ab91ace455d467fe4cba5c42#file-app-red-L16)
11:29@bubnenkoff try to use:
db-result: copy sqlite/query generate-sql-for-processing
pekr
11:32Wouldn't it be better to simply call sqlite.exe via a calland parse results? Did so in the past and IIRC the query can stay hidden ...
Oldes
11:32and you can try to modify the sqlite/query to be like:
query: func[
		"Executes SQL query"
		sql [string!]
		/into result [block!]
	][
		unless into [result: clear head output]
		do compose [result: exec (sql)]
		either into [result][copy result]
	]
11:34@pekr using the binding (correctly) will be much efficient than using call where you pay for executable evaluation and complete sqlite initialization with each call.
11:37And again.. it was just a proof-of-concept. Everybody is free to use whatever want. I can imagine that the high-level could be much better using the possible routines from the low-level binding... like no need to use just plain strings for queries.
11:38Maybe when I will have a need to use some DB, I will review it. But so far I'm using plain data for my projects.
bubnenkoff
11:38@Oldes I understand that it's alpha stage, but I really do not know how to continue work without DB.
Look how it's like https://www.youtube.com/watch?v=fa1T_MpGW-4&feature=youtu.be

I tried Probe:
{UPDATE "xml_files" SET "processed_date" = '2020-04-28', "status" = 'success' WHERE "id" = '10155'}

I have not any idea why it's stop after single execute (yes I see sinle result in DB)
Oldes
11:42Sorry... I really cannot work on your project. Try to reproduce the issue with some simple script. Like the one [in the code repo](https://github.com/red/code/blob/master/Library/SQLite/SQLite3-test.red)
bubnenkoff
11:43ok, I will do it some simple project
12:17@Oldes can't reproduce error with simple project with foreach loop. I will try to debug my project. Very strange error...
12:17But big thanks again! Sorry that I spend so much your time
12:18I did not mind that something is wrong with my code because I thought this place can have any bugs
12:47Your examples really helped me! It's seems I found place were was an error:
https://gist.github.com/bubnenkoff/80fdbf30ab91ace455d467fe4cba5c42#file-app-red-L16

It should be db-result: copy sqlite/query generate-sql-for-processing. I am still not fully understand cases where copy is should be used, but here is good place for it
12:48And really again sorry that I spend so much your time. I was sure that the code is correct because print is worked
GiuseppeChillemi
22:00Is there a technical term to name the progressive availability of words during object building ?

>> context [a: 1 b: 2 c: a + b d: c + c]
== make object! [
    a: 1
    b: 2
    c: 3
    d: 6
]


C and D can be calculated because previous words are progressively available. How is called this characteristic ?
hiiamboris
22:07I think no one claimed the name so far, so it's yours to take ☻
GiuseppeChillemi
22:15Thanks, it's like discovering a new start. I will think on it ! :-)
22:15(No joke!)
23:43@hiiamboris here is my choice: *Progressive Availability on Building*(PAB) or just *Progressive Availability*.
23:46So one can say: "Contexts (objects) have progressive availability of their elements (members) during building"

cloutiy
00:08I see that load has a refinement /next. Could someone provide an example of its use?
dsunanda
00:57LOAD loads the whole of its target into a block:
>> load "1 2 3"
== [1 2 3]

LOAD/NEXT loads just the next symbol, and also creates a word with the rest of the unloaded target:
>> load/next "1 2 3" 'pos 
== 1
>> probe pos
== " 2 3"
GiuseppeChillemi
07:20@dsunanda I still have not understood which are the use cases. I have not found examples around.
xqlab
09:18You can load step by step. That's useful if you want to intercept and check e.g for security reasons and especially useful before the refinement /trap was available in debugging
hiiamboris
10:04@GiuseppeChillemi I think I gave you examples already, did you look at them? :point_up: [April 19, 2020 12:47 PM](https://gitter.im/red/help?at=5e9c1e4763e7b73a5fea3c06)
GiuseppeChillemi
15:46Yes, I have looked at them, I was searching for more ample usage examples.
toomasv
17:26@GiuseppeChillemi I used it a lot in [syntax-highlighter](https://github.com/toomasv/syntax-highlighter/blob/master/syntax-highlighting.red)
GiuseppeChillemi
18:32@toomasv Thanks !
hiiamboris
21:29
>> find series! integer!
== false

Interesting that find does not always return none on failure. I wonder if it's by design.
dockimbel
21:44@hiiamboris For sake of compatibility with R3. It makes it shorter to write the wrapper mezz functions for typesets:
>> probe :series?
func ["Returns true if the value is any type of series" value [any-type!]][
    find series! type? :value
]

Given the limited usage of typesets beyond the predefined ones using those wrapper functions, I don't think it matters much for end users.
hiiamboris
21:45It's better as false when I'm passing it to pick :)
Though someone's code using found?: func [x][not none? :x] will break
21:50I see the point. Though I disagree about "limited usage of typesets beyond..". I've used them a lot.
dockimbel
21:50I'm not against keeping findreturn value consistent with other types.
hiiamboris
21:51Tough choice as always ;)
greggirwin
21:53If it isn't consistent, we need to update the doc string. Consistency seems like a good idea here though. Even bitsets return none.
dockimbel
21:55While we are at it, why not allow find series! :value directly, so that when the second argument is not a datatype!, the type will be first extracted by find before searching it in the typeset?
greggirwin
21:56Do you mean only for find ?
21:58Or specifically find : (get syntax)?
hiiamboris
21:58Might make sense.
22:00What I'm really missing though about find and typesets, is find ;)
greggirwin
22:02Works for me @hiiamboris
>> b: reduce [any-word!]
== [make typeset! [word! set-word! lit-word! get-word!]]
>> find b any-word!
== [make typeset! [word! set-word! lit-word! get-word!]]
22:02Or do you mean the values *within* a typeset?
22:03e.g.
>> find [a b c 1 2 3] number!
== none
hiiamboris
22:04Same as find . A piece of R3:
>> find [a "b"] series!
== ["b"]       ;) == none in red
greggirwin
22:06So then you need an escape hatch, which may be what @dockimbel is leading toward. Otherwise you can't find typesets. That is certainly a less common case, but at least it's consistent in find. :^\
>> find reduce ['a "b" series!] series!
== ["b" make typeset! [binary! string! file! email! url! tag! image! vector! block! paren! path! set-path! get-path! lit-path!]]
hiiamboris
22:08I can!
>> find reduce ['a "b" series!] reduce [series!]
== [make typeset! [block! paren! string! file! url! path! l

22:09Besides, you already need this hatch to find datatypes.
greggirwin
22:10Nice. But I don't see the need for datatypes' escape.
>> find reduce [integer!] integer!
== [integer!]
hiiamboris
22:11
>> find reduce [1 integer!] integer!
== [1 integer!]

;)
22:12Another hatch may become find/same but I don't like "exceptions to exceptions" way in design :D
22:14What you've shown me just makes search by datatype unreliable in unknown data :/
That means I can't use it as optimization, so I will have to make an extra check that what I found is not a datatype.
22:15And an extra check for that check that I've been searching by datatype not by value :/
22:15parse will save us from this mess.
greggirwin
22:23Ah, I see.
22:23I think parse is the answer here. Find is its simple cousin. :^)
hiiamboris
22:24> While we are at it, why not allow find series! :value directly, so that when the second argument is not a datatype!, the type will be first extracted by find before searching it in the typeset?

One drawback I can see is when you forget to reduce your datatype:
>> find series! first [string!]
*** Script Error: invalid argument: string!
*** Where: find
*** Stack:

An error thrown helps detecting this possible bug. Without it, one may lose a lot of time, trying to figure out that it's actually looking for word!
greggirwin
22:25As with some other constructs, and why type?/word exists.
hiiamboris
22:25Indeed.
22:41I think it's worth it. Not the syntax improvement, but speedup obtained by removing an extra type? call, is definitely worth it.
22:45@dockimbel would it not be possible to become able to make op!s not only from binary functions, but also binary functions with refinements (op will just not use those refinements)? E.g.:
make op! :append
make op! :find
etc.

dockimbel
09:46find has not been implemented yet. find implementation is already quite overloaded, we'll see how to achieve it. A wish ticket for that (including searching for a typeset) is welcome.
09:47> Do you mean only for find ?

That one, yes.
hiiamboris
13:22> find has not been implemented yet.

has been. has been not.
dockimbel
14:27@hiiamboris Thanks for correcting me.
hiiamboris
14:44> A wish ticket for that (including searching for a typeset) is welcome.

It's 1.5 years old ;) https://github.com/red/REP/issues/29

greggirwin
15:19If @dockimbel approves, is that a ticket you want to handle @hiiamboris ? After sleeping on it, it does make sense to work that way for typesets if it works that way for types.
hiiamboris
15:50I don't mind :) Let me just finish my mezz/HOFs work shortly
dockimbel
15:53@greggirwin @hiiamboris I think it's just about adding a couple of lines, I'm already giving it a quick try.
hiiamboris
15:54:+1:
dockimbel
16:45Done: https://github.com/red/red/commit/f34004142a679c996ee93c5ce3531d36defc4380
greggirwin
17:00Works great! :+1:
dockimbel
19:49Good, if you have some test code to share, I could use them. I'm writing some unit tests for it right now.
hiiamboris
20:00I've only had plans to use it in place of alternative approaches in mezzanines. Nothing ready.

GiuseppeChillemi
15:30I am searching for a way to have a comment even between a function word and its arguments on the same line. Do you have solutions?
toomasv
15:46:smile:
>> f: func [comment arg1 arg2][print ["arg1:" arg1 "arg2:" arg2]]()
>> f "This is comment" 1 2
arg1: 1 arg2: 2
GiuseppeChillemi
toomasv
16:01
>> system/lexer/pre-load: function [src part][string: [#"^"" any [#"^^" #"^"" | not #"^"" skip] #"^""] parse src [some [remove " comm " string | skip]]]
== func [src part /local string][string: [#"^"" any [#"^^" #"^"" | not #"^"" skip] #"^""] parse src [some [remove " comm " string | skip]]]
>> find comm "Another possibility of including comments between func and args" "abracadabra" "abra"
== "abra"

GiuseppeChillemi
16:04@toomasv I have no knowledge on this part of Red, so I have to ask: would ^"string" be possible ?
toomasv
16:04:question: What'd'ya mean?
GiuseppeChillemi
16:05Having a comment in the form: ^ + like ^{I am a comment!}
16:07(Without COMM)
toomasv
16:13Didn't try if it is safe:
>> system/lexer/pre-load: function [src part][comm: [" ^^" string] string: [#"{" any [string | not #"}" skip] #"}"] parse src [some [remove comm | skip]]]
== func [src part /local comm string][comm: [" ^^" string] string: [#"{" any [string | not #"}" skip] #"}"] parse src [some [remove comm | skip]]]
>> find ^{I am comment} [1 2 3 4 5] 3
== [3 4 5]
GiuseppeChillemi
16:15Trying it !
toomasv
16:15Also
>> find ^{I am {nested} comment} [1 2 3 4 5] 3
== [3 4 5]
>> find ^{I am {nested} "and subquoted" comment} [1 2 3 4 5] 3
== [3 4 5]
GiuseppeChillemi
16:23It seems enough safe:

>> find [a ^{comment} b] {comment}
== none
>> find [a ^{comment} b] 'a
== [a b]
>> find [a ^{comment} b] 'b
== [b]
>> length? [a ^{comment} b]
== 2
probe load {[a ^{comment} b]}
==[a b]


It just won't let me manipulate it from the inside of Red code block. I have to read a source file as a string to do this.
16:30Ok I have found a problem:

>> probe {  xxxxx ^ ^{a comment} b}
"  xxxxx  b"
== "  xxxxx  b"

toomasv
16:33What is the problem here?
>> " ^ "
== "  "

One space missing?
GiuseppeChillemi
16:35No, ^ has been eaten.
16:36(The first one)
hiiamboris
16:36It's an escape char
GiuseppeChillemi
16:37^{ this is the start of the comment, ^ this is a simple char
hiiamboris
16:37> ^ this is a simple char

Nope

GiuseppeChillemi
16:38Yes, I know that in this implementation it is :) But Pre-lexer should consider comment start ^{ this combination.
hiiamboris
16:39https://github.com/meijeru/red.specs-public/blob/master/specs.adoc#526-char
meijeru
16:46Thanks for quoting me :smile:
endo64
16:48@GiuseppeChillemi Do you really need to specify comment that way?
>> f: func compose [(comment "this is a comment") arg1 arg2] []
== func [arg1 arg2][]
GiuseppeChillemi
16:59Thanks to everyone. I have still to learn a lot and you are all good teachers.
@toomasv The idea behind this request is boiling in my mind from the last year. Hope to assemble and show you what they are needed form sometime in the future. Thank you for having provided this other gem!
17:05@endo64
Yes as it should be possible to have them everywhere

>> f: func (comment "this is a comment")  compose [arg1 arg2] []
*** Script Error: func does not allow unset! for its spec argument
*** Where: func
*** Stack: f  

>> f: func ^{this is a comment}  compose [arg1 arg2] []
== func [arg1 arg2][]

17:09@toomasv To manage those comments in a block I thought about removing the pre-lexer but it is impossible to load a block with comment formed that way.

>> a: [ ^{this is a comment} ]
*** Syntax Error: missing #"]" at "^^{this is a comment} ]"
*** Where: do
*** Stack: load 
>>


Do you have any idea?
17:11(The best solution would be to have something valid with or without the pre-lexer)
hiiamboris
17:59@GiuseppeChillemi you do realize your code will become totally unreadable with *comments everywhere* approach?
GiuseppeChillemi
18:47@hiiamboris Not in my idea, the content of comments will act as a mark for positions inside the code, so you can LOAD and interpret the code without markers interference. My idea can be implemented at string level (with read) or block-level with load (after the lexer). @toomasv unblocked the doability of first part of the idea with his solution, when we will be able to make markers visible or "transparent" at block level by choice, then the second part of the idea could be implemented.
18:59(Find/marker Lenght?/marker append/marker or just a global switch system/options/marker-visible: true)
toomasv
20:00@GiuseppeChillemi

> To manage those comments in a block I thought about removing the pre-lexer but it is impossible to load a block with comment formed that way.

No, you can't manage these comments (as you can't manage ;... comments either) - they are not part of (loaded) language, as they are (or should be) stripped from code before loading.
If you do not use pre-load to strip them, your code/data becomes malformed and it should and it is good.
GiuseppeChillemi
20:32I know. Conditional transparency can't be achieved without a specific datatype recognized by the language but at this phase of my "life with red" your solution is enough.

greggirwin
03:38@GiuseppeChillemi, I think this is another case where a dialect is the way to go. Munging Red in general this way makes it incompatible with every other piece of Red in the world. You can do it of course, but then you can't easily share code or ask for help.
GiuseppeChillemi
07:58@greggirwin if the idea is a good one, there could be the option that it will be adopted by team and every Red in the world will be compatible. It's up to me to demonstrate it is a valid one.
greggirwin
20:55Yes. :^)
TimeSlip
20:56@greggirwin A few months ago you posted an error you were getting: Compiling to native code...
*** Warning: OS_TYPE macro in R/S is redefined
*** Compilation Error: invalid path value: image/extract-data
*** in file: %/c/dev/greggirwin/red/tests/android/datatypes/binary.reds
*** in function: red/binary/to
*** at line: 1
*** near: [1030x7
proto: image/extract-data as red-image! spec EXTRACT_ARGB
]
20:57I was just checking to see how much I could do with a Cross compile to Android and ran into the same. Any idea on how to fix that?
greggirwin
21:02The Android branch is out of date at this point, so first thing is to see if we have an open ticket for that on master.
TimeSlip
21:04OK, thanks.

TimeSlip
03:37Out of curiosity. Can one create the red.exe from the source files, and if so, how? I decided to check out the previous version 0.6.3 to see if the Android cross compile works. I did manage to find the .exe file but I was interested in knowing if I hadn't found it, could I generate it with those source files.
giesse
05:57There are two separate "exe"s, the interpreter and the compiler. The compiler is actually just an encapped REBOL script, so you need /SDK to generate that; there's not much reason to do it unless you for some reason want to redistribute the compiler (maybe after some changes?).
the interpreter is what is produced by the compiler by following the instructions in the README file, eg:

You can also compile the Red console from source:
>> do/args %red.r "-r %environment/console/CLI/console.red"


(that's from a REBOL console)
TimeSlip
05:59@giesse Thank you Gabriele.
pekr
06:20@TimeSlip In a similar way, you can generate Red/View GUI console. That's what I do all the time, so that I have environment, which feels similar to R2 console :-)

do/args %red.r "-r -t Windows %environment/console/GUI/gui-console.red"
TimeSlip
06:21@pekr Thank you!
bubnenkoff
18:31My friend got error ODBC32_SQLDrivers No ODBC drivers could be found. Check the settings for your libodbc provide (I do not know situation possible attempt to run Red on WINE). Does it mean that Red have support of ODBC connection?
endo64
23:09No ODBC support yet, probably will come after v0.7.0 or v0.7.1 release (ports).
Your friend is using a ODBC binding, this one may be: https://github.com/gurzgri/odbc-red

bubnenkoff
15:45What number of next planed release? Will be next 0.6.5 or immediately 0.7.0?
hiiamboris
15:500.6.5

TimeSlip
17:36Hello, have/could any of you compile and run the eval.red Android apk on an Android device? The already made one on the website works but I have had no success running my own compiled version. Yes, it compiles and creates the eval.apk file but when launched on an Android device, it says it is corrupted.
17:37
do/args %red.r "-t Android bridges/android/samples/eval/eval.red"

-=== Red Compiler 0.4.3 ===-

Compiling /a/bridges/android/samples/eval/eval.red ...
...compilation time : 551 ms

Compiling to native code...
...compilation time : 22574 ms
...linking time     : 474 ms
...output file size : 587976 bytes
...output file      : a:\eval.so
...generating apk
...signing apk
...aligning apk
...all done!
17:38BTW, I am compiling with the Android branch .
GiuseppeChillemi
21:49I have created a small GUI. It contains a field and a code which updates it to "World" clicking enter. I have written "Hero" inside the field which is immediately updated to "world" on enter. I expected this printing X but result is "hero"

x: "Hello" view [field x 100x20 on-enter [face/data: "World"]] probe x


"Hero"
== "Hero"


Why?
endo64
21:54
x: "Hello" view [field x 100x20 on-enter [insert clear face/text "World"]] probe x
"World"
== "World"
>> x
== "World"

GiuseppeChillemi
22:03So, the GUI element is tied to the X string and when I set face\text, I connect it to another string breaking the link, don't I?
hiiamboris
22:09Yes.
endo64
22:18Correct, face/text: "World" also wouldn't work as x and the new World strings are not the same anymore.
GiuseppeChillemi
22:32I think this "side effect" of updating face/text or face/data is worth documenting with a WARNING here https://doc.red-lang.org/en/view.html#_field. If you start editing the field from the GUI and PROBE x you see the expected result and think the result is mirrored in x content, if you edit from the inside you think you are setting the GUI element which also updates the X string... instead you change the connection! I admit that even working with Red from some time it has really been difficult to think about it correctly.

toomasv
04:02@GiuseppeChillemi It's just a difference between replacing something and changing it.
GiuseppeChillemi
05:53Toomas, the first thing I have thought has been that I was setting the field to a value and this value would have been propagated to the chained elements. Believe me when I say that once you see x: content changed when you enter a new value in the GUI, and you also you see that face/text: new value changes the GUI, you think that face/text: new value -> x: new value. If someone else falls in this hole and not just me, I think it is worth putting a warning.
06:02About fields and words content. So while a word is set to a string you can change it directly editing it in the GUI, but if the original content is a integer, you have to convert it to string, set it as field content and convert it back to integer once finished editing. Is it the correct way of doing things?
toomasv
06:24It is not specific to view. Consider:
>> x: "Hello" b: reduce [x]
== ["Hello"]
>> b/1: "World"
== "World"
>> x
== "Hello"

>> x: "Hello" b: reduce [x]
== ["Hello"]
>> head change/part b/1 "World" tail b/1
== "World"
>> x
== "World"

In first case you change first element of block replacing it with another string, in second case you change contents of the same string, not replacing it as a whole with another string.

About your second: Nope, it is not the correct way :) If you want to change the scalar type "backwards", you'll have to set it explicitly:
>> x: 1 view [field data x 100x20 on-enter [x: face/data]] ; set it to 2
>> x
== 2
GiuseppeChillemi
06:37Toomas, I know how series work but I admit I have thought there was a different mechanism here.
06:43Also thanks for the second answer. Face/data retains the original datatype and the data is converted to string to be edited in the field and back to integer after editing. So I have to use face/data to set the data source word.
toomasv
09:46Partially true. data is formed into field’s text, and field’s text is loaded into data, but data does not retain the original datatype.
GiuseppeChillemi
11:48I'll try it later when I will be back on my PC
13:39@toomasv This morning I have initialized the field to a number and then entered another number and found this datatype on face/data, for this reason, I have started thinking it retained the original datatype. Now I have tried again and yes, face/data is a pure and simple LOADing of face/text. It even converts to block!. I have enter (a)/b and found: [(a) /b] in face/data
toomasv
13:41@GiuseppeChillemi Yes, that's what it says in [doc](https://doc.red-lang.org/en/view.html#_field).
GiuseppeChillemi
13:44Exactly but sometimes simple explanations become complicate ones when mixing with our thoughts ;-)
toomasv
14:00:smile:
bubnenkoff
14:12I have file 123.txt and I want to remove spaces from end of every line:
first line 
second line  
third line

I wrote next code:
rr: read/lines %123.txt
foreach line rr [
	trim/tail line
]

write %321.txt rejoin rr


the problem that in result file I am getting all lines merged:
first linesecond linethird line

toomasv
14:19@bubnenkoff
lines: {first line^/second line^/third line}
print replace/all lines " " ""
firstline
secondline
thirdline

rebolek
14:19See help for trim: /tail => Removes only from the tail.
14:20Also, you are using read/lines and then rejoin. You loose newlines this way and trim/tail actually does nothing at all.
bubnenkoff
14:21@toomasv oh sorry< I forgot to mention about "end of" I edited post
14:21I did:
rr: read/lines %123.txt
foreach line rr [
	trim/tail line 
	line: append line newline
]
write %321.txt rejoin rr
rebolek
14:22From end, I see. Do something like collect [foreach line read/lines your-file [keep trim/tail line keep newline]]
14:23line: append line newline is same as append line newline as append modifies.
toomasv
14:33@bubnenkoff Another possibility is to use parse:
lines: {first line    ^/second line    ^/third line          }
parse lines [any [change [some space [newline | end]] (newline) | skip]] lines
== {first line^/second line^/third line^/}
endo64
15:22
>> lines: {first line    ^/second line    ^/third line          }
>> remove-each c lines [c = space]
>> lines
== "firstline^/secondline^/thirdline"

ralfwenske
08:37I have a layout
win: layout [400x300] react [do-my-own-resize]

If I want to limit the minimum and/or maximum size, how can I do that?
I tried setting the win/size, also returning 'false neither of which seem to work.
hiiamboris
08:44Not very elegant, but: view/flags [size 400x300 on-resizing [face/size: 400x300]] 'resize
08:45I don't think constraints are implemented. And on-detect doesn't help too (perhaps we can request that it stops resizing when the actor returns 'stop)
08:46If this doesn't work for you, please make a wish ticket at https://github.com/red/REP/issues
ralfwenske
10:01@hiiamboris Yes, returning 'stop could be the way - as I had thought returning 'false might do the trick. My size limits are determined in code and there might be a minimum and maximum, so your first suggestion doesn’t seem to do it. #73
GiuseppeChillemi
12:48I admit I expected 44. It seems the body of function is not bound to the object.

x: 22 
a: func [][probe x] 
m: make object! [
   x: 44 
   b: func [] copy body-of get in system/words 'a
]

>> m/b
22

hiiamboris
12:52Use compose or manually bind it, else it is first bound then built (and you have no literal func body to bind at bind stage)
GiuseppeChillemi
12:58I apologize but I have not understood the process. Could you explain increasing verbosity level ?

hiiamboris
13:03make calls bind, then evaluates the object's body. bind needs a block! to bind, but there's no block - only a couple words and a path: copy body-of get in system/words 'a
13:03Does this make sense? ;)
13:05What you want is to have a block there before bind is called - that is before make. For that you may use compose: make object! compose/only [...]
GiuseppeChillemi
13:08I think I have understood:

Make creates the context and binds the block to it then, it makes the remaining part of the work. At binding stage we have still no function body but just words to be evaluated.
hiiamboris
13:08Yes ;)
GiuseppeChillemi
13:13This partially ruined the beauty of reusing the same func body block with 2 specs: one when a function is defined outside an object and another when using it on the inside. In the latter case I omit the refinement and its words as they are already available in the context. I have to use the not so elegant compose! :(
hiiamboris
13:15If compose is ugly then bind copy/deep body-of :a self
GiuseppeChillemi
13:15So, self is available at building !
hiiamboris
GiuseppeChillemi
13:16T H A N K S !
hiiamboris
GiuseppeChillemi
13:23Your explanation has also answered a question about using the same word inside and outside the body of object:

x: 22 
a: func [][probe x] 
m: make object! [
  x: 44 a: func [] copy body-of :a
]

*** Script Error: body-of does not allow unset! for its value argument
*** Where: body-of
*** Stack: body-of


why I was not able to reuse the :aform in place of get in system/words 'a form.
hiiamboris
13:25:system/words/a is shorter
GiuseppeChillemi
13:26This is what happens when you put things in the wrong place. Thanks, now it works!
hiiamboris
13:29There's bind/copy btw, so no need to copy/deep the body
GiuseppeChillemi
13:34I see it deep copies by default.
13:42Difference between Red and Rebol:

x: 22 
a: func [][probe x] 
m: make object! [
   x: 44 
   a: func [] bind/copy body-of :system/words/a self
]

Red:
Ok

Rebol:
22
** Script Error: Cannot use reflect on integer value
** Near: make error! reduce [err-type err-id pick args 1 pick args 2 pick args 3]


It evaluates the function!
hiiamboris
13:45Yes, R2 has no get-paths.
13:45It's a huge annoyance
toomasv
15:19@ralfwenske This works on Windows, don't know about macOS (although auto-sync should be probably set to off)
view/flags [size 400x300 on-resizing [face/size: min 800x600 max 200x150 face/size]] 'resize
15:21Strange, Gitters seems to eat digits from start of pairs in above!
view/flags [size 400x300 on-resizing [face/size: min 800x600 max 200x150 face/size]] 'resize
xqlab
15:27in R2: a: func [] bind/copy body-of get in system/words 'a self
hiiamboris
15:54@toomasv doesn't work on W7. with autosync: off has no effect at all. With on, a lot of flickering
toomasv
greggirwin
16:23On @ralfwenske's issue, do all OS's support min/max window size limits. I know Windows does. It would be a nice feature to support, and should be easy enough.
ralfwenske
23:27@toomasv Thanks.
On macOS - using your suggestion - the window shows the resize cursors but the view does not change size at all.
On GTK I can resize the view without any limitation. @greggirwin
Btw. in my code sample in #73 I attempted to change the face/size to as-pair maxsx maxsy before returning.
Replacing clear d4/text d4/text: copy rejoin [as-pair maxsx maxsy " LIMIT!!!!"] shows the correct limited pair. Why can’t I change face/size?

toomasv
04:43@ralfwenske Did you use show face after you set auto-sync: off (i.e. if you did set it off)?
ralfwenske
04:57I don’t know about auto-sync :) @toomasv - and I don’t use show face.
btw. I just observed (with your one-liner from above) on macOS when I attempt to resize on the top or left border (seeing the resize-cursor) the window is being dragged along.
bubnenkoff
11:20is the any way to increase font size in all app?
toomasv
12:54@ralfwenske Here is workaround (at least for W10) :)
view [
   size 400x300 
   at 390x290 base 10x10 cursor 'hand loose 
   on-down [system/view/auto-sync?: off] 
   on-up [system/view/auto-sync?: off] 
   on-drag [
      face/offset: max 290x190 min 590x390 face/offset 
      face/parent/size: face/offset + 10 
      show face/parent
   ]
]
greggirwin
18:07@bubnenkoff I thought setting system/view/VID/default-font/size would do it, but it seems not. @dockimbel @qtxie @%VID.red:L423-437 looks like at least some font setting has to be set for a face, for @L434 to be applied. I know some changes were made for style font application a while back.
18:12I don't think it's a regression, just never worked that way.
ralfwenske
21:39@toomasv Phantastic! Very helpful - and now I know what auto-sync? is good for…
Thank you. …so much to learn…
I learn best when converting an idea into something that works - going through more or less complicated code - yet detecting all the little niggly things related. And then the help in form of specific examples - as You and others so generously provide - is the icing on the (delicious) Red - cake :cake:. :) :thumbsup:
hiiamboris
21:43works on W7 btw ;)
great idea to make your own resize control!
ralfwenske
21:50Also on macOS and GTK Linux! :thumbsup:

qtxie
02:40> I don't think it's a regression, just never worked that way.

Yes. system/view/VID/default-font is a read-only property for now.
toomasv
02:43@ralfwenske @hiiamboris :smile:
10:52Oops, typo on-up [system/view/auto-sync?: on] :flushed:

bubnenkoff
18:20I want to write function that parse value and then return result or message "unknown".

Should I simply write if/either for every possible case or should I use try-catch?

parse filecontent [<id> copy scheme-name to "<id>"]
		either value? 'scheme-name ; check if scheme-name was set 
		[
			parse scheme-name [remove to "<" thru ">" remove to end] ; some other manipulation
			
			either (length? scheme-name) > 0 ; check again
			[
				scheme-name
			]
			[
				"unknown-scheme" ; ditto
			]
		]
		[
			"unknown-scheme" ; ditto
		]


Could this code be simplified?
dockimbel
20:03@bubnenkoff
scheme: none
parse filecontent [<id> to #"<" copy scheme thru #">"]
either any [none? scheme empty? scheme]["unknown-scheme"][scheme]
hiiamboris
20:39empty? contains none? though ;)
dockimbel
21:34@hiiamboris Good point. I'm too used to the Rebol version. ;-)

rsheehan
00:28How can I replace both set-words and words in a block as in the following example?
f: [a: a + 1] replace/all f 'a 'b
greggirwin
02:17You can do something like this:
change-words: func [
	blk [block!] "(modified)"
	old [word!]
	new [word!]
	/local w
][
	parse blk [
		any [
			pos: any-word! (
				if pos/1 = old [
					change pos make pos/1 new
				]
			)
			| skip
		]
	] 
	blk
]
f: [a: a + 1]
change-words copy f 'a 'b
02:18Holler if you want anything explained. Sometimes we'll just give hints in answer, other times examples for you to tease apart.
02:21Here you have the concepts of set-words in parse, change, equality testing for words, and make.
rsheehan
02:39@greggirwin Thanks, that is very helpful.
loziniak
16:22Hi! Is it possible to do an animation in parallel to some heavy calculations, like in this code:
Red [Needs: 'View]

view [
	ticker: base on-time [print [now/precise]] ; a visual effect could be displayed instead
	button "rate" [
		ticker/rate: 10
		wait 3.0 ; some heavy calculations
		ticker/rate: none
	]
]
hiiamboris
16:29You'll have to flush View events periodically during your heavy math
16:31
view [
    ticker: base on-time [print [now/precise]] ; a visual effect could be displayed instead
    button "rate" [
        ticker/rate: 10
        loop 30 [wait 0.1 do-queued-events] ; some heavy calculations
        ticker/rate: none
    ]
]
16:31https://gitlab.com/hiiamboris/red-mezz-warehouse/-/blob/master/do-queued-events.red
loziniak
18:35Thanks!
18:38Unfortunately, these "calculations" are mostly external to my code. I'd have to stick with something static.
greggirwin
19:08Red is single threaded, but maybe you can use call, having results written to a file, and poll that file in your Red app.

GiuseppeChillemi
07:41I have dilemma in chosing a coding style for passing data between functions. When creating VID panels I pass around a context which includes VALIDATION tables, COLUMNS specs, FIELDS configurations. Child functions needs other data like object FIELD to update and the object itself. I have 2 approaches: putting them inside the context with MAKE CTX [field-name: value obj: myobject] and pass it to the functions like UPDATE-FIELD ctx which will be ARITY 1, or have the context separate separate and call the function as UPDATE-FIELD field-name value ctx?
Which one And why ?
hiiamboris
08:17when in doubt, do what looks more declarative and readable ☺
GiuseppeChillemi
09:37I am pro verbosity of code, because if your are not verbose there you have to be in comments. But also you can't charge a command line with 6/7 elements. I think That a good mix is represented by the latter option where more static structures are passed in a context and words that are often used to explain what is happening and / or are passed as standalone arguments.
greggirwin
15:20Consider that if you pass the field name, that acts as documentation for what field update-field is expected to change. Though I might put the context first in that case, to match series func standard order.
15:24If your temporary context only has a couple things in it, and it is basically a data structure, you could also use a map, but it still doesn't add a lot of value in that case. What the latter approach gives you, which matches Boris' recommendation, is that it feels more direct and readable (to me).
15:25I often suggest to follow Red's patterns, but you have a lot of your own, so consider what matches your own patterns as well, for maintainers.

meijeru
12:52A question: when I use load on a text file which contains JSON data, it is automatically converted. Does this mean that for text files, json is the default encoding? The docstring says that to load "code" one needs to specify /as none. So that would imply that "code" (i.e. molded Red values) is not default. Can anyone explain?
12:54An example is https://api.github.com/repos/red/red/commits. This is a string which "looks" like JSON, and indeed is. But the address itself does not suggest that. Without any help from me, load makes this into a block of maps -- magically!
13:19On decoding more generally: both JSON and CSV can encode into a file! or url! value, but decode only from a file! value, not from a url!. What is the reason?
13:26Moreover, the function spec for JSON decoding, which lacks url!, is in contradiction with my experience described above.
dockimbel
14:51@meijeru See: https://github.com/red/red/blob/master/environment/functions.red#L418
14:53Also load/as ... none <=> load ...
meijeru
15:38I have now seen that for decoding from url!, the MIME type is determined by read/info, and for file! it is determined by the suffix. So that covers everything.
17:01You may judge the improved presentation of load and save in the spec document [here](https://github.com/meijeru/red.specs-public/blob/master/specs.adoc#111-conversion-of-data).
greggirwin
17:20@meijeru :+1:

GiuseppeChillemi
00:08@hiiamboris I have an answer for you about arguments and/or context passing. Well, with composed code it is a nightmare. For example: if you have a functions call stack and in the middle function you have WORD and in the first called function you have another WORD and a CONTEXT, then a composed, for example, VID block will have to handle bindings either to the first and to the middle function. Also, if an upper function needs to pass values to a lower one and updates its arguments WORDs, it is also a nightmare under the light of binding and composing. Composed code ends up often with WORDS bound to the main context while they should use another one. Too much work with current Red tools and structure (but I see a couple of functions that could be created to mitigate the problems)
The best solution is to create a context with everything you need and pass it to the first function called which will then pass it to the other functions at call site. Then work in their body with path syntax relative to the passed context. Example: ctx-vid-panel -> ctx-vid-panel/validation-data or /field or /anything you want.
I have realized that's the best someone can do ! I have spent 24 hours trying to structure all functions with either CTXs, and function arguments, moving data back and forth and composing VID blocks with blocks taken from a code blocks library.
hiiamboris
08:36Uhm.. I sort of vaguely paint the idea, but a minimal snippet to illustrate the problem would help ;)
GiuseppeChillemi
09:00It's simple: if you have a code blocks library the best solution is to have a context you share between functions and work on it with paths. This because when you bind a block you do this with just one context! There is no danger of having undefined words, contexts not available and many other problems related to passing data via functions. You lose part of code readability but you gain in brain health. (I will post something)
cloutiy
14:36Regarding object, other than creating a new object with inheritance, is there a way to add things to the object's body after it's been created? Something like append body-of myobject [ new-word: newval ]
meijeru
14:45The built-in function extend will take an object! value as first argument and a set of key-value pairs as second argument of type block! hash! or map!. It will add the keys that are not present in the object, with their values, and replace the values for those keys that are already present. The keys and values are not evaluated. **It is not yet implemented!**
cloutiy
15:17@meijeru thanks for this info. Will keep making new objects until extend )
dockimbel
15:41@cloutiy Why not use map! or block instead of objects?
cloutiy
18:50@dockimbel I suppose I could, had not thought about that option!
GiuseppeChillemi
20:05@meijeru will extend manage the block as make object! does with its spec block?
dockimbel
20:08@meijeru @cloutiy The primary purpose of extend is to be able to extend *in-place* objects (like the ones in system object or in a View face tree), and not to enable OOP. That last concern is the main reason why it's not already implemented. I need to figure out a way to limit its usage to in-place objects.
GiuseppeChillemi
20:09Also a remove would be useful.
21:12But I understand that a context is a one way travel so removing an element would left words without their corresponding elements in their respective context.
21:15@dockimbel
>> @meijeru @cloutiy The primary purpose of extend is to be able to extend in-place objects (like the ones in system object or in a View face tree), and not to enable OOP. That last concern is the main reason why it's not already implemented. I need to figure out a way to limit its usage to in-place objects.

I do not know which are not "in place" objects and so the reason of your fear. Could you explain please?
hiiamboris
21:20those internally created
GiuseppeChillemi
21:21Thanks Hiiamboris.
21:24Also I don't uderstand the fear of The Creator on this topic. Enriching a context is useful in many scenarios.
meijeru
21:35@GiuseppeChillemi You still deserve an answer to the question: " will extend manage the block as make object! does with its spec block?" The answer was already in my earlier post: The keys and values are not evaluated. So that is how it differs from make object!.
GiuseppeChillemi
21:43Thanks Rudolf. So it is a normal block but I suppose that if extend will support an object as input you can create it and just extend the target one using it as argument. This to have standard evaluation of the spec blocks before "extending" the target.

meijeru
08:32That seems correct.
mikeyaunish
21:18Can't seem to figure out how to access a context from within a layout. I have tried this but it doesn't work. What is the correct way to do this?
check-for-context: does [ print (value? 'my-ctx) ]
my-ctx: context [
    view layout [
        button "check for context" [ check-for-context ]
    ]
]

hiiamboris
21:32No, not like that.
context [
	my-ctx: self
	inner: context [
		... uses my-ctx ...
	]
	view [... [uses my-ctx] ...]
]
21:33Your my-ctx is not set before the view returns (window closed)
mikeyaunish
21:53Great - thanks.
nedzadarek
23:21Good evening,
I want to execute some exe(cutable). It opens some window (some game - Love/Lua). On my windows I just move a directory at the executable (shortcut to be precise) or from cmd: path-to-exe some-dir.
It works but is call/show right way to call it? /show says Force the display of system's shell window (Windows only) not saying anything about "graphical window".

hiiamboris
07:57Docstrings lie ;)
bubnenkoff
10:56I have got float error Runtime Error 1: access violation . I can't reproduce it because I am retting it randomly when data is processing. How I can debug it or at last get full stack-trace?
11:19> No ODBC support yet, probably will come after v0.7.0 or v0.7.1 release (ports).
> Your friend is using a ODBC binding, this one may be: https://github.com/gurzgri/odbc-red

I decided to try this driver. I placed odbc.red and odbc.reds in app.red folder.
app.red:
Red []
#import %odbc.red

drivers: odbc-drivers
print drivers

then tried to compile it and got error:
*** Compilation Error: undefined word odbc-drivers
*** in file: D:\code\odbc_test\app.red
*** near: [odbc-drivers
    print drivers
]

endo64
13:27Try to compile with -r
bubnenkoff
13:41Same error
greggirwin
15:51I think %ODBC.red was experimental.
bubnenkoff
20:05I need to store key-value pairs. The object is seems to be exactly for it. The only problem that my keys is string values like:
{"some key": "some value"}
Is objects still good for me?
I will generate list of k-v from two nested foreach loop
hiiamboris
20:10See https://github.com/red/red/wiki/[DOC]-Comparison-of-aggregate-values-(block!-vector!-object!-hash!-map!)
endo64
20:27@bubnenkoff map could be better in your case.

bubnenkoff
09:10What if I do not sure what kind of stash will be passed in path / or \?
>> last split "file/foo/file.txt" "/" 
== "file.txt"

hiiamboris
09:19split can take charsets for it's delimiter
bubnenkoff
09:24thanks! I have small question about copy. I need to prevent touching original data and work with it's copy inside function.
I tried this:
rules: ["bb" "cc" "dd"]

f: func[] [
	insert copy rules "aa"
	print rules
]
>> f
bb cc dd


I expected that output will be: aa bb cc dd
rebolek
09:25you are inserting into a copy of rules, but that copy is not stored anywhere
09:25try something like insert local-rules: copy rules "aa"
09:26and then print local-rules
bubnenkoff
09:26it will destroy after exit from function?
rebolek
09:27if you add it to header as /local local-rules then yes
toomasv
10:32Or you may do it without creating local word:
f: func[] [
    print head insert copy rules "aa"
]

GiuseppeChillemi
16:54Do we have a single command to set all the bound words of a block to the values of the corresponding words (corresponding = the same word and not position based as SET does) of another block ?

I mean:

blk1: words-of make object! [c: 99 b: 33 a: 22 ] 
blk2: words-of make object! [a: 66 b: 55]
>> setxxx blk1 blk2
[c b a]
>> probe reduce setxxx blk1 blk2
[99 55 66]


I have already created a function but I ask just to understand if it is redundant.
hiiamboris
16:58You could just bind this block to the second object
GiuseppeChillemi
16:58Without binding, the first context values must change.
hiiamboris
17:00Well, in this case try set context? :blk1/1 context? :blk2/1
GiuseppeChillemi
17:01I'll try.
17:25Thanks, It worked. Help does not talk about this working mode:

word         [any-word! block! object! path!] "Word, object, map path or block of words to set."
value        [any-type!] "Value or block of values to assign to words."


For value I expected only single words can be used and not couples [set-word values]. Also this working is symbol based and not positional based.
hiiamboris
17:29It's not "couples [set-word values]" though, it's set object! object! form
GiuseppeChillemi
18:13I spot just a problem with this approach: all words must be bound to the same context.
hiiamboris
18:17What would be the point of setting object's values to values of the same object?
GiuseppeChillemi
18:26Values in blk1 could have different contexts each one
hiiamboris
18:33I see

bubnenkoff
12:16I know that Rebol was designed with idea of distribution computing. What can I read about it? For example I want to try do some distribution app. Which protocols it would base on etc? How such app(s) should be organized?
theSherwood
15:53Is a series an array or a linked list? When I get some element from a particular index, is it iterating over all previous elements?
hiiamboris
15:55It's an array
15:55O(1) indexed access, O(1) insertion at tail, O(n) insertion at the head
theSherwood
15:56Okay. Interesting. How is that working with memory? Series can include anything, right? So is each element in an array a pointer to some value elsewhere in memory?
hiiamboris
15:57Technically we may introduce a linked list at some point, which will also be included in the series! typeset, but all that currently is there is arrays (hash! is an array powered by hashtable)
15:59> Series can include anything, right?

>> ? series!
SERIES! is a typeset! value: make typeset! [block! paren! string! file! url! path! lit-path! set-path! get-path! vector! hash! binary! tag! email! image!]
16:00Though block types
>> ? any-block!
ANY-BLOCK! is a typeset! value: make typeset! [block! paren! path! lit-path! set-path! get-path! hash!]

can include any Red value
theSherwood
16:00Okay. In contrast, vector can only contain primitives of the same type?
hiiamboris
16:00Yes.
16:01It is also true that series is only a pointer and start index ("head"), into what we call a "series buffer" (which is *the* array)
theSherwood
16:02That clarifies a lot, thanks.
hiiamboris
16:02You're welcome. Nice to see good questions ;)
theSherwood
16:03I have lots of questions. I'm sure they'll get tiresome fairly quickly. haha
hiiamboris
16:04Do your own homework first then ☻
16:04You know where to look from my message in red/red
theSherwood
16:04Yes, I won't ask questions that I haven't tried to answer by other means first.
hiiamboris
16:04:+1:
theSherwood
16:07Most of my experience is with high-level languages. So I'm not clear on the nature of cross-compilation. I with cross compilation, a single red program can be compiled to run in windows, macOs, android, etc. But how far does that concept extend? If an operating system were written in Red, could it run on x86 and ARM?
hiiamboris
16:10In Red/System you can even insert binary code right into your program ;)
So yeah, nothing's stopping you from writing an OS in Red. It emits code native to the CPU and wraps it into the OS format.
theSherwood
16:11Wow. So you could have the same operating system running across your desktop, phone, tablet, raspberry pi, etc?
16:11That would be convenient.
hiiamboris
16:12I guess it was an old dream of Carl Sassenrath, inventor of Rebol. There are some experiments in writing a Red/OS but I can't recall whose...
theSherwood
16:14Amazing. Red is very exciting.
cloutiy
17:36Apologize for the gitter question, but how do I search inside rooms? Trying to find answers to some previous questions but can't figure out searching for the life of me.
hiiamboris
17:46On the leftmost panel there's a magnifier icon. Although... well.. gitter search is the worst one I've ever seen ;)
17:46Better ask @rebolek how to download gutter archives locally and search there ☻
17:47Because there's very little chance you will actually find anything of use otherwise
cloutiy
21:50@hiiamboris ok thanks. Ya, it's pretty useless search.
endo64
22:08@cloutiy You can try @rebolek 's gitter client, it can download room content & search locally: https://github.com/rebolek/gritter
theSherwood
22:17Looking at system in http://helpin.red/Whatisinsystem.html, is system available from scripts and programs or only from the repl?
hiiamboris
22:18Almost everything is
theSherwood
22:20That's really interesting. Does that kind of reflectivity incur any performance costs?
greggirwin
23:52No more than any other evaluation.

theSherwood
00:38Interesting. Related is the '?' function. If applied to a function, it will print the docstring. Does that mean that the docstring is included in the compilation output?
greggirwin
01:39Yes.
01:40Red is deeply reflective.
theSherwood
02:22I'm finding the more I dig into it, Red is familiar but in some areas taken to such extremes as to feel alien again.
02:23I don't say that as a criticism, by the way.
02:26Are there any resources on destructuring and pattern matching? I've seen a little bit of destructuring in the use of foreach and I've seen the case and switch statements. Are there any more resources on Red's capabilities here? For example, what datatypes can and cannot be destructured?
GiuseppeChillemi
07:49What you mean for "destructuring" ?
greggirwin
08:40Red has a familiar facade, but is alien in many ways. And there are gotchas that are rites of passage, but keep in mind that things work the way they do for a reason. e.g., soon enough you'll trip over the need to copy series values in funcs. I won't spoil it for you though. ;^)

For destructuring, play with set using blocks of words and values, and objects.
08:42The king of pattern matching is parse, but it's overkill for simple dispatching in most cases. Important basic funcs for this are any and all; learn how they work. Also, one of the most distinctive features of Red is the variety of datatypes. Leverage those for all they're worth.
cloutiy
19:06@theSherwood Nothing could prevent one from adding a 'destructuring' feature. Depends on your use case of destructuring. For example destructuring lists of tuples (as found in other languages):
destruct: func [ recipients container ] [
    parse recipients [
        any [
            'rest (rest: container)
            | copy s word! (set s first container container: next container)
        ]
    ]
    exit
]

~: make op! :destruct

>> [a b rest] ~ [ 1 2 3 4 5]
>> a
== 1
>> b
== 2
>> rest
== [3 4 5]
theSherwood
19:25Wow. Thanks! This is great stuff. Red seems remarkably flexible.
endo64
19:25For pattern matching, we will have a basic one in find
? find
...
    /any         => TBD: Use * and ? wildcards in string searches.
    /with        => TBD: Use custom wildcards in place of * and ?.
greggirwin
19:26@cloutiy :+1: I have done that kind of thing a few times in the past. e.g.
set...: func [
	"Like SET, but the first set-word! in words will refer to the rest of the values"
	words  [block!]  "Words to set"
	values [series!] "Values words will refer to"
	/local w
][
	parse words [
		any [
			set w set-word! (set w values) to end
			| set w word! (
				set w pick values 1
				values: next values
			)
		]
	]
]
set... [a __:] [1 2 3 4 5]   ?? __
set... [a b __:] [1 2 3 4 5] ?? __
set... [a b c] [5 6]
set... [a b c __:] [1 2 [x y z] 3 4 5] ?? __
theSherwood
19:28Could you explain the __?
19:29Oooh. Okay. I think I understand.
19:30You can do that because set-word! is a datatype in its own right.
19:31@endo64 Do you have an example of what those refinements might look like in use?
endo64
19:32A basic example:
>> find "one two three" "t*o"
== none
>> find/any "one two three" "t*o"
== "two three"
>> find/any "one two three" "t?o"
== "two three"
19:33But remember, it is not yet implemented in Red.
theSherwood
19:53@endo64 Gotcha. So /with will allow finer-grained patterns based on what? Something regex-like?
hiiamboris
19:57Just custom chars for wildcards I suppose
theSherwood
20:06Gotcha
GiuseppeChillemi
21:18I expected the first one to return hello/world

>> type? probe head insert to-path first [/world] 'hello
hello//world
== path!
>> type? probe head insert to-path to-word first [/world] 'hello
hello/world
== path!


But the second one did it.

Also I expected the first one to return an error in the following code...

hello: [/world 1]

>> reduce probe head insert to-path first [/world] 'hello
hello//world
== 1

... but it worked !

I don know why it has been done this way but I had 10 minutes of crazyness trying to figure how to do this simple probe head insert first [/world] 'hello. Then I figure it out.
But which is the reason to have such atypical // paths ? Is it to use refinement as key too ?
hiiamboris
21:20Path is a block.
21:20
>> to block! /world
== [/world]
21:21
>> head insert as path! [world] 'hello
== hello/world
21:29
>> hello: [/world 1]
>> key: /world
>> path1: 'hello/(key)
== hello/(key)
>> path2: as path! compose as block! path1
== hello//world
>> get path1
== 1
>> get path2
== 1

Reasonable that both paths work the same?
21:312nd one even faster
>> clock/times [get path1] 1000000
0.46 μs	[get path1]
== 1
>> clock/times [get path2] 1000000
0.40 μs	[get path2]
== 1
GiuseppeChillemi
21:32I should not ask such questions when I am near to falling asleep. My REM phase will be delayed by some hours.
hiiamboris
GiuseppeChillemi
21:34The concept that paths are series was already mine but those convoluted uses and buildings were not. Thanks you!
greggirwin
22:37I have this old workaround:
to-path: func [spec][
	; LOAD FORM is used to clean up specs that have refinements 
	; in them. Refinement values get their sigil doubled, which
	; FORM removes, so they are sanitized. More overhead, but we
	; could make that optional if this func lives on.
	load form append clear '_/_ spec
]

theSherwood
03:10Are variadic functions possible in Red? I can't seem to find an example.
03:21I'm guessing I might need a macro for this?
hiiamboris
07:03Just use blocks as arguments. Otherwise possible but you'll shoot yourself in the foot a lot.
07:05print is an example
rebolek
08:29@cloutiy @endo64 @hiiamboris I've added some info about Gritter usage to [README.md](https://github.com/rebolek/gritter/blob/master/README.md). I'll add info about searching soon, if you have any questions, feel free to use [Gritter room](https://gitter.im/red-gitter/Lobby)
bubnenkoff
10:51How to debug red-app? I am getting error Runtime Error 1: access violation but I do not see any stack-trace
hiiamboris
10:55You need to build it in debug mode -d
10:55But best thing to do is to isolate the crash to a minimal reproducible example and let us test it ;)
bubnenkoff
11:12Thanks! I tried, but I do not understand logic of crush. it's looks random for me.
11:14> You need to build it in debug mode -d

Thanks!
11:29Oh... it's seems that it some problem with SQLite driver. I still continue using it because there is no better alternative.
https://gist.github.com/bubnenkoff/11a9bb13099d536a2a75546cef3178ba

I can't create reproducible example because it's random crush on insert operation. Sometimes it can work very long, sometimes it's crush again and again and I do not see any logic. If I will be able to reproduce it I will give you know
hiiamboris
11:32Try putting recycle/off somewhere at the top of your script.
bubnenkoff
11:42I did. What it's doing?
hiiamboris
11:42Disables Garbage Collector.
11:43It's known to cause random crashes.
bubnenkoff
11:44But how it's possible that red can work with and without it?
hiiamboris
11:45Why not? It's just a global flag
pekr
11:49There should be technically no need to turn-off a GC imo. If it helps, then it is imo a sign of a buggy GC ...
hiiamboris
11:49It's a temporary design ;)
11:50Normal GC is planned for 1.0 IIRC
bubnenkoff
11:54In what moment GC is needed? How red can free objects\memory without it?
hiiamboris
12:03It can't.
12:04GC is needed when you run out of memory ;)
bubnenkoff
12:15So if my app is allocate some objects it's memory usage will grow till crush?
hiiamboris
bubnenkoff
13:39Can I free objects manually?
hiiamboris
13:49You can maximize reuse though ;)
bubnenkoff
14:34use same name for different data?
hiiamboris
14:35No. Reuse the same blocks and objects for new data.
bubnenkoff
14:36I want to send POST request and specify content type like: --header 'accept: application/json' is it possible to do with red now?
hiiamboris
14:36Yes. With some voodoo.
14:37See here https://github.com/rebolek/red-tools/blob/dc3dceaf74e7356c00c5983d69ff00ff07579d36/http-tools.red#L286
bubnenkoff
14:52Thanks! What it wrong?
>> send-request/data http://localhost/api  POST "{}"
*** Script Error: POST has no value
hiiamboris
bubnenkoff
14:58"Data to send with request (auto-converted to proper encoding)" content [string! block! map! object! none!]
So I can send url 'POST object [a: 1] ?
hiiamboris
14:59Not sure. Try it or ask Bolek
bubnenkoff
15:03Does he is present here?
hiiamboris
15:06At times
bferris413
15:57Hi all, are system resources GC'd yet? If I load an image ("load" as in "do whatever I need to do to display it", I don't have the old source in front of me at the moment) and display it in Red, many months ago it wasn't garbage collected. Has that changed?
hiiamboris
15:59If you use this build then yes https://github.com/red/red/pull/4300
bferris413
16:01Cool, thanks
GiuseppeChillemi
19:54@hiiamboris

Refinements and path experiments come from the need to find a datatype which naturally represents a relation between blocks and in particular the generic relation were you have a path without the head (You will add it later).

Think about having:

data: [database1 [table1 [[a b c][1 2 3][9 10 11]]]
and
data2: [database1 [table2 [[a b c][1 /table1/b 3][9 /table1/b 11]]]


Or a column configuration where you identify a relative relation.
When you will process this data and you find /table you will it join to data1 and the the corresponding column [/table1 key]

data2: [database1 [table2 [
                    columns-cfg 
                                 [a [] b [/table1/b] c []]
                                                       ]
                                        ]
                ]


However, the experiments failed and I can't use a path multilevel path without having an rooot word to give as sacrifice to the Red God.

>> type? /aword/bword
== /bword
>>

I can use just the refinement datatype to reference a table but not the column.

I will have to find another approach for deeper relations.
19:59Well, I could sacrifice .. :-)
20:02
>> type? quote ../table1/c
== path!
>>


Red likes this notation.
hiiamboris
20:11Yeah, that might work
20:13Or just table1/b
GiuseppeChillemi
20:33I am searching for a way to express both relative and absolute data paths in my code/data and using a word as the first element of the path I (think I) would loose the ability to make this distinction.
hiiamboris
20:39I sometimes use ~ as shortcut for global context (system/words)
20:40Another option would be use lit-paths and normal paths
20:41e.g. 'table1/b - global, table2/c - local
20:41See what's more readable in your case
GiuseppeChillemi
20:41Both are really good options !
20:42Nice, Thank you!
hiiamboris
20:43No problem ☻

endo64
01:00Shouldn't red build libRed stdcall generates a dll instead of an exe?

> \red\build\bin>red build libRed stdcall
Target: MSDOS
Compiling to native code...
...output file      : \Red\red\build\bin\libRed.exe  <<<<<<<

greggirwin
01:10I haven't built it in a long time, but we should clarify and doc if you need --dynamic-lib to force that.
endo64
01:30Nope even with --dynamic-lib the result is an exe. Also as I see in the source code if the first argument is build then all other arguments are ignored.
https://github.com/red/red/blob/master/red.r#L687
01:31IIRC I compiled libRed.dll a few months ago, but don't remember how, what changed since then.
01:37Executing from Rebol (do/args %red.r "build libred stdcall") works. From CLI it produces exe.
bubnenkoff
11:58I have list of words that I want to unset:
words-for-unset: ["aa" "bb" "cc"]

foreach word words-for-unset [
	unset (to-lit-word word)
]

And I am getting error: Script Error: unset does not allow lit-word! for its word argument
hiiamboris
11:59It's all in the error message
bubnenkoff
12:01but when I am unseting I am writing: unset 'x
>> to-lit-word "x"
== 'x
12:02So I assume that unset to-lit-word "x" should work. But it does not
hiiamboris
12:05
>> type? 'x
== word!
12:06'x is evaluated. What is the result of evaluation of a lit-word?
12:07In your case (to-lit-word word) is evaluated instead. Does it return result of the same type as 'x?
bubnenkoff
12:35oh, I understood. But how to prevent it from evaluation?
hiiamboris
12:40Do you need to?
bubnenkoff
12:40did not understand
hiiamboris
12:41Do you need to prevent evaluation? (you'll get a raw paren then)
bubnenkoff
12:50I just need to unset all words from block: words-for-unset: ["aa" "bb" "cc"]
like unset 'aa unset 'bb ...
hiiamboris
12:51Think about the error message you're getting. You'll figure it out at some point ;)
bubnenkoff
19:54@hiiamboris it should be very simply, but I really could not find good way.
words-for-unset: ["aa" "bb" "cc"]
foreach word words-for-unset [
    unset to-lit-word mold word
]

that also do not work
hiiamboris
19:57Programming is hard, what can I say ;)
greggirwin
19:57@bubnenkoff have you done help unset? Read [Boris' message](https://gitter.im/red/help?at=5ecd061b2c49c45f5aa1d02f) again.
hiiamboris
19:58Why do you insist on making it a lit-word when it told you it does not accept lit-word?
greggirwin
20:01@bubnenkoff the really, really, really, *really*, really, really important thing is understanding evaluation, when it occurs, and what results it produces. This is very different from other languages. It can trip you up, even experts have to stop and think through it sometimes, but without understanding it, you'll suffer a lot of confusion.

The other really, really, really, *really* important thing is datatypes. In this case, why are you using strings in your list of words to unset?
theSherwood
20:04I have heard the issue of evaluation being different a few times. @greggirwin is there any resource that would give me a better idea about what these differences are?
20:05@bubnenkoff Have you tried to-word?
hiiamboris
20:05Spoiled his quest ;)
theSherwood
20:06Oh. haha. sorry. just a shot in the dark.
greggirwin
20:07The summary is: Everything is data until it is evaluated. Critically, understanding that blocks are *not* evaluated by default, which is where reduce and other evaluators come in. Then it's a matter of learning which funcs reduce, e.g. print, and on to the deep voodoo. :^)
theSherwood
20:09Oh. I see. Okay. That makes sense.
greggirwin
20:10Playing to learn is invaluable. I do it all the time, even after 20 years of Reboling. In thinking about how to answer your question, I just did this in the console:
>> type? 'a
== word!
>> type? first [a]
== word!
>> type? a
*** Script Error: a has no value
*** Where: type?
*** Stack:  

>> type? first ['a]
== lit-word!
>> type? :a
== unset!
>> type? first [:a]
== get-word!
>> type? a:
*** Script Error: a needs a value
*** Where: a
*** Stack:  

>> type? first [a:]
== set-word!
bubnenkoff
20:10> Why do you insist on making it a lit-word when it told you it does not accept lit-word?

because I am doing:
>> to-lit-word "x"
== 'x

and see that it return lit-word, that accepted by unset. I really confuse with it. I reread your messages but I am did not understand idea behind it.

@greggirwin you are really right about other languages, I am more comfortable with Red now than half year ago, but still having a lot of question that I am not able to solve myself.

A am using strings here just to learn

> to-word

Oh my god! It's work. I will try in next day to understand how it works!

Really big thanks for help! Because without your answers I I would lose all motivation.
theSherwood
20:11@greggirwin This is slightly different but related to the issue of how evaluation happens. Is it possible to declare a #macro within a #macro function body?
greggirwin
20:12From that, I realized that I missed stating an important aspect of all this: Red gives you enormous control over evaluation. Many users will never need it, or use it, but it is a *huge* difference from other languages.
theSherwood
20:12I've glimpsed some of that in the past couple days of playing with Red. I haven't figured out how to make use of that yet, but it feels very interesting to explore.
bubnenkoff
20:13I have other question, I need to return code (status of execution) to OS. Like in C-sh languages: main() { return 0;} Is it's possible to do with Red? If to compile app of course
hiiamboris
20:14try ? quit
bubnenkoff
20:14ok! thank!
greggirwin
20:14@theSherwood, @hiiamboris and some others love macros, so I'll let him talk your ear off about them. Just know that there be tygers there. :^)
hiiamboris
20:15Let's first hear why @theSherwood needs macros (:
theSherwood
20:15@greggirwin Haha. Thanks for the warning.
greggirwin
20:15I was going to use the word "madness!", but restrained myself. ;^)
theSherwood
20:15@hiiamboris I want to play with implementing multiple dispatch.
20:17I'm hung up because I think I need a macro for variadic functions and then a further macro that somehow incorporates that to add multiple dispatch (on arity)
hiiamboris
20:20You can make variadic functions without macros. But since Red doesn't have expression separators, you'll have to wrap every call into a paren.
greggirwin
20:20Madness! ;^) It might have been @maximvl who did an experiment along those lines, long ago. But with free ranging evaluation in Red, variadic funcs are going to drive you...deep. Since I crossed the borders of sanity long ago, I try to keep things simple and not fight what my inner Red Master tells my heart.
20:21So I'd either just use blocks, or think about making a dialect.
hiiamboris
20:22Yes, use blocks (as print does)
theSherwood
20:22Ha. I don't really have a specific need, I'm just still playing with the language.
20:22Oh right.
20:22I just noticed that about print 5 minutes ago.
20:22haha
20:23So I should do variadic functions in the style of print then use a macro to get multiple dispatch from that. Is that the right approach?
greggirwin
20:26Multiple dispatch can be done in many ways. Maybe start with examples of how you want to write it, at the user level.
hiiamboris
20:27The only point in using macros is when you wanna produce some code before it's bound (bind is a deeeep topic of Redbol), or when you wanna preprocess a piece of code once and use it multiple times after (saves you precious CPU cycles). In your case I don't see that need. You will call the dispatch code each time anyway.
theSherwood
20:30@greggirwin This is what I'm thinking of in terms of syntax:
product: f-mult [x y z][
  [x]       [ print x ]
  [x y]    [ print x * y ]
  [x y z] [ print x * y * z ]
]
20:31@hiiamboris I'm wanting to avoid having the syntax transformation happen at runtime. Is that thinking about it wrong?
hiiamboris
20:32Unless you compiled your script, there's only runtime.
20:32Did you? ;)
theSherwood
20:33I have not, but may want to leave the possibility open. Again, all this is just exploration. No real use case at this point.
hiiamboris
greggirwin
20:33Not wrong, but (since you're going deep) don't think in terms of ASTs in Red, think in terms of CSTs (Concrete Syntax Trees).
hiiamboris
20:35@theSherwood macros also have a problem: they don't work in console ;) So I suggest first writing a function that does the transformation, getting happy with it, then simply transforming into a macro.
theSherwood
20:36@greggirwin Okay. I'm not familiar with that concept. I'll do some research on that.
20:37@hiiamboris :thumbsup:
greggirwin
20:38It comes back to the core tenet I noted. Red is very dynamic, and there are no keywords, so until you evaluate something, in a given context, you really have no idea what it's going to do. :^) That includes how many values will be consumed, which comes back to free ranging evaluation and variadics.
hiiamboris
20:38As for macro within a macro, you can call normal functions within a macro, and define them in the preprocessor.
theSherwood
20:40@greggirwin So CST's are related to that. Thanks for the context
20:41@hiiamboris Define them in the preprocessor? I thought that's what #macro was doing
hiiamboris
20:43#macro substitutes parts of source code (data). Although you can substitute some pattern with itself, and define a function on your way, it's not very efficient as you might guess. #do OTOH is for definitions.
20:43E.g. #do [my-func: ..] then #macro another-func [..][ uses my-func here ...]
theSherwood
20:44Oh. I see. This goes back to what you were saying about bind?
hiiamboris
20:44Don't rush it ;) You'll get there
theSherwood
20:44Will do!
greggirwin
20:45There is another way to look at things, in the dispatch space. Tease this apart and ask questions.
map-ex: func [
	"Evaluates a function for all values in a series and returns the results."
	series [series!]
	fn [any-function!] "Function to perform on each value; called with value, index, series args"
][
	collect [
		repeat i length? series [
			keep/only fn series/:i :i :series
		]
	]
]
res: map-ex [1 2 3 a b c #d #e #f] :form
res: map-ex [1 2 3 a b c #d #e #f] func [v i] [reduce [i v]]
res: map-ex [1 2 3 a b c #d #e #f] func [v i s] [reduce [i v s]]
theSherwood
20:47First question is :form. That passes a copy of the native function into the map-ex function?
20:47I'm trying to remember where I saw that :fn syntax...
greggirwin
20:49You saw it in my console example some messages up.
20:49https://doc.red-lang.org/en/datatypes/get-word.html
theSherwood
20:50Ahh. Right.
20:52Looks like I've got plenty of homework to be getting on with. I'm sure I'll be back with plenty of questions in the next few days!
20:55Thanks @hiiamboris and @greggirwin for all the helpful direction. My initial impression of Red this last week has been a real eye-opener.
hiiamboris
20:56:+1:
greggirwin
20:59@theSherwood another way (or two), you can approach this:
product: func [
	args [block!] "1, 2, or 3 integers"
	/local x y z
][
	set [x y z] args
;	case [
;		integer? z [print x * y * z]
;		integer? y [print x * y]
;		integer? x [print x]
;	]
	parse args [
		  3 integer! (print x * y * z)
		| 2 integer! (print x * y)
		| 1 integer! (print x)
	]
]
print product [2]
print product [2 3]
print product [2 3 4]
theSherwood
21:02Okay. That's full of interesting tidbits. I didn't realize that you could use set to destructure a block like that.
endo64
22:07@theSherwood Here are some different ways for product:
;for 3 values at most. Empty block returns 1
product: func [b [block!]] [multiply any [pick b 1 1] multiply any [pick b 2 1] any [pick b 3 1] ]

;recursive mathod, for any number of values
product: func [b [block!]] [either tail? b [1] [multiply first b product next b]]
;or
product: func [b [block!]] [either tail? b [1] [b/1 * product next b]]

>> product [3 5 7 9]
== 945
hiiamboris
22:12Or this horror :point_up: [May 19, 2020 8:02 PM](https://gitter.im/red/chit-chat?at=5ec41108520b7a38fbde6d39)
theSherwood
22:13@endo64 The any [... 1] combination is to prevent multiplying by 0?
endo64
22:14@theSherwood Yes
22:19Of course those examples are just to show different ways, none of them is perfect.
One of the simplest is:
product: function [b [block!]] [r: 1 forall b [r: r * b/1]]

>> product [3 5 7 9]
== 945
>> product []
== none
theSherwood
22:23:thumbsup: Which way is the more idiomatic Red way?
endo64
22:29Well, the last one is the first one comes to mind (at least for me), but it depends on other constraints like should it work for 3 values only, what empty block returns, etc.
22:31Here is another one:
>> calculate: function [b [block!] op [op!]] [r: 1 forall b [r: r op b/1]]
== func [b [block!] op [op!] /local r][r: 1 forall b [r: r op b/1]]
>> calculate [3 4 5] :*
== 60
>> calculate [3 4 5] :+
== 13
22:34Ah, 1 as initial value isn't correct for other op values. Sorry, not a good example, but you get the point :)
theSherwood
22:42Yes. That's quite an interesting one, turns operators into reducers. I like it.
22:43Unrelated but:
a: 1
switch a [
	1 [ print "hello" ]
]

b: integer!
switch b [
	integer! [ print "hello" ]
]


Why does the first switch statement print "hello" but the second does not?
greggirwin
22:50@theSherwood it's all about evaluation. Sometimes it helps to break things apart.
b: integer!
cases: [
    integer! [ print "hello" ]
]
type? b
type? first cases
type? first reduce cases
22:53Also be sure to look at help type? for a refinement it offers.
theSherwood
22:58Thanks @greggirwin
23:03I see what you're saying now about evaluation being tricky. first cases gives me integer! and first reduce cases gives me integer! but type? first cases gives me word! while type? first reduce cases gives me datatype!
23:04So in my switch statement, the integer! is of type word! while b is of type datatype!?
endo64
23:29Correct. Blocks are not evaluated unless you do, compose, reduce or try it (and a few others)
And switch doesn't reduce its second argument.
greggirwin
23:37Correct. One of the problems we face in Red is that we have to choose a "form" when we display values, and the friendly form doesn't show you all the details. So some things may look alike in the console, and even when printed during debugging, but be of different types.

In the future, all types will offer a serialized form, but just a few do today. It's possible, then, that the console will show that for some types, but maybe not all. e.g.
>> mold none
== "none"
>> mold/all none
== "#[none]"
theSherwood
23:56:thumbsup:
23:58I'd like to be able to use a word without giving it a value. Is this possible without parse? I want to be able to iterate over a block and simply note if and where there is this particular word that has been given no value. Is that possible?
23:59
[1 2 3 _ 5 6 7]

theSherwood
00:00For example, the _ above. It would be convenient if it did not need to be given a value to find where its position is in the block. I find I can print it just fine, but haven't found any other functions that can grapple with it.
greggirwin
00:01Not sure how you want to use it, but you can use find to find it, and ask if if has a value?.
theSherwood
00:06Okay. That should help. I'm trying to make an 'equalish' function that compares two blocks but ignores any place where a block has an undefined "_". I will use that function to make a pattern matching function which I will eventually use for the multiple dispatch function.
02:42Hmm. I'm still struggling with this. I need to be able to compare the unset! _ to make sure it isn't some other unset!, like x.
02:43Is there a way to do that? Preferably without parse?
02:46Here's the function:
equalish: func [
	block1
	block2
][
	l1: length? block1
	l2: length? block2
	repeat i l1 [
		b1: pick block1 i
		b2: pick block2 i
		case [
			not b1 = b2 or (not value? b1) or (not value? b2) [return false]
			; i > b2 and b1 is not _                          [return false]
		]
	]
	true
]
02:47I want to return false if block1 is longer and the elements of block1 beyond the length of block2 are not the unset! _.
toomasv
07:03One possibility:
equalish: func [block1 block2][
	len: length? block2 
	repeat i length? block1 [
		b1: block1/:i
		b2: block2/:i
		if any [
			not any [
				b1 = b2 
				b1 = '_ 
				b2 = '_
			] 
			all [
				i > len
				b1 <> '_
			]
		][return false]
	]
	true
]
bubnenkoff
07:44@hiiamboris
>
> >> type? 'x
> == word!
>

> 'x is evaluated. What is the result of evaluation of a lit-word?

I am still confusing with it.

Docs says: "A lit-word! value is an unevaluated word! value".

Why you are saying that: "'x is evaluated"?

07:57
>> type? x 
== integer! ; type of evelauted word value
>> type? 'x ; type of word literal, not word value
== word!


Right?
endo64
07:58> Why you are saying that: "'x is evaluated"?

@bubnenkoff when you type it on console, console evaluates 'x lit-word to x word.
07:59Otherwise x: 5 type? x would return word!.
bubnenkoff
08:00and than x can be evaluated again to it's value?
toomasv
08:01:point_up: [May 27, 2020 10:03 AM](https://gitter.im/red/help?at=5ece10a8778fad0b132b992b) Simplified:
equalish: func [b1 b2][
	forall b1 [
		if not any [
			b1/1 = b2/(i: index? b1)
			b1/1  = '_
			b2/:i = '_
		][return false]
	]
	true
]
bubnenkoff
08:02Oh... word evaluation is blowing my mind.
endo64
08:02@bubnenkoff Yes, it is evaluated to its value in its context.
bubnenkoff
08:03lit is shortcut to literalaka spelling?
endo64
08:07Yes it is for literal word.
GiuseppeChillemi
12:41> Oh... word evaluation is blowing my mind.

@bubnenkoff I can understand you, it has blown my mind too. But console + help here has cleared my mind.
theSherwood
14:58Thanks to all your help, I was able to make a rust-style match function that can be used like this:
foo: [ 1 3 ]
val: match/deep foo [
	[ 1 y z ][ y * z ]
	[ x 3 _ ][ x + 3 ]
	[ _ _ z ][ z ]
	_        [ "default" foo ]
]
print val ; => 4

bar: [ 1 3 5 ]
val: match/type bar [
	integer!           [ "type int" bar ]				;-- type
	[ block! ]         [ "type block" bar ]			  ;-- wrapped type
	[ logic! | float! ][ "enum" bar ]					;-- enum
	_                  [ "default" bar ]				 ;-- default
]
print val ; => "type block" 1 3 5

baz: 7
val: match baz [
	[ 1 | 2 | 3 ][ baz + 100 ]						   ;-- enum
	4            [ baz * 10 ]							;-- value
	[ 5 .. 9 ]   [ baz + 10 ]						    ;-- range
	[ 10 ]       [ baz * 800 ]						   ;-- wrapped value
	_            [ 1000 ]								;-- default
]
print val ; => 17
15:02The match/type doesn't work particularly well, unfortunately. It throws errors if you try to match action!, op!, function!, and probably others.
15:05So match feels like it's most of the way to multiple dispatch. I will have to tinker with that some more.
hiiamboris
15:16@theSherwood use get-words (:bar & :baz) if your problem is evaluating functions where you don't need to
theSherwood
15:18@hiiamboris Tried that, but I've got something in the implementation of the match function that is handling them incorrectly.
hiiamboris
15:18I see
theSherwood
15:18I haven't been able to find how that's happening yet.
15:21The evaluation stuff is pretty sticky. I'm still wrapping my head around all that.
greggirwin
18:19Fun stuff @theSherwood. :+1:
theSherwood
18:39@greggirwin It's getting to be a bit of a problem. Playing with Red is distracting me from what I *should* be doing.
hiiamboris
18:50We know right. Red is addictive.
greggirwin
18:53It's done that to me for 20 years.
theSherwood
18:57I feel like I need to code in Red all the time now. Other languages don't seem to be giving me the same high. Haha.
rebolek
19:07@theSherwood nice!
dockimbel
19:08@theSherwood Resistance is futile!
greggirwin
19:51Wait until you start typing URLs, dates, times, IP and email addresses, hashtags (and now refs) and curse having to put them in quotes and not typecheck them. Or when you do read http://... that returns JSON and...you're done.
theSherwood
19:57Haha. Well, I look forward to the day I can write Red fulltime then!
20:20I'm sure this is something simple, but I'm thrown on this:
map: function [
	series
	fn
][
	s: []
	repeat i length? series [
		append s fn series/:i i series
	]
	s
]
print map [ 1 2 3 4 5 ] function [ a ][ a * a ]		; 1 4 9 16 25
print map [ 5 4 3 2 1 ] function [ a b ][ a + b ]	; 1 4 9 16 25 6 6 6 6
rebolek
20:21s: copy []
20:22or you could rewrite it using collect:
collect [repeat i length? series [keep fn serires/:i series]]
theSherwood
20:22Okay. Interesting. Could you talk me through that?
20:23the s: copy []
rebolek
theSherwood
20:23Does [] refer to something in memory?
rebolek
20:23Exactly.
20:23Let me show you an example...
dockimbel
20:24There's a [long wiki entry](https://github.com/red/red/wiki/%5BDOC%5D-Why-you-have-to-copy-series-values) about that.
rebolek
20:24
>> second body-of :map
== []
>> print map [ 1 2 3 4 5 ] function [ a ][ a * a ]
1 4 9 16 25
>> second body-of :map
== [1 4 9 16 25]
theSherwood
20:26That is something of a mind-bender. haha
20:27I will definitely be reading that wiki entry.
20:32Woah! So changing values actually changes the place where those values are defined?! This is trippy.
rebolek
20:32code is data. you are just manipulating that data.
20:32and that data are then evaluated to actually do something
theSherwood
20:34I had never considered that the mutations were happening on the data/code itself. I guess I had assumed that Red was creating data structures that mimicked the shape of the descriptions (code) I was supplying it. But it's actually mutating the code. Haha. How long does this take to sink in, typically?
20:35How long until the implications of that feel intuitive?
hiiamboris
20:35It depends ;)
theSherwood
20:37Ha! So what happens with the collect script that @rebolek posted? That's not mutating anything, so it genuinely creates a new data structure every time?
hiiamboris
20:37It does
theSherwood
20:38Very interesting.
hiiamboris
20:39I'm no fan of collect though ;)
20:39That's why I wrote [map-each](https://gitlab.com/hiiamboris/red-mezz-warehouse/-/blob/master/map-each.red)
rebolek
20:39why?
hiiamboris
20:40Because collect is extra verbose most of the time
rebolek
20:40that's true
hiiamboris
20:40It has it's use cases, like generating draw or VID blocks. Where you're laying out mixed data
rebolek
20:42for simple loops like the map example about it's too much
hiiamboris
20:43Yeah. I have found that most of the time collect in people's code is only used to wrap a loop (mostly foreach).
20:43So why not have a ready construct for that? ;)
theSherwood
20:44Do mezzanine functions not show up in the console or is map-each simply new enough that it isn't in the 0.6.4 release?
hiiamboris
20:44It's not in the official binary, as the design is still fresh.
theSherwood
20:45Gotcha. Will it be coming to the binary?
hiiamboris
20:45At some point, of course.
theSherwood
20:46:thumbsup:
hiiamboris
20:46Use it, report your experience, and you'll bring the moment closer ;)
theSherwood
20:46Ha. okay. will do.
hiiamboris
20:47By the way "mezzanine" is our slang for functions written purely in Red (contrary to those supported by R/S)
theSherwood
20:48Written purely in red but they still go in the binary? Or any function written purely in Red?
hiiamboris
20:48Any function written purely in Red.
theSherwood
20:49Gotcha.
20:49Red seems to bill itself as influenced by functional, imperative, and reactive styles. But most of what I've seen has a fairly imperative flavor. I'll be interested to see more functional stuff coming to Red.
20:50In that vein, are there any plans for transducers, or will that stuff need to be an external library?
greggirwin
20:51There is almost nothing you *can't* do in Red. We have a large HOF design effort in the works, as just copying old ideas isn't the best fit for Red.
theSherwood
20:54That makes sense. I'm already finding that with the toy functions I'm throwing together. I'm doing it to bring in stuff that I'm more familiar with, but it doesn't quite fit the way wants to work.
hiiamboris
20:54The key here however that Red is interpreted and some designs will simply be more efficient than others within it.
theSherwood
20:54That makes sense.
20:55This obviously creates a big onboarding problem that I'm sure you folks have thought a lot about.
greggirwin
20:55Right, and no auto TCO.
theSherwood
20:55TCO?
greggirwin
20:55Tail Call Optimization.
theSherwood
20:56Right. Yeah, I can see that being a friction point for some functional folks.
20:57Are you planning on a clojure-esque loop and recur combo, or is there something that would fit Red better?
greggirwin
20:57I don't know how those work in Clojure, so...No. :^)
theSherwood
20:57Haha. Fair enough
greggirwin
20:58I started https://github.com/red/red/wiki/%5BDOC%5D-Red-Should...-(Feature-Wars) at one point, and we'll fill things in as needed.
theSherwood
21:04:thumbsup:
greggirwin
21:20I glanced at the Clojure docs on those, and the examples didn't make me go "Oooh! We need that!" A good deal of that is my lack of experience with Clojure, so I don't see them through the lens of regular use, or problems they solve for Clojurists.

@theSherwood you will find, and perhaps be annoyed by, my tendency to ask for concrete use cases. It's not that I mean to push back on ideas, just that it helps me understand things. It also gives us things we can touch, bang on, play with, and use for discussion.
theSherwood
21:27@greggirwin I don't mind at all. That sounds very sensible to me. There are lots of things I could imagine being a part of Red, but not all of those things would make Red better on the whole.
21:29I hope the opposite is also true, that if I have suggestions or criticisms that it should go without saying that I am incredibly appreciative of what you all have built / are building, and that I'd like to see Red succeed!
greggirwin
21:54:+1:
GiuseppeChillemi
22:08I have a word in a compose paren that is in a VID block I COLLECT. it should contain across or nothing and then return nothing to add. How should I do this?
hiiamboris
22:10
>> compose [1 ([]) 2]
== [1 2]
>> compose [1 (()) 2]
== [1 2]

This helps?
GiuseppeChillemi
22:26Ok, so I should let it return an empty block, thank you.

theSherwood
15:14@greggirwin What is the process for submitting something to that "Red Should..." page?
bubnenkoff
15:44Am I right understand that in red/system words work as variables
15:54Question about language design. I see that Red\system have C-string type. But should it have strings without that store it's length in itself? I have heard that C-string are very dangerous and error-prone
rebolek
16:00If Red/System wants to be able to cooperate with C libraries, it needs to support them.
hiiamboris
16:02> Am I right understand that in red/system words work as variables

Yes.
16:05> I have heard that C-string are very dangerous and error-prone

All pointers are. R/S is no less dangerous than C, and has to interface with OS API where C-strings are used as well.
greggirwin
19:56@theSherwood you can post a note in chat. It's a wiki, so you can also edit directly. Feel free to add new sections to be filled in. If something is going to represent Team Red's views, we are the final arbiters of that content.
theSherwood
20:15:thumbsup: I'll just edit the wiki directly then, and you folks can curate how you see fit.
20:35@greggirwin I added a little blurb about some kind of sandboxing.
greggirwin
21:02The subject of sandboxing is fine, but it's probably too soon for you to add content that contains ideas of what Red might do. The effort is appreciated, but it's not a good answer. First, Red has a well defined way to deal with untrusted code: use dialects. Second, a datatype is not the right mechanism for this. We will likely have a secure dialect like Rebol used.
21:06Please remove the content but leave the Sandboxing section.
theSherwood
21:09:thumbsup:
greggirwin
21:10Thanks!
theSherwood
21:10Sure thing!

bubnenkoff
10:01Why R/S use integers for exceptions, but not text?
PierreChTux_twitter
10:13> This is trippy.

I love your word. It almost ounds like a guru name.
10:36@greggirwin I got TCO (Tail Call Optimization), although the concept isn't quite clear yet; however, HOF is still mysterious to me, and duckduckgo didn't help me much...
ne1uno
10:43add +programming to search term HOF TCO ETC
rebolek
11:14@bubnenkoff here's a dedicated room for Red/System: https://gitter.im/red/red/system
Anyway, integer is a common method for such situations in low-level languages. You return just one value without a need for allocating memory for a string.
greggirwin
15:26@PierreChTux_twitter TCO allows you to write recursive code (has to be written a certain way though) which doesn't just keep growing the function call stack; so it can be faster and also not blow the stack. HOF is an advanced concept, and you never *need* to use or understand it. In expert hands it is very powerful, but also requires thinking more abstractly. We hope to make its power more accessible, and also leverage it internally to make less code do more.
theSherwood
23:33So I was just reading up a bit in the FAQ and came across this: https://github.com/red/red/wiki/%5BDOC%5D-FAQ#how-can-i-make-the-compiler-accept-more-dynamic-code.
23:34Are there hard limits on how much dynamism the compiler can handle? Does that depend on compilation target or on the parser?
23:36I guess, more to the point, I'm wondering what happens to all the uniquely red dynamic and reflective stuff if you compile to javascript as in this proposal: https://github.com/red/red/wiki/%5BPROP%5D-REP-XXXX-----Adding-JavaScript-compiler-target
23:37Are there certain language features that become unavailable or does it compile to a higher level of abstraction within the target language to maintain those capabilities and consequently suffer a performance penalty?

greggirwin
00:36Rebol never had a compiler. Ever. If it weren't for a very good reason, Red wouldn't need one either. That reason is self-hosting. There will always be limits to what can be AoT compiled, which depends entirely on what it supports and how the code is used. It doesn't depend on the target or the parser in any way. The great thing is, you can use -e when compiling and never have an issue, because it forces code to always be interpreted. Or you can use do for sections of code to force that on a more granular level.

Check out https://gitter.im/red/red.js to see what @ALANVF is doing on a JS front. Since JS is only JiT compiled, it can be dynamic. The implementation will be very different, and less efficient, but the core language should all be implementable. View and VID, OTOH, are a different story. Then there's DOM access.

This is another topic to note, because it comes up repeatedly. It sounds appealing, on the surface, but the costs...oh, the costs. Targeting JS is not beyond the team's technical ability. That should be made very clear. But we have this mission, this goal, this purpose in life, to fight software complexity. As soon as we buy into that world, we lose a piece of our soul (speaking for myself here), and are then sitting on top of a big pile of...stuff. And people *will* use all those libs and frameworks, which are not designed to be anything like Red, so now we've just *added* to the polyglot stack of languages and concepts. So we shouldn't do it, because it will just hurt the poor web devs. ;^)

theSherwood
01:16That makes sense. The notion of having Red own the entire software stack is a very attractive one. Do you think Red-on-the-Web could serve as a kind of bridge to lead developers and users to Red proper? Isomorphic apps could be a kind of gateway of sorts. Or is that fool's gold?
01:18Thanks for the link, by the way!
greggirwin
01:38It's hard to gain any type of visibility in the web-sphere. We'd be up against TypeScript these days, and if you're still in the browser, a lot of Red's value is compromised. Certainly the language is still what it is, but you also have to consider all the tooling, deployment models, etc. I do think that having a fairly complete core will let web devs play with the language, which is a good thing. It changes how you think, and it's fun.
theSherwood
01:45:thumbsup:
pekr
05:17@greggirwin So everytime we mention JS here, there dies one little kittie somewhere around the world, right? :-) Well, I can easily agree, that to generate nice small and conscise VID dialect to something like Angular or other frameworks, it really feels like a pain to redbollers :-)

When I think about it more, I wonder what attracts ppl (including me) about the browser. Many would like to script the web and interoperate with the DOM, etc. But for me mostly, it always was the means to distribute the app. In a corporate environment with hundreds of ppl, and in situation where users don't have the rights to run installations, the distribution of apps is an obstacle to overcome. And here I thought something like WebAssembly target might become handy. But not sure how difficult would it be to support the idea.

However, and as @dockimbel also mentioned IIRC, the model might change. Even on desktop MS introduced so called Metro / Modern apps first. Those did not take off properly, as the initial plan was to replace Win32 API apps. But nowadays, using Office 365, we've got e.g. MS Teams app, it updates itself for users and that's just it. Any you know what? Ppl prefer the Desktop app in comparison to the Teams web version.

Btw - MS is working on a project called Reunion - maybe something to look-up for the future direction in terms of the Windows support - https://www.theverge.com/2020/5/19/21258697/microsoft-windows-project-reunion-win32-uwp-apps-apis-build
giesse
06:04@theSherwood about compiling Red, in the general sense, it's impossible. More explicitly, for any Red compiler you can write, I can come up with a piece of code that will run in the interpreter but not be compiled correctly by your compiler.

That being said, so long as you're not specifically writing code to beat the compiler, most code can be compiled. When you have something that can't, you either rewrite it (if you care about performance) or just leave that part interpreted (eg. wrap around do [...] in the current compiler).

It is my personal opinion that with deep static analysis, 99% or more of code that you'd normally write (ie. if you're not purposefully trying to beat the compiler) can be compiled. But, that's quite a lot of work, in fact I'm not sure I've seen a compiler for any language do the level of code analysis that I'm thinking about. (Also, I don't believe the compiler shouldn't be working out of text files, or even blocks, but rather function! values etc. after everything has been set up by the interpreter, especially all the binding; this makes any macro preprocessing unnecessary because you can just build your code dynamically in the interpreter before the compiler even kicks in. But, I digress.)

I'd also add in a neural network to catch even more edge cases and do even more trickier optimizations, constantly learning from what people do every day...
dander
07:10I still think that WASM is an interesting target. I found a [nice article](https://blog.scottlogic.com/2019/12/24/webassembly-2019.html) talking about recent things happening in that space. In particular, he highlights [this tweet](https://twitter.com/solomonstre/status/1111004913222324225) by a Docker co-founder basically saying that WASM+WASI makes Docker unnecessary. Still, Red doesn't need WASM to be able to run on multiple platforms, but having that as a target would make it possible to make platform agnostic binaries I guess
pekr

TimeSlip
14:00Sorry to interrupt this very interesting conversation. I was and have been wondering about how you all handle/get-around nested objects that are saved and then retrieved. What method do you use to "revive" the nested ones? I've been using "do load" and then manually reducing the nested blocks of objects but that seems rather primitive. Thanks in advance.
nedzadarek
14:55Is it me, or doc.red-lang.org/ is offline?
GiuseppeChillemi
16:01@nedzadarek I can see it
hiiamboris
16:43@TimeSlip for blocks of objects, you'll have to do that, yes
until serialized form gets finished
nedzadarek
17:21@GiuseppeChillemi hmm... could you get me site's ip (on windows run console and type ping site).
TimeSlip
17:41@hiiamboris Thank you. That's a lot of reducing in View! :-)
PierreChTux_twitter
17:46@nedzadarek Here it is:

# pierre@latitude: ~        < 2020_05_31__19:45:51 >  [bashpid_14979]
ping -c 1 doc.red-lang.org
PING cdn.gitbook.com (138.68.189.76) 56(84) bytes of data.
64 bytes from eu2-do-lon.gitbook.me (138.68.189.76): icmp_seq=1 ttl=51 time=43.3 ms

--- cdn.gitbook.com ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 43.272/43.272/43.272/0.000 ms
17:47I can also see the website at https://doc.red-lang.org/
GiuseppeChillemi
18:43@nedzadarek
ping doc.red-lang.org

Esecuzione di Ping cdn.gitbook.com [107.170.223.154] con 32 byte di dati:
Risposta da 107.170.223.154: byte=32 durata=194ms TTL=52
Risposta da 107.170.223.154: byte=32 durata=229ms TTL=52
Risposta da 107.170.223.154: byte=32 durata=198ms TTL=52
Risposta da 107.170.223.154: byte=32 durata=203ms TTL=52

Statistiche Ping per 107.170.223.154:
    Pacchetti: Trasmessi = 4, Ricevuti = 4,
    Persi = 0 (0% persi),
Tempo approssimativo percorsi andata/ritorno in millisecondi:
    Minimo = 194ms, Massimo =  229ms, Medio =  206ms
hiiamboris
19:15@PierreChTux_twitter about https://github.com/red/red/wiki/%5BDOC%5D-Red-Should...-(Feature-Wars)/_history
I don't think mentions of unimplemented yet features is the purpose of that wiki
giesse
19:42@TimeSlip that's why mold/all is quite important, unfortunately not yet implemented fully in Red. In the meantime, if you can, use map! instead of object!, or even blocks etc.
nedzadarek
20:07@GiuseppeChillemi thank you
It's seems to be problem with OpenDNS. One person had this problem: https://gitter.im/red/red?at=5e95fb3ecc370f0b07e53b50 Is it possible that people from Red team send some kind of message to update their database?
GiuseppeChillemi
20:24Ask them directly @greggirwin this ^^^^^^ is for you!
hiiamboris
20:26It's not like their DNS is specifically blocks doc.red-lang.org ;)
endo64
21:14@PierreChTux_twitter I reverted your changes on https://github.com/red/red/wiki/%5BDOC%5D-Red-Should...-(Feature-Wars) as @hiiamboris 's pointed no need to put notes there about features that just not yet implemented.
21:45@TimeSlip And when Redbin (https://doc.red-lang.org/en/redbin.html) is available at Red level, we will be able to save & load objects even keeping words bindings.
nedzadarek
23:14@hiiamboris I'm not network guy but they have old IP for over month.

TimeSlip
00:00@endo64 @giesse I won't ask how you know all these things but thank you so very much!
PierreChTux_twitter
19:00> @PierreChTux_twitter about https://github.com/red/red/wiki/%5BDOC%5D-Red-Should...-(Feature-Wars)/_history
> I don't think mentions of unimplemented yet features is the purpose of that wiki

Well, I had heard (somewhere within one of these gitter chats, can't remember where, but that was quite recent, less than a few weeks ago, I think) that there had been some progress on ports, but maybe I misunderstood something.
hiiamboris
19:18Did you read the preamble of that wiki? ;)
greggirwin
19:24Ports are coming.

theSherwood
04:12I'm on macOs and just upgraded? to Catalina, and now I'm getting this:

zsh: bad CPU type in executable: ./red-064


Is there any workaround for this?
greggirwin
04:20Some people are using Docker, as Catalina requires 64-bit apps, and Red is still 32-bit only.
theSherwood
04:22Right. Makes sense. Thanks @greggirwin.
bubnenkoff
09:03> Ports are coming.

is there any chance to get them in nearest few months?
rebolek
09:27Of course there is a chance.
09:29There's a public branch with ports for many months already, I ported my R3 Redis client to it and it was about the same speed or maybe even faster than R3.
09:31So anyone can try it and write code for it right now. However, there's no guarantee that the code will work with future versions of ports.
pekr
09:31I thought that the public branch is not the target one and that it is being worked on on behind the scenes?
rebolek
09:32@pekr right, but if you want to try ports, you can. Even if the final interface will change, the underlying logic would be same.
bubnenkoff
10:59> There's a public branch with ports for many months already, I ported my R3 Redis client to it and it was about the same speed or maybe even faster than R3.

What it's name I do not see ports mentions on github
11:12I am on the latest git brach. Is ports merged there?
>> ? open
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!] 

REFINEMENTS:
     /new         => Create new file - if it exists, deletes it.
     /read        => Open for read access.
     /write       => Open for write access.
     /seek        => Optimize for random access.
     /allow       => Specificies right access attributes.
        access       [block!] 

>> 
>> f: open/new %123.txt
*** Script Error: open does not allow file! for its port argument
*** Where: open
*** Stack:
11:38What is analog of ports in another languages?
hiiamboris
11:42> What is analog of ports in another languages?

IO streams
11:42> I am on the latest git brach. Is ports merged there?

I don't think so
rebolek
12:22Ports are not merged yet and the public branch is behind the private one.
qtxie
23:51FYI. https://github.com/qtxie/red/tree/IO2 is the latest code for ports.

bubnenkoff
11:52thanks!
11:58Am I right understand that ports is just attempt to create common way to work with data? And every particular case can be done in another way?
hiiamboris
bubnenkoff
20:35Then I don’t understand how ports related with db access?
hiiamboris
20:42ports describe persistent connections (to db, to file I/O, http...)

meijeru
13:30See the spec document, section 11.4:

Ports represent a generalization of files and urls. They implement the concept of Uniform Resource Identifier (URI), as defined in RFC3986, and the various operations on the resources represented by URIs; the functionality offered by ports will be more complete than the basic I/O currently provided. Besides I/O actions proper, the actions applicable to ports comprise most of the series actions. These actions differ according to the type of resource, which RFC3986 calls its scheme. For certain schemes, Red provides built-in implementation of the actions. For other schemes, the user can provide the implementation in the form of Red functions.

PierreChTux_twitter
13:34@bubnenkoff Some databases work with files, which are simply opened and accessed by third-party client programs: for instance, sqlite, or dBase, stuff like that.
Other databases work as client/server, for instance PostgreSQL (my favourite ;)), MySQL, etc. For those, communication between clients and server travels through the network, using protocols, through *ports*.
13:36Such a port can be defined by a hostname and a number. On PostgreSQL, for instance, if you want to access a database server running on a machine called SVR, and the server is listening on port number 5432 (this is the default for PostgreSQL), then a client must connect to SVR:5432 in order to establish a connection, and then all communication occurs within this communication channel.
13:38Therefore, ports are a fundamental key when it comes to client-server computing.
Same goes for a web server and web clients such as browsers.
pekr
14:24I don't necessarily agree with ports description. I my view, they are much more than a file or an url access. Rebol had file, url, serial, db, sound, crypto, system ports. Not all fit into the file or url category?
meijeru
16:22I think you are right -- ports MAY represent all kinds of resources. The first real example was the GPIO port. I will update my description.
TimeSlip
17:09@bubnenkoff That is a good question. I never really thought about it too much but was curious in Rebol when using Doc's mysql driver I had to "Insert" into the port and "copy" to see the results of a query. It makes sense now.
meijeru
18:33@pekr @bubnenkoff A revised description of ports:
Ports represent external resources in the most general sense. In particular, they are a generalization of files and urls. In this, they implement the concept of Uniform Resource Identifier (URI), as defined in RFC3986, and the various operations on the resources represented by URIs; the functionality offered by ports will be more complete than the basic file and url I/O currently provided. In addition, they may represent all other external resources such as serial ports, database servers, audio and video devices, timers etc. The operations applicable to ports are described in section 11.4.2; besides I/O operations proper, these comprise most of the series operations as already described in sections 9.2/3. These operations differ according to the type of resource, which RFC3986 calls its scheme. The ports facility of Red extends this notion to all external resources, not only those considered by RFC3986. For certain schemes, Red provides a built-in implementation of the operations, in the form of Red actions (action! values). For other schemes, the user can provide the implementation in the form of Red functions (function! values).
cloutiy
22:01Hi there, grateful if someone can clarify. in the Red book, it says non-scalars are passed by reference to functions. Therefore I assume changes to a block inside the function is side-effect, and once outside the function, the original block would reflect the modification. Is this correct? If so, I'm not sure why this code doesn't do that. Unless once the function returns, the index position goes back to what it was prior to entering the function?
yield: function [items] [  f: first items items: next items  f]

data: [ 1 2 3 4 ]
>> yield data
== 1
>> yield data
== 1
>> yield data
== 1
>> yield data
== 1

Did I miss something?
hiiamboris
22:15https://github.com/red/red/blob/master/runtime/datatypes/structures.reds#L54 this should answer your question
cloutiy
22:38@hiiamboris Thanks for the link. I'm looking at it however not sure how to extract from it the answer :/
loziniak
23:03@cloutiy it's because items and f are local to a function. Also, index of series is kept inside word, not the series itself:
>> a: "1234"
== "1234"
>> b: a
== "1234"
>> a: skip a 2
== "34"
>> b
== "1234"
cloutiy
23:37Ok I think I got this to work as I wanted, albeit not s elegant:
yield: func ['items] [  
   f: first get items 
   set items next get items  
   f
]
>> yield data
== 1
>> yield data
== 2
>> yield data
== 3
>> yield data
== 4
>> yield data
== none

toomasv
03:49@cloutiy Currently your f is global. Maybe localize it or get rid of it altogether with also.
cloutiy
16:07@toomasv Thanks for your suggestion. also is a new one for me. Will check it out!
16:09Is there a way to get a dump of all the words and their values? Something like ?? but to list all the words and their values?
toomasv
16:10It can be huge. See body-of system/words for global ones.
cloutiy
16:15@toomasv great thanks Toomas.
toomasv
16:15You are welcome!
16:19But for starting probe new-line/all sort words-of system/words true may be of more use (or maybe what).
cloutiy
16:36@toomasv Thanks for the tip regarding also. Pretty cool:
yield: function ['items] [  
    also 
        first get items 
        set items next get items  
]

toomasv
16:36:+1:
16:39Now you don't need function as you define no words there (but function is rewritten into func).
17:05@cloutiy One more helper to peek on words/values (try in fresh console, it can easily crash)
foreach word sort words-of system/words [
    if not unset? :system/words/:word [
        print [
            pad word 15 #" " 
            pad type? get word 15 #" " 
            replace/all copy/part help-string :word 100 #"^/" #" "
]]]
cloutiy
19:26@toomasv Thanks Toomas. What I have in mind is something for debugging purposes. Having something I can call various places to see the content of various words. When called, it pauses the program, probes the list of words and their content, then press any key to continue. Actually to take it a step further, send the words and their contents to a web server which displays them on a web page. With checkboxes for each to "watch". They whole thing could be recorded to be replayed at slower speed. A visual debugging tool. Well, anyhow, that is the vision lol.
toomasv
19:28Nice! Waiting to see it in action.

rsheehan
23:19Does anyone else have problems with Visual Studio Code and the latest builds? In the last couple of weeks I always get the server crashing and not restarting as soon as I open a red file. This also happened a couple of months ago, but then the problem went away. I am use MacOS Mojave.

ldci
07:06Same problem for me with macOS 10.14.6
bitbegin
07:07@rsheehan @ldci VSCode extension not work for lastest builds
07:09commits older than 5aa78a6b60d0fa7d41d7a8e88ed653904908a909 on master branch should work
ldci
07:10@bitbegin Thanks for information. Not really important for me since I'm not really using VS
bitbegin
07:10or you need wait the new release of Extension
rsheehan
07:46@bitbegin Thanks. Good to know it is not just my setup.
loziniak
12:09Hi! Is there a platform independent way of opening a link in a browser from Red script?
rebolek
12:10browse link
loziniak
12:10nice, thanks!
rebolek
12:10You're welcome :-)
12:11I'm not sure if it works on Linux yet, but if not, it's easy to add.
loziniak
12:12Probably depends on Linux configuration. For me it works, Arch Linux + XFCE + Firefox
rebolek
12:13Ah, cool then.
loziniak
12:13I think it can depend on implementing Freedesktop.org standards in system.
rebolek
12:14It probably uses xde-open
12:14Yes, exactly :-)
ne1uno
12:30on windows, firefox family browsers might act different if they aren't already open. forget last session, trigger check if all extensions. wish it could make sure your default browser was already open.
hiiamboris
12:35use the 'session manager' addon
ne1uno
12:36losing last session is bad enough, getting a bunch of plugins disabled or updated can waste a day. I would be careful using that casually in a app
hiiamboris
12:39to not get plugins disabled you can set compatibility options in about:config
ne1uno
12:39some editors have poor session management. ok if already open but call an associated file all bets are off.
nedzadarek
14:04Hi, I have few question about progress. Suppose I have 4 progress, like this:
view [ 
    p1: progress  20x100 100% 
    p2: progress 100x20  100%
    at 150x10 p3: progress 20x100 50%
    return at 40x90 p4: progress 100x20 0%
]

1) I want a progress to start from another side (left <> right and top <> bottom). So in the above example "green part" (or however it is displayed in your machine) should start from the top.
2) How do I stylize it. Can I put some image that move when progress is increasing. Can I at least change a color?

ps. I'm aware of a non-progress solutions - no need to waste your time.
14:123) Is precision set to 1%? Can I change it?
hiiamboris
14:22You should understand that native OS widgets were designed for the task at hand, not for somebody to light up a party ☻
14:27looks like Windows will allow you to change colors and step: https://docs.microsoft.com/en-us/windows/win32/controls/progress-bar-control-reference

justinthesmith
01:31How do I launch the GUI console on macos?
nedzadarek
16:26@hiiamboris It wasn't "a party"... well, but I get what you mean. Thank you.
greggirwin
23:31@meijeru it may be more accurate to say that ports represent a connection; the important aspects of which are that they may be opened, and kept open, to process more than a single action or generate more than a single event. They also don't have to be external, as we look forward at instrumentation, in-process channels, and aggregators.
23:32On progress, if someone can verify what features work across platforms, that would be great.

meijeru
11:51@greggirwin I have refined my ports description (again). I put a question in another room, that may have escaped you and others:
"Another question to be raised: if ports may represent resources of any kind, what is the significance of the spec field of the port in case the resource has no URI (e.g. the GPIO port already provided). Is it obliged to have the same structure as a URI spec (system/standard/url-parts)?"

greggirwin
19:18@meijeru, good question. The scheme name (word!) is simply used to find the scheme in system/schemes, similar to how codecs work. You create a new scheme and add it to the system with register-scheme. Beyond this, you can think of Red as providing a simple interface for common cases, but you are not limited to that. For example, when file!s support open, you get a port with a scheme name of 'file, and that port can leverage some of the same fields as for urls (which get their scheme name from the first part of the URL); e.g., path and target. The file and URL types map to a common port configuration.

But you will also be able to make a port with a spec that contains any fields you may need for your special port, or none at all. Rebol's [encryption ports](http://www.rebol.com/docs/encryption.html) are a good example. There is no URI. All you need is a scheme name so Red can dispatch to the proper handler. In this way, Red puts the power entirely in your hands, while proving a simple interface for common cases. In the case of URLs, they *can be* used as a common interface for port specs, but also have limitations, and may not be a great match in all cases. Rebol's [serial](http://www.rebol.com/docs/changes-2-5.html#section-81) scheme shows both sides. It's concise as a URL, but not as self documenting. Each has its strengths.

It's instructive to note how Rebol's crypt port, like files and urls, let you insert raw data, while the GPIO port provides a dialected interface.
meijeru
20:56@greggirwin I reviewed my ports write-up and it was almost conformant to what you say. Just edited it slightly just now, to make it even more clear. One thing I conclude is that whatever you want to do on ports, it has to be done by I/O and/or series actions, which is a fixed and limited set of actions.
greggirwin
22:51:+1: The actions are fixed, as for all datatypes, but what you can do with them is not.
GiuseppeChillemi
23:33Just a personal note un URI: one the previous ERPs I have used, mapped the entire GUI on URI so that you can write on fields in nested panels, activate flags, read values and so on. It could be interesting to map our GUIs in such way.

nedzadarek
17:32Can we use the Responsive Design (e.g. setting position to the 50% of a base's draw)? If not is there a plan to add it?
ps. I mean directly in the code not composing blocks.
hiiamboris
17:40Position of what?
17:41What does "Responsive Design" mean in your book?
Respectech
18:19Generally, Responsive Design in UI means that it can reorganize the content based on the resolution of the UI area. Not sure if that's what @nedzadarek is referring to.
TimeSlip
21:39Question: What is the way to implement Rebol's stylize/master in Red? Or perhaps I should ask what Red's master style sheet is called?
nedzadarek
21:40@hiiamboris @Respectech Yes, like this (I'm not an expert at this). It's like using things like percentage instead of hard coded pixel values. I mean things like this:
[W3 schools: responsive text](https://www.w3schools.com/html/tryit.asp?filename=tryhtml_responsive_text) & [W3 schools: responsive page](
https://www.w3schools.com/html/tryit.asp?filename=tryhtml_responsive_page).

Like drawing square in the middle view [base 100x100 draw [box 49x49 51x51]] but without hardcoded values: view [b: base 100x100 draw [box (50% |- 1x1) (50% |+ 1x1)]] (pseudo code, but it shows using not-hardcoded values).
hiiamboris
21:42@TimeSlip not sure about Rebol. Maybe you're looking for system/view/VID/styles?
21:45@nedzadarek Write a VID preparser for that ;)
greggirwin
21:46@TimeSlip @rebolek had a stylize function long ago, but it needs to be updated. He may be the best to advise on it. https://github.com/red/red/pull/3825
TimeSlip
21:56 @greggirwin @hiiamboris Thank you.
22:05@greggirwin You also had a snippit showing layout/styles which hopefully will serve for the time being. I just want to get past the stylize function for now.
nedzadarek
22:25> @nedzadarek Write a VID preparser for that ;)

@hiiamboris too much work for such small task & my Red skills are rusty.

GiuseppeChillemi
22:51Could someone please take a look at my json file for vscode: https://github.com/red/VScode-extension/issues/35#issuecomment-643830032 to see if it is correct. Server keep crashing even without spaces on windows!

GiuseppeChillemi
20:43Don't mind reverting to vscode 0.3.5 solved all my problems

loziniak
10:06@nedzadarek you can check out my [resize-deep](https://github.com/robotix-pl/resize-deep) function. Execute resize-deep-test.red and play with resizing the window.
hiiamboris
10:10Also https://gitlab.com/hiiamboris/red-elastic-ui
10:12But I think he wants the initial layout to use percents.
loziniak
10:13That's what he wrote. But he can probably achieve this with both tools.

bubnenkoff
12:58what is this line do? https://github.com/red/code/blob/master/Library/SQLite/SQLite3.red#L450
/into result [block!] put result to block?
12:59and what is the reason to pre-allocate data for result in this line: output: make block! 16 ;use for temporary outputs ?
hiiamboris
13:06Particularily here - the reason is probably just a personal habit of the developer ;) "why not?" kind of reasoning
greggirwin
19:43Reusing, or using existing, blocks can reduce memory pressure and GC activity. When you see copy for a series, a new copy is created each time. When you see clear, the existing series may not deallocate memory, so it can be reused.

TimeSlip
13:40@greggirwin "a new copy is created each time." Good to know. Does that happen with something like this? myword: copy "" That's the only way I know to clear a string.
greggirwin
18:53Yes. You can clear it like so: myword: clear ""
18:54But copy is the standard approach, and good for most cases.
TimeSlip
18:55@greggirwin Thanks, that's new to me.

bubnenkoff
14:58So if I am getting random crush that lackly cause by GC I could try to change:
SQLite/query sql-query

to collecting it result to block and the emptying it with:
result: SQLite/query sql-query
clear result

?


15:01@Oldes it's look after some practice I begin better understand your code! Thanks for you help again! Before it was mostly like copy-past magic.

nedzadarek
14:10@loziniak Thank you. It looks promising (the test code). I need to put minimum windows size (so I don't have to use scrolls) and it should work. I will check the code later.
+ @hiiamboris I guess I could do it with both codes but I cannot compile it:
*** Compilation Error: undefined word x
*** near: [x align anchor-of y align]

Red [needs: view]
#include %elasticity.red
view/flags elastic [
	area "Hello tensile world!" #fill
	button "OK" [quit] #fix
] 'resize

ps. could you provide a license?
Oldes
14:14@bubnenkoff you don't have to, [it is being cleared in the sqlite/query call](https://github.com/red/code/blob/8bc261749fbf9920e2155c077411c64e7c1bdae8/Library/SQLite/SQLite3.red#L452)
14:15Also you can detect if crashes are GC related by turning GC off using recycle off.
14:15And to locate where the crash happens you can use debug build (using -d)
hiiamboris
14:16@nedzadarek license: BSD-3 - from the file
14:16@nedzadarek for compilation - tried -e?
14:17I recently tried to compile a simple 100 LOC file. Got a few hours of compiler bug hunting. It's that bad ;)
nedzadarek
15:18@hiiamboris now , with -c -e:
*** at line: 353
*** near: [word/duplicate ~script
    ~args|467: word/duplicate ~args comment "Literals"
    ctx48:
]

with the newest red
hiiamboris
15:42Add -u then.
15:42It builds for me.
15:42You must have an outdated libRedRT
bubnenkoff
15:46> Also you can detect if crashes are GC related by turning GC off using recycle off.

Yes I tried. I am getting OM when the memory is ending. And I am not sure at what moment it's not free. Does parse can eat and not free memory?

I tied to debug, but I do not have enough experience to understand place. It was related with query, but it really crush random.
wallysilva
20:17Hi guys, a noob question: why random keeps generating the same number every time I run the program? For instance random 100 keeps giving me 53. I can't understand this behavior...
hiiamboris
20:19Use random/seed now/time
wallysilva
20:23Thanks @hiiamboris, I understand that it needs to be seeded to work as intended. What I don't understand is in what kind of situation would I use random without having to seed it first?
hiiamboris
20:25When you have found a bug and you need repeatability for example.
wallysilva
20:31Oh I see, thank you!
hiiamboris
20:32I asked myself the same question some time ago ;)
nedzadarek
22:38@hiiamboris It works now. I guess you were right. I thought that the compiler would update libret.

@waglebr
In my opinion you would use random without seeding if you are doing "soft randomness" (e.g. pick one number a day, but you don't have any/many constraints like it can output the same number 3 days in a row).

If I want repeatability I would use a seed.
greggirwin
22:39"Soft randomness". Good term.

theSherwood
03:17Is there a cli option for running red as the "gui console"? I'm on mac
wallysilva
04:40@nedzadarek
I see, thank you
04:45Now I'm having issues to compile using ask. I added #include %./red-source/environment/console/CLI/input.red to my code but I keep getting random compiling errors related to win32.reds.
I'm sure this must have been discussed before, so I would appreciate if anyone could point me to the right direction.
04:46By the way, is it ok to ask these questions here or should I use the Welcome room?
hiiamboris
07:31@waglebr Totally okay ;)
Do you compile with -r flag?
bubnenkoff
09:30I decided to try process data with issue in GC. As I wrote before the app randomly hang. The crush was be more ideally for me because I was able to check if PID in memory. Is there any idea how to better check if app is hanging to know that It need restart?
hiiamboris
09:41depends on the app
bubnenkoff
13:34m... for example?
hiiamboris
13:45e.g. you may dump the time into a file periodically and check that file
bubnenkoff
13:54good idea!
wallysilva
15:59@hiiamboris Thanks :D
I tried with -r and it worked!
The thing is that I had tried it before and I got an error as well (I figure the issue was in my code at that time).
Now, when I try to compile with -c I get this error:
Target: MSDOS

Compiling to native code...
*** Compilation Error: undefined symbol: red/unicode/cp-to-utf16
*** in file: %/C/Users/wally/Coding/Red/red-source/environment/console/CLI/win32.reds
*** in function: exec/terminal/emit-red-char
*** at line: 282
*** near: [unicode/cp-to-utf16 cp pbuffer
    pbuffer: pbuffer + n
]
hiiamboris
16:01LibRedRT gets built with a specific set of exported (from the runtime) symbols that your program uses. When your script requires other symbols you need to rebuild it with -c -u
wallysilva
16:14I tried -c -u but I get this error now:
*** Compilation Error: undefined symbol: root
*** in file: %/C/Users/wally/Coding/Red/red-source/environment/console/CLI/input.red
*** in function: exec/terminal/init-globals
*** at line: 356
*** near: [root 1]
nedzadarek
16:35> "Soft randomness". Good term.

@greggirwin thank you. I don't know if anyone use it. I based it on soft & hard real-time computing.
hiiamboris
16:43@waglebr just tried myself. This is what I'm getting :D
Compiling to native code...                                                              
*** Compilation Error: argument type mismatch on calling: exec/parse-text-styles         
*** expected: [integer!], found: [struct! [                                              
        header [integer!]                                                                
        head [integer!]                                                                  
        node [pointer! [integer!]]                                                       
        cache [pointer! [integer!]]                                                      
    ]]                                                                                   
*** in file: %/D/devel/red/red-src/red-master/modules/view/backends/windows/text-box.reds
*** in function: exec/gui/OS-text-box-layout                                             
*** at line: 365                                                                         
*** near: [str catch?]
16:45And when I compile *in another directory*, I get the [root 1] error you mentioned. I'll report this bug.
16:45We need a test for this case as it's quite common and it's not the 1st time it breaks.
16:46Apparently some export definitions came out of sync with their functions' real code.
wallysilva
17:04@hiiamboris Thank you for taking the time and looking into that. For a beginner like me, these kinds of little errors can easily become a nightmare as we get stuck and it eventually adds up to the reasons to give up learning. Thank you for your support, I appreciate it!
hiiamboris
17:07Indeed. And you're welcome ☻
17:08For now, stick with -r. Unlikely you need to compile things often, as Red is primarily an interpreted language.
wallysilva
17:10It sounds good, thank you
hiiamboris
17:27:+1: Let us know when you encounter issues. It's those who are using Red who eventually make Red better ☻
wallysilva
23:07@hiiamboris
Just to let you know, I've just found out that -r mode is actually required when the program contains #include statements or Red/System code. So, I guess those errors with -c seem to be an expected behavior.

greggirwin
00:28@waglebr sort of true. You can build custom runtimes, which include your own Red/System code, which is then shared by multiple apps that use that runtime. Red gives you a lot of flexibility, which can be confusing, because you can assemble parts in many ways. You can also use -e (or do in code) to force interpreted mode in compiled apps, when your code is either very dynamic or runs up against compiler limitations.
wallysilva
01:09Hi @greggirwin, that sounds very interesting. I feel that I have a lot to learn. Thank you for sharing.
hiiamboris
07:52No, #include statements don't affect that, and R/S code should also work with -c after -c -u.
wallysilva
16:46There's a note in the book that I'm reading, but it doesn't explain why:
> "This compile mode (release) is also required when the program contains #include statements, or when it contains Red/System code."
Learn Red - Fundamentals of Red by Ivo Balbaert
hiiamboris
17:22IMO Ivo isn't the best source.
wallysilva
17:47His book was the only one that I could find on Red...
What other sources would you recommend?
hiiamboris
17:48We usually recommend Rebol/Core manual http://www.rebol.com/docs/core23/rebolcore.html
17:52There's also http://helpin.red/Introduction.html but I haven't read it. That it starts with some dubious editors probably doesn't speak for it
17:52As a quick reference nothing beats https://www.red-by-example.org/
wallysilva
17:53I know that Red is very similar to Rebol, but what are the differences that I should watch out for? Should I learn Rebol first and then transition to Red?
hiiamboris
17:55Learn how Rebol works and you'll be comfy in Red. Probably everything from Rebol/Core manual applies, except for Ports (not implemented yet).
17:55View subsystem is quite different though in Red, much much easier to use.
17:58The goal is first to build a proper mental model, see. Once it exists, it all becomes clear and natural ;)
greggirwin
18:11@hiiamboris +1, noting that Rebol never compiled user code. You could encap your code with the interpreter though.
wallysilva
19:48@hiiamboris +1 Thanks for the recommendations e clarifications.

nedzadarek
00:25@waglebr not sure how up to date it is, but there is https://github.com/red/red/wiki/%5BDOC%5D-Differences-between-Red-and-Rebol On the other hands I don't know if there is a list of "additions". I guess you can check main site and topics like https://www.red-lang.org/2016/06/061-reactive-programming.html or documentations... If you really want.
pekr
12:56Wasn't there recently a discussion of how to query a database via ODBC? Wonder if there is any command line tool (which would be callable and parseable via Red's callinterface), or any work already being done wrapping some OS level libraries?
GaryMiller
14:33Something like this? http://www.sqledit.com/odbc/order-runner.html
theSherwood
17:16@hiiamboris Just continuing with that discussion of Rebol, which version is most similar to Red? 2 or 3?
hiiamboris
17:35My opinion is all three are equidistant to each other ;)
theSherwood
17:40Ok. That simplifies things. Thanks!
wallysilva
21:33@nedzadarek +1 Thank you for the link. At a glance it seems that Red is very similar to Rebol, but certainly not a twin.
greggirwin
21:39It's an evolution of Rebol. :^)

vazub
06:16Has anyone already tried and hopefully achieved success with creating a Docker image for Red?
rebolek
07:00@vazub I believe @rcqls has/had Docker for GTK version of Red.
rcqls
07:29@vazub You can visit [https://github.com/rcqls/red-gtk-macOS](https://github.com/rcqls/red-gtk-macOS) or [https://github.com/rcqls/docker-red-gtk](https://github.com/rcqls/docker-red-gtk)
vazub
07:31Nice! Yeah, I am on Catalina now, therefore the updated project will be of most interest to me. Thanks, @rcqls !
bubnenkoff
12:21How to use function if it have two options (or how to correctly name /foo /bar signatures like here:
https://github.com/rebolek/red-tools/blob/master/http-tools.red#L401

I need /data and /auth together

send-request/data ... is ok, but how to add /auth?
rebolek
12:28Your arguments must have same order as refinements. So both
send-request/data/auth server method content auth-type auth-data
and
send-request/auth/data server method auth-type auth-data content
would work.
12:31btw, send-request is overloaded with refinements (eight, the horror!), so my plan is to create make-request and accept one or two args, link and dialect (and probly also settings object, I don't have the design done yet). I'll keep send-request as a wrapper for compatibility, but make-request will be main code. No ETA, but I'm still adding new stuff to send-request so I need to make the switch ASAP.
bubnenkoff
12:56Should auth-data contain prefix Bearer like: 'Bearer "eyJhbGciOiJIUzI1N ...... hSns=" or only: "eyJhbGciOiJIUzI1N ...... hSns="?
rebolek
12:57'Bearer is auth-type so your code should look like this:
send-request/data/auth server method data 'Bearer "asdf"
bubnenkoff
13:00What I am missing:
answer: send-request/auth http://localhost:8529/_db/ztest/_api/collection/protocols 'POST 'Bearer "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjEuNTkzMTcyOTU4NTg4MzQ3OGUrNiwiZXhwIjoxNTk1NzY0OTU4LCJpc3MiOiJhcmFuZ29kYiIsInByZWZlcnJlZF91c2VybmFtZSI6InVzZXIifQ==.a9L7AGDqjjZv1OdFYmT_uFUGLbX_NBva00UoUQXhSns="

*** Script Error: invalid argument: none
*** Where: write
*** Stack: send-request

?
rebolek
13:11You are missing any data. However it's not clear from the error message, I need to fix it.
13:11It's an empty POST request. You need to add /data
bubnenkoff
13:13I tried with data, but I am getting 400 -- bad request:
answer: send-request/data/auth http://localhost:8529/_db/ztest/_api/collection/protocols 'POST to-json object [a: 1] 'Bearer "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjEuNTkzMTcyOTU4NTg4MzQ3OGUrNiwiZXhwIjoxNTk1NzY0OTU4LCJpc3MiOiJhcmFuZ29kYiIsInByZWZlcnJlZF91c2VybmFtZSI6InVzZXIifQ==.a9L7AGDqjjZv1OdFYmT_uFUGLbX_NBva00UoUQXhSns="


This request is work fine if turn off auth:
answer: send-request/data http://localhost:8529/_db/ztest/_api/collection/protocols 'POST to-json object [a: 1]
rebolek
13:14btw, you shouldn't need to-json, it should convert authomatically
13:15What is listening on localhost:8259 ?
bubnenkoff
13:15ArangoDB
rebolek
13:16You may add /verbose and /debug refinements to see what is going on, full reply then will be available in raw-reply
bubnenkoff
13:19[![изображение.png](https://files.gitter.im/5780ef02c2f0db084a2231b0/05r9/thumb/izobrazhenie.png)](https://files.gitter.im/5780ef02c2f0db084a2231b0/05r9/izobrazhenie.png)
13:20Where I should look? Not very informative for me
13:20btw if you will use Arango here is curl command for generation token:
curl -X POST http://127.0.0.1:8529/_open/auth --data '{"username":"user","password":"123"}'
rebolek
13:21can you get the token from Red?
13:22
send-request/data http://127.0.0.1:8259/_open/auth 'POST #(username: "user" password: "123")


should work
bubnenkoff
13:24No, I am getting:
*** Access Error: cannot connect: http://127.0.0.1:8259/_open/auth reason: timeout
*** Where: write
*** Stack: send-request


But curl is working fine
rebolek
13:26you get timeout for getting token, but other requests work fine? This is strange.
bubnenkoff
13:28oh stop
13:28One moment I will check port
rebolek
13:28ok :)
bubnenkoff
13:29Yes:
send-request/data http://127.0.0.1:8529/_open/auth 'POST #(username: "user" password: "123")


return 200
rebolek
13:30btw, I just pushed new version that will throw a proper error when you are using POST method and data are missing:
>> send-request http://localhost 'POST
*** User Error: POST method needs data. Use /data refinement.
bubnenkoff
13:31one moment I will run it
rebolek
13:34I'm installing ArangoDB docker image, so I can try what is going wrong there
bubnenkoff
13:35[![изображение.png](https://files.gitter.im/5780ef02c2f0db084a2231b0/tChk/thumb/izobrazhenie.png)](https://files.gitter.im/5780ef02c2f0db084a2231b0/tChk/izobrazhenie.png)
13:35Thanks! btw still not working
rebolek
13:42does ArangoDB have some logs anywhere, so I can check what is wrong with the request?
bubnenkoff
13:44it should, but I also will google about them
13:45do you have same issue?
rebolek
13:46I get 401 wrong credentials when trying to get token
13:46both from Red and curl
13:46do I need to create user somehow?
bubnenkoff
13:49use root with it's pass, or create user in web interface
13:52for test you can use default _system db I think
rebolek
13:54Ok, I was able to get token
bubnenkoff
14:02Do you getting same error on send-request/data/auth?
rebolek
14:02I haven't tried it yet, I am looking at the token and it looks like this:
data: #(                                                                     
    jwt: {eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjEuNTkzMTc5NjY3NDYyMTUyNGUrNiwiZXhwIjoxNTk1NzcxNjY3LCJpc3MiOiJhcmFuZ29kYiIsInByZWZlcnJlZF91c2VybmFtZSI6InJvb3QifQ==.kltSJm_SzzuNUf3tlGtK_ISxcxnerjMNkFqlsbr4vw0=}←
)
14:03so it's using Json Web Tokens that aren't supported in send-request yet (although I have some partial implementation).
bubnenkoff
14:04auth-type [word!] "Basic, Bearer, TODO: Digest"
Bearer it's not JWT?
rebolek
14:04It's for OAuth usually.
bubnenkoff
14:04If not, so your are right that problem that it's not implemented...
rebolek
14:12Hm, I would need to add JWT to send-request to be able to use ArangoDB, sorry.
greggirwin
19:38[json-web-token.red](https://files.gitter.im/5780ef02c2f0db084a2231b0/7POk/json-web-token.red)
19:39My tinkerings from some time back. I only remember the base-64 oddities and perhaps my comment says something:

> The JWT specs lead to other specs, that lead to other specs.
19:40Maybe we worked on that together @rebolek I don't remember.
19:42Oh yeah! I also remember now thinking "Really? It's the 21st century and they're using 3 letter abbreviations for field names?"
rebolek
21:50@greggirwin yes, we were cooking something together. Maybe it's time to finish it :-)
22:06@bubnenkoff I'll be adding JWT to send-request however to use ArangoDB, you actually don't need it. Do this:
reply: send-request/data arangodb-server:port/_open/auth 'POST #(username: "name" password: "pass")
token: reply/data/jwt
reply: send-request/auth arangodb-server:port/_db/mydb/_api/version 'Get 'Bearer token


I.e. just send the jwt token back as Bearer authentication. There's no need to encode your JWT claim.

vazub
16:17What are the requirements to run http://static.red-lang.org/dl/branch/GTK/linux/red-latest on Linux? Trying some docker images - seems to run in Ubuntu but not on Alpine.
rebolek
20:16@vazub IIRC Alpine uses musl C library, which is currently not supported by Red, only glibc.
vazub
20:26> @vazub IIRC Alpine uses musl C library, which is currently not supported by Red, only glibc.

Indeed, it does use musl. I'll try installing glibc packages and see if it actually helps, thanks)

rebolek
05:12@vazub let me know how it went. It would be nice if red could be compiled with musl as I see it as a good fit, I've tried, but file access doesn't work then.
nedzadarek
16:27I cannot put functions directly into map: #(f: function [] [print 'yes]). Is it a feature or a bug (without gui console closing of course)?
toomasv
16:34map! is not reduced at creation. It's by design and [documented](https://github.com/red/docs/blob/master/en/datatypes/map.adoc#3-creation-syntax).
nedzadarek
19:08@toomasv thank you
toomasv
20:15You are welcome!

bubnenkoff
15:21@rebolek if I am using basic auth what format I should use for login/password?
rebolek
15:26... 'basic ["username" "password"], it Will convert it to proper format

nedzadarek
13:09@rebolek https://gitter.im/red/red/gui-branch?at=5ef9c009bb149531edd9b439
What do you mean that you "have plenty of space for custom stuff"? Isn't it the same as extra being a block or map?

@hiiamboris https://gitter.im/red/red/gui-branch?at=5ef9bff9e0e5673398dface9
Is there some tutorial or info about it (e.g. required fields like type & size)? Based on the links (and red's site) I was able to define actor but I cannot set a default actor (that which is set without on-even text):
extend system/view/VID/styles [
    ttt: [
        template: [
            type: 'text
            color: 255.0.0
            size: 100x100 ; you need to define it!!!!
            default-actor: function [f e] [print 'default]
            fas: function [a] [a * 2]
            actors: [
                on-down: function [face event] [
                    print 'text-on-down 
                    probe face/fas random 100]
            ]
        ]
    ]
]
; works: 
view [ttt "foo"  ] 

; error:
view [ttt "foo"[print 'not-default-actor]]
; Script Error: make-actor does not allow none for its <anon> argument
hiiamboris
13:14?? system/view/VID/styles is your tutorial ;)
13:16You don't need to define size, but it should be obvious that if you don't define it - you *have* to explicitly set it in the VID block.
nedzadarek
14:51@hiiamboris apart the type it's not obvious. Why I should define size but not color? Well, I'm going to check system/view/VID/styles.
15:28* put default-actor in the wrong place
rebolek
16:35@nedzadarek basically yes, I chose object, but map or block are fine too.
cloutiy
22:41Could someone explain why I keep getting "keep has no value"? I'm not understanding, since I'm using keep within a collect, and keep is a red word:
; my function
foreach*: function ['items collection body] [
    body: replace/all/deep body 'yield 'keep 
    collect [ foreach items collection body ]  
]

; some test
foreach* i [ 1 2 3 4 5 6 {hello} 45 {world} ] [
    if string? i [ yield i ]
]

==
*** Script Error: keep has no value
*** Where: do
*** Stack: do-file


greggirwin
23:14If I paste your code I get:
*** Script Error: i has no value
*** Where: string?
*** Stack: do-clip foreach* collect string?

do-clip is my own func to do from the clipboard. You need to compose in (items), then I get the error you posted. Remember that foreach itself uses a lit-word argument. I'll also suggest using the same parameter names, if you're using a variant of foreach for the name. Replace modifies the series in place, so you don't need to reassign body:, as another side note.

Finally, as to your real problem, you're running into a subtle behavior of binding (and Red's definitional scoping). The way around it is to compose the body into the body that is collect's arg. Even talking about things like this can show how important context is. :^)
foreach*: function ['items collection body] [
    replace/all/deep body 'yield 'keep 
    collect compose/only [
        foreach (items) collection (body)
    ]  
]

; some test
blk: [1 2 3 4 5 6 {hello} 45 {world}]
foreach* i blk [
    if string? i [yield i]
]

cloutiy
00:53@greggirwin You have o idea how long I've tried different ways of getting this to work. Just when you think you start to get a hang of red, it throws another curve ball at you ;) Thanks so much for your explanation. But looking at your solution I see I was getting there. Was missing the compose .
greggirwin
01:34Note, too, that reassigning body after replace doesn't hurt anything, but it's a subtle idiom that can aid readers. If you don't use the result of an expression, it's a hint that you are relying on side effects.

Red-Beginner
10:07Hello all,
How can I reach value of "x" by use "from"?
Red []
from: 'x
x: [
  [cat dog elegant] 
]
print (from)/1/1
hiiamboris
10:08@Red-Beginner Hi and welcome ;)
Paths cannot start from anything other than a word, so you'll have to use select action.
Red-Beginner
10:09Oh! Thank you so much.
10:14
print select (from) 1
10:16It didn't work.
GalenIvanov
10:52@Red-Beginner
10:53
print pick get from 1

Red-Beginner
10:57Thanks Galen. This is great.
GalenIvanov
11:01@Red-Beginner I'm glad it works for you. If you need an explanation: get returns the value form refers to (x -> [cat dog elegant]), pickreturns the value of the series at the given index.
Red-Beginner
11:11Thanks again.
GalenIvanov
11:12@Red-Beginner :thumbsup:

vazub
13:12Is there a graphic console on *nix? Or is it on Windows only?
greggirwin
16:53The GUI console is written in Red itself.

vazub
06:46I mean Red’s REPL seems to start on Linux and MacOS in CLI mode by default. Is it because there is no GUI support for those systems (GUI is Windows only) or am I missing something here?
ldci
09:18@vazub GUI REPL runs under MacOS: you just need to compile it.
rebolek
09:21@vazub there is GTK branch (not yet merged into master), you can build GUI-console with it
vazub
09:57For context: I am currently working on a Docker image for Red (primarily for MacOS use case), which is essentially based on the latest GTK-branch builds. However, the GUI console is not started by default, therefore I am trying to understand whether this is a bug or intended behavior due to lack of implementation, or merely some quirks related to this particular case (I am forwarding X11 to Xquartz using socat - which seems to work with GUI code overall - >> view [] creates windows etc., but the console itself is strictly CLI).
rebolek
09:58@vazub why is your Docker image based on GTK? There's native GUI support for MacOS.
vazub
09:58because there is no working Red for latest MacOS (it is 64-bit Catalina)
09:59Or do you mean that I should just use latest image built of the master branch?
rebolek
10:04Ok, so the image is based on debian, right? Could it be based on macos? I have no experience with making Docker images, so my question may be stupid.
vazub
10:07Unfortunately, no. Docker is based on Linux kernel facilities for managing containers, or Windows facilities (which is rarely used, unless you develop your server-side stack for Windows). This means that if your host is MacOS - Docker essentially creates a small Linux VM and then layers all the usual container command structure on top. Which results in this: a container is essentially a Linux machine, requiring Linux-builds of Red to funciton.
rebolek
10:22Ok, thanks. Then my advice about using macOS UI makes no sense.

bubnenkoff
12:15Remind me plz how ho add field to object?
>> o: object [a: 1]
== make object! [
    a: 1
]


Now I want add another field to o after it's created
hiiamboris
12:15Not possible.
nedzadarek
12:54@bubnenkoff there will be extend function... but it's not implemented yet. Not sure how it would work though.
There are workarounds depending on what you do. The simplest way is to use map! (or block!). If you have to use an object then maybe you can create another object with old fields, like in this case:
m: #()
m/o: object [ a: 1 ]
m/o:  make o [b: a]
12:56Do I have to init text's size? Or is it a bug:
extend system/view/VID/styles [
    style-name2: [
            template: [
                type: 'text
                size: 200x200
                color: red 
            ]
        ]
]
view [ style-name2]
12:56with type: 'base , the size is set correctly.
hiiamboris
12:59Height must be determined from the font.
nedzadarek
13:05@hiiamboris but I specified both the height and width of the text.
hiiamboris
13:08Would you expect text face also ignore the font and always use a static height?
nedzadarek
13:45@hiiamboris well, that's exactly what it is doing here: view [text "foo" 10x10]
13:48And, yes, I would expect if I specify size it should be exact.
hiiamboris
14:03Okay, you can modify layout function to work as you like.
nedzadarek
14:18@hiiamboris but why should I? In every cases (I guess init shouldn't count) it works as expected -> it sets correct size.
I guess I'll post it in the /bug.
hiiamboris
14:25But it's not a bug.
nedzadarek
14:31@hiiamboris Why?
14:31Unless size is not a size of a face.
14:34this:
extend system/view/VID/styles [
    style-name2: [
            template: [
                type: 'text
                size: 200x200
                color: red 
            ]
        ]
]
view [ style-name2]

is the same as this (without using styles):
view [text 200x200 red]
hiiamboris
14:38No it's not the same. First is template size, second is size override.
nedzadarek
14:49@hiiamboris so...what's the purpose of y value? Is it just discarded?
hiiamboris
14:50Width is used, height inferred from the font.
14:53I guess the height could have been used too, with wrap on. Worth a wish ticket?
nedzadarek
14:53So, size/y is never used?
14:53> I guess the height could have been used too, with wrap on. Worth a wish ticket?

It could be minimal size. It would be easier and less confusing.
14:56btw. is it possible to **not** create a face with init or on-create? I've tried
init [
            print 'initiation
            face: none
        ]

but it won't work (face: make-face 'another-type works for changing face type).
hiiamboris
14:58☻ interesting need
14:58do something erroneous in init maybe? ;)
nedzadarek
14:59@hiiamboris it won't run view block
hiiamboris
15:00True. Well, I'm sure VID is not designed for that. Why do you wanna do this?
nedzadarek
15:01I was thinking about letting user create max number of faces.
hiiamboris
15:02Strange thing to do IMO. You might have all labels in place but the only button will be missing.
nedzadarek
15:04Well, I can put some error message or something.
15:07To be honest, I was writing a tutorial on styles and I was trying to figuring it out what's the difference between on-create and init. One thing is I can set another style/face. I was wondering if there is more.
hiiamboris
15:09init is used internally by the style, while on-create is for the user to override.
15:09Both buggy though https://github.com/red/red/issues/4473 https://github.com/red/red/issues/4454
nedzadarek
15:15> init is used internally by the style, while on-create is for the user to override.

Make sense, as with init you have to create external style (extending built-in styles) but with on-create it's inside block.
hiiamboris
15:22Dunno what you mean
nedzadarek
15:27@hiiamboris never mind - I confused something.
16:12@hiiamboris https://github.com/red/red/wiki/%5BTUTORIAL-EXAMPLES%5D-gui-styles if you want something to add then it would be nice
hiiamboris
16:25Nice!
16:30I didn't know about do-actor and init replacing the face :D
16:30We're still lacking this kind of docs, so much appreciated @nedzadarek
16:31init, on-create and on-created are especially bags of tricks, and when you try to use reactivity inside them... well I hope you don't.
16:32I'd add that do-actor is an internal thing, not guaranteed to not go away. While actors are functions so why not call them directly as face/on-down face event?
nedzadarek
17:00@hiiamboris well, I assumed that if you have some kind of function that runs "on creations" then you can change a face. I've just played a little.

I'm glad I was in use. I use to save simple snippets in files but this topic was little bigger. So... I had to organize it.

I've not played with reactivity for so long... so I don't think I will add something important to this tutorial.

do-actor -> well, I took it from the main page. It has some nice error checking and it checks whenever or not an actor/event exists but face/on-actor face event should be sufficient in a lots of cases.
endo64
21:36Great notes @nedzadarek !
Just a few notes:
> Setting fields with with will not set a field for each style. It will be "global" (will it change?)

This might confuse people, with is not *only* for setting some face fields, it actually just binds the given block to the newly created face object and then evaluates. So you can execute any code in there.
Another small note, latest with block will override the previous ones:
>> view [style btn: base red with [print "I'm Here!" ]  btn with [print "I'll be overwritten :("]  with [print "Here I am!" ]]
I'm Here!
Here I am!
21:41So it doesn't explicitly set words in global context, it just evaluates the block, same as
view/no-wait [bs: base red]
do bind [color: red] bs
do-events

21:58Only (?) with init you can change a face, init block is also bind & evaluated during the face creation (after the face object created before the events triggered).

greggirwin
00:03Thanks for the contribution @nedzadarek !
nedzadarek
13:43@endo64 I didn't want to introduce terms about binding but I will change it a little and I will add another paragraph explaining bindings, init and with.
why 2nd with will override first with?
14:24@hiiamboris I added more info about do-actor: [do-actor](https://github.com/red/red/wiki/%5BTUTORIAL-EXAMPLES%5D-gui-styles#triggering-an-actor)

@endo64 I changed the last sentence a little: [here](https://github.com/red/red/wiki/%5BTUTORIAL-EXAMPLES%5D-gui-styles#global-custom-fields) and added a whole [new paragraph](https://github.com/red/red/wiki/%5BTUTORIAL-EXAMPLES%5D-gui-styles#more-about-init--with)

How do you both feel about those changes. Are they easy to understand?
14:27> Thanks for the contribution @nedzadarek !

You welcome.
endo64
14:48> why 2nd with will override first with?

@nedzadarek It is the current implementation.
hiiamboris
18:01Yes. See also https://github.com/red/REP/issues/74
18:02@nedzadarek :+1:
nedzadarek
20:02@endo64 I see, thank you.
@hiiamboris Thank you. And I've even posted a little snipped.
20:05Although, after trying things for some days, I don't think using extra by style maker & an user is right way.

bkalef88_gitlab
13:49just trying to use to-date to convert a string of yy/mm/dd to a date, and red 0.6.4 doesn't allow it. It works in Rebol, so wondering if I am doing something wrong. I tried a more specific format "yy/mm/dd 00:00:01" as well and also didn't work.
rebolek
13:59@bkalef88_gitlab you need to use load:
>> load "76/03/14"
== 14-Mar-1976
bkalef88_gitlab
14:00ah, perfect. Tx
rebolek
14:08you're welcome
ldci
15:19to-date 1976/03/14 is also running
bkalef88_gitlab
16:25Tx... so this is a recognized date format, what I was trying to do was convert a generated string of a date, to a date.
ldci
17:55@bkalef88_gitlab . OK, I see d: do "1976/03/14" returns a date! type. Similar to load as suggested by Boleslav.
amreus
21:56Question about dockimbel's walk-files.red gist. (https://gist.github.com/dockimbel/1c0f51e3044f23688aae696a28d3096b). The first line of the dive function binds the word 'path to action. Without really understanding what bind does, it appears to make 'path available inside action. My question is how does action know what file is since file isn't bound to action like 'path is?
hiiamboris
22:06bind action 'path is the same as bind action context? 'path which in this case is the same as bind action :dive, thus it exposes arguments and locals of dive to action. file is one of those locals (function collects foreach argument as a local).
amreus
22:39> bind action 'path is the same as bind action context? 'path

Is this substitution true in all uses of bind or specific to this example?

hiiamboris
07:56True in all uses.
nedzadarek
10:58Can you rotate (or in general transform) faces? I would like to do something like this:
view [
    style s: base red 100x20
    
    s 
    s rotate 90
    s rotate 180
    s rotate 270 transform -100x20
]

Or is it only for a draw?
hiiamboris
10:59Yes, only for Draw.
nedzadarek
11:00@hiiamboris thank you.
amreus
21:41Thanks @hiiamboris. Is there an advantage to using bind action 'path followed with do action instead of having action be a function and then calling the function?
hiiamboris
21:46Probably not ;)
amreus
21:50Well, I read that functions are just syntactic sugar for binding so... probably not?

GiuseppeChillemi
19:30I am trying to understand if there is a way to have functions with no arguments inside other functions. They will use words in the container function context. I have tried this code in the console but I can't understand how context is working.

>> a: func [x] [fnc: [probe x] do fnc] ()
>> a 1
1
== 1
>> a 2
2
== 2
>> a 3
3
== 3
>> a 4
4
== 4
>>

Until now I have thought the context was bound to the block words at block loading. Also I know that at each execution of the function a new context is created. But which context is bound to X in my example? The block is static between function iteration, so I suppose that once the function is created it will have the context of the first run but X returns results reflecting the current argument value. So X is not bound to an "absolute context" connected to the function. It is the one of the current run. But how is happening the rebinding or the context retrieval? The X context is not a fixed one, it seems different at each run!
Is it taken from the current function one?
Is a block rebinding happening at each run?
hiiamboris
19:33Do you have links to my previous answers about function context? ;) It's all there.
GiuseppeChillemi
19:33Not on that particular situation.
19:34(But I have all the others!)
hiiamboris
19:37:point_up: [October 10, 2019 6:55 PM](https://gitter.im/red/help?at=5d9f5473940b4c2fc0abfafd)
19:37No it's not recreated. Why would it be?
19:38And works like a stack.
19:38That's all there is to it.
19:38What you do with a function call is just set values of that context.
19:41Think simple man ;) You're always overcomplicating things.
GiuseppeChillemi
19:47I always have multiple explanation. It is difficult but also nice thinking this way.
theSherwood
20:13This has been tricky for me. I'm so used to using closures all over the place. I find I keep reaching for to use closures in Red only to rediscover that it doesn't work. I haven't adapted yet.
hiiamboris
20:15@theSherwood https://github.com/red/red/wiki/%5BNOTES%5D-Closures this may help? ;)
20:16R2's functions were closures IIRC, but this created unnecessary GC load.
theSherwood
20:22Oh awesome! thanks!
GiuseppeChillemi
20:27@hiiamboris Let's suppose a function with args and locals is being invoked, X is part of locals. You pass the arguments and the respective context entries are set. X is set to a value during the first run. Then you invoke the function for the second time with different arguments, local values are cleared, aren't they? I have tried and it seems they are set to none at each run.
>> a: func [val /local x] [probe x if x = none [x: val] fnc: [probe x] do fnc]
== func [val /local x][probe x if x = none [x: val] fnc: [probe x] do fnc]
>> a 1
none
1
== 1
>> a 1
none
1

Do you confirm?

hiiamboris
20:28Of course. Refinements are set to false and other values to none.
GiuseppeChillemi
20:29And what happens when refinement is not provided and refinement has arguments? Is the context of the word the main one or the local one and argument value is none too ?
hiiamboris
20:31Try it ;)
theSherwood
20:34
f1: func [/local x][
	x: []
	append x 1
	print x
]

f1 ;-- 1
f1 ;-- 1 1
probe body-of :f1 
; [
;    x: [1 1]
;    append x 1
;    print x
;]
GiuseppeChillemi
20:34I knew you would have answered that but I was really lazy and I have tried. You are not permitting this to me!
hiiamboris
theSherwood
20:35So I think I understand that part. But what I don't understand is the following:
20:36
f1: func [/local x][
	x: copy []
	append x 1
	print x
]

f1 ;-- 1
f1 ;-- 1
probe body-of :f1 
; [
;    x: copy []
;    append x 1
;    print x
;]

20:37When 1 is appended to x, where is that data stored? Where is x?
hiiamboris
20:37https://github.com/red/red/wiki/[DOC]-Why-you-have-to-copy-series-values
20:38TL;DR: copycopies the empty block, every time.
theSherwood
20:38I've read that and I get the general idea (I think). But I still don't quite get where the data for x is.
hiiamboris
20:38What do you mean by "where"?
theSherwood
20:41As in, during the function call, x takes on a particular value [1] by the end of the function. But unlike the first example, that change isn't reflected in the function body after the fact.
20:41So is that x: [1] just on the stack somewhere but doesn't get placed in Red's representation of the code?
hiiamboris
20:42Literal blocks statically lie within their parent literal blocks. In the case of f1 you have 3 literal blocks: [/local x] [x: copy [] append x 1 print x] and [] inside it.
20:43copy does what you expect of it: copies the given block and returns the new one. x is now a copy. It's not anymore the same [] block that is within the f1 body.
theSherwood
20:43With you so far...
20:44I *think* I understand up to that point
hiiamboris
20:46As to where it is - within Red memory segment. It is not freed by GC because x points to it and x is locked by the function body during evaluation.
20:46Same for the f1 and it's parts actually. Long as you have access to f1, you don't lose it.
theSherwood
20:46And then gc frees it after the function returns?
hiiamboris
20:48GC frees it when it kicks in. That usually happens when new allocation is requested and especially often when it can't allocate new chunk without growing the memory.
20:48But if you return the value of x, you now have it on the stack or assigned to something, so it's not lost.
theSherwood
20:48I see. But unless you return x, that value is now inaccessible?
hiiamboris
20:49Yes.
theSherwood
20:49Whereas the static representation (which can, in fact be updated as in the first example) won't get thrown away because it's static?
20:50That's not quite right is it?
20:50Red doesn't actually see a difference between these two types of things does it?
hiiamboris
20:51> won't get thrown away because it's static?

No, because you have a link to f1, which in turn links to it's body, which links to [].
20:52The root is system/words
theSherwood
20:53Okay. So in the first example, root links to f1 which links x and thereby to []?
hiiamboris
20:53Yes ;)
theSherwood
20:54But in the second example, root links to f1 which links to x which does not link to []?
hiiamboris
20:55Body of f1 is just a block. It has a word x which refers to no value after the f1 returns, and it has a literal block []. But not your copied block.
theSherwood
20:56Ah okay. f1 does link to [] because it is inside it. But the copy of [] is not linked.
hiiamboris
20:57You get it ☻
theSherwood
20:57So are there 2 x in memory?
20:57Haha. I'm not sure I do yet!
20:57The x that f1 links to, and the other x that is waiting to be garbage collected?
hiiamboris
20:58x is a word, it's not collected.
GiuseppeChillemi
20:58> And what happens when refinement is not provided and refinement has arguments? Is the context of the word the main one or the local one and argument value is none too ?

>> y: 33 a: func [/ref y] [probe y]
>> a
none


So the context contains the refinement arguments statically.

Also, the whole context is RESET between invocations and there is not persistence of values at all.

The only tecnique to have persistence between invocations is using a block like x: [1]
hiiamboris
20:58Block that x refers to may be collected.
theSherwood
20:59Ooooh. Okay. x can't be collected. But how about x: [1]?
20:59Because that is a set-word rather than a word
hiiamboris
20:59x: won't be collected as it's a flavor of a word (anyway, a scalar).
21:00[1] because you have a link to it.
theSherwood
21:00Okay.
21:00But the meaning of x is getting collected?
21:01Once 1 is appended to x, how does Red know to associate x with [1]?
hiiamboris
21:02Meaning :)
You should get your terminology straight.
1 is never appended to x, but to the value x refers to, in your case a block.
21:03> how does Red know to associate x with [1]?

That's the property of words. They have a link to a context. And in that context the same word has a link to a value.
theSherwood
21:03Haha. Yeah I'm not sure how to refer to things in Red. It feels subtly wrong to refer to the value of x when it doesn't act as a variable.
hiiamboris
21:03I think @GiuseppeChillemi may recall a nice graphic illustration. Maybe he'll show it ;)
theSherwood
21:05Oh okay. So there is a context created by the call to f1 and not only the definition of f1 which exists in a context that wraps around f1?
21:05f1 points to this new inner context during the function call and then not again?
hiiamboris
21:06No. func creates a context. But function context is a stack. That is, it is layered ;) You call f1 - a layer of values is added. You return - the layer is stipped away.
theSherwood
21:07Oh that's right. func creates a context which is how you have /local words
hiiamboris
21:09To blow your mind further, local is a normal refinement:
>> f: func [/local x] [local: 100 print [local x]]
== func [/local x][local: 100 print [local x]]
>> f
100 none
>> f/local 200
100 200
21:10It's no different from arguments.
greggirwin
21:10@hiiamboris it's almost cruel to lead people to the edge of understanding, then push them off the cliff. :^)
hiiamboris
21:10I just knew you were watching ;)
theSherwood
21:10So in the second example, the value of x is [1] only in the second context. But the value of x as copy [] still exists in the first context. Whereas in the first example the second context created from the call to f1 does not assign a new value to x?
greggirwin
21:10It's a great chat though, and worth noting somewhere.
theSherwood
21:11Wait? What?!
21:11/local is just an argument? hahaha
greggirwin
21:11I hear @theSherwood falling now... ;^)
hiiamboris
21:11Haha :D
theSherwood
21:12hahaha
greggirwin
21:13@theSherwood you'll sometimes here someone say (maybe just me) that "Everything in Red is data until it is evaluated." Then it becomes all about understanding when and how things are evaluated in a given scenario (I'd say "context", but that would be confusing, as it's not the same as context).
theSherwood
21:14So the "context" created by func is the first kind: "context", but not context?
hiiamboris
21:15Don't worry, you'll climb back up eventually ;)
21:15It seems we've totally confused you though now.
theSherwood
21:16Under the hood, a call to func sets the value of local to true or false in the new context created by the function call?
hiiamboris
21:16Time to do your own homework ;)
greggirwin
21:17Story time. At the Rebol Davis DevCon in '04 (I think) I gave a talk about dialects, and asked what people thought the most frequently used dialect in Rebol was. VID and parse were the clear audience favorites, but it was a trick question. Carl was in the front row, looking at who was voting for what, and getting very excited. I finally told them they were all wrong, and asked Carl to tell them.

Can you guess what it is?

Hint, it's related to "context" not being the same as context.
theSherwood
21:17func?
greggirwin
21:17Correct. :^)
GiuseppeChillemi
21:17@hiiamboris Do you mean this one?
:point_up: [10 novembre 2019 21:44](https://gitter.im/red/help?at=5dc876beeeb63e1a838d9111)
hiiamboris
21:18@GiuseppeChillemi It's a good one.
theSherwood
21:19hahaha. How long does it take to hit bedrock? I keep trying to pull up the carpet to find another layer of carpet underneath.
greggirwin
21:19It's a deep lake.
GiuseppeChillemi
21:20There is also the graph on nice [Vladimir Explanation on meaning](https://gitter.im/red/help?at=5dc6026e4adf071a84f6afb7)
:point_up: [10 novembre 2019 20:10](https://gitter.im/red/help?at=5dc860984adf071a8406c574)
hiiamboris
21:21Let's hope it will help ;)
greggirwin
21:21But not so deep that you can't glimpse the bottom, which may be enough for a long time. You, @theSherwood, are the type who wants to find the bottom and then go into the deepest trench in a bathyscaphe. :^)
21:22Most Reducers can happily just paddle on the surface, ignorant of the depths, safely leaving the Kraken sleeping.
hiiamboris
theSherwood
21:24Haha. I don't know how to do a thing but to dive in the deep end.
greggirwin
21:24So, not even a snorkle, just free diving.
theSherwood
21:25Yeah. Unfortunately, I'm not a great swimmer. ;)
greggirwin
21:25Beware the Kraken then. You've been warned. ;^)
theSherwood
21:25haha
21:27Thanks for answering all my questions, everybody. And those are some good resources. I think what I need is to figure out what functions or other language constructs create bindings.
21:28Is there a list, by chance?
hiiamboris
21:29You read what Giuseppe linked you first.
theSherwood
21:31I think I understand that far. I think what I don't know to anticipate is what is going to create a new binding and then how or at what point that binding gets eliminated.
hiiamboris
21:32set creates and destroys both.
theSherwood
21:33Sorry, I should say rather, the context of a binding.
hiiamboris
21:33func and context (and their equivalents)
theSherwood
21:34context and make object! create contexts. func creates contexts. function calls create context. VID and parse...
hiiamboris
21:34> function calls create context.

Nah-nah. That's just in Giuseppe's world, not relevant ;)
theSherwood
21:35Haha. I'm lost again.
hiiamboris
21:35> VID and parse...

These are DSLs, not contexts.
theSherwood
21:35But they change the values of words, right?
hiiamboris
21:36Sure.
21:36In an existing context.
theSherwood
21:37Oh. So if you use something like button outside of a view block, it has the same value as within?
21:38Hmm. That's not a great example.
hiiamboris
21:38Sleep on it.
21:39Morning makes such things clearer ;)
theSherwood
21:41
view [
  btn: button "click here" [ alert "I've been clicked" ]
]

probe btn


btn is a face outside of the view block. So not a different context. Gotcha.
GiuseppeChillemi
21:41@theSherwood Adam if you call them Variables you think about them as containers which is WRONG! Word are not filled in Red but *LINKED* to tables where they have a their value. In each table you will find their name and the value. This table is called "context" but is just a table. So if word is LINKED to a context where its value is 1 then it will get this value. If you link the word to another context it will take another value. You manipulate the link with BIND. BIND = LINKER.
The link is invisible but it is present in each instance of a word.
Remember that [A A A] is a block with 3 elements and each A has its own link. Once you REDUCE the block Red will scan the link (the context) of each one and will return the value associated to each instance of to the word A. So REDUCE [A A A] can return [33 55 "HELLO"] if 3 different links exists.
theSherwood
21:43I *think* I understand that much, in theory.
GiuseppeChillemi
21:44Well, good!
theSherwood
21:44So when func creates a context, it only binds the /local words to it? All the other words are still bound to the outer context?
GiuseppeChillemi
21:45The local words and arguments.
theSherwood
21:45Oh right. Arguments too.
GiuseppeChillemi
21:47Then the function block will have an hybrid set of words, some linked to the global context, some other to the function one.
theSherwood
21:47And then when the function is called, words get rebound.
GiuseppeChillemi
theSherwood
21:47I mean, in the case of some kind of set or set-word?
21:48
f1: func [/local x][
	x: []
	append x 1
	print x
]
GiuseppeChillemi
21:49Words are bound at function creation to the function context. When it is called Red takes the value from it.
theSherwood
21:50Okay. Is x being rebound to [] every time the function is called? But [] is always the same [] that was bound to the function when the function was created?
greggirwin
21:50@theSherwood you don't do system level work yet, but you could still skim some of the R/S source for word, object, context, and function. You might find some clues.

Something that isn't obvious, which is different, is that words carry their context with them.
hiiamboris
21:53@theSherwood You're still seemingly thinking that binding relates word to a value. While it is not ;)
theSherwood
21:53I will definitely do that.

> words carry their context with them

I figured that something like that must be happening given the examples given of [rock rock rock].
21:54@hiiamboris You're right. I said "x being rebound to []"
21:56x's binding isn't changing at the function call, it is simply getting re-set?
hiiamboris
21:56Yes.
theSherwood
21:58
f: func [/local x][
	x: copy []
	append x 1
	print x
]
21:59x is getting set every time, but the *context* is not being edited as in the previous example, where [] (which exists in the function context) was getting appended to?
22:01Sorry, the context is not being edited.
22:01Something in the context is changing, but none of the bindings in the context itself.
hiiamboris
22:02Sort of. Wording is wrong, but it's okay for now.
theSherwood
22:03Okay. Yeah. I'm not expressing it to my satisfaction.
GiuseppeChillemi
22:03Functions code block is a container which exists in memory at LOAD time and it has a context BEFORE it is executed and it is the global one. When your code CREATES a function Red takes its code block and RELINKS its words to the function one. Which words it will relink? Just LOCALS and ARGUMENTS. which are in the function context! Each time you CALL a function, it takes the existing context and sets each of its word to the corresponding ARGUMENT and none for LOCALs and then the block evaluation starts!
theSherwood
22:06
f: func [ /local x ][ x: copy [] ]
22:07glocal context includes: f, func, copy, and []
function context includes: local, x
GiuseppeChillemi
22:08GLOBAL context is just a giant table couple of WORDS and VALUES
22:08[] is not in the global context.
hiiamboris
22:09because it's not a word :)
theSherwood
22:09Gotcha.
22:10So [] does not feature in any table, then?
GiuseppeChillemi
22:12Remember this point: context of function is created when Red encounters

f: func [ARG1 ARG2 /local x ][ probe ARG1  x: copy [] ]


22:13And contexts contain only WORDS.
theSherwood
22:13Table of keys and values as key/value pairs?
GiuseppeChillemi
22:14Bingo!
theSherwood
22:14Okay. Thanks for your patience everybody. I'm going to dig into some code and see if I can make it click!
GiuseppeChillemi
22:16
f 1 3
it changes ARG1 ad ARG2 keys values in the function' context so when the code runs, it queries the context for ARG1 and it will return 1 and 3 for ARG2>
theSherwood
22:17That makes sense
hiiamboris
22:18Best code to dig in is https://gist.github.com/9214/cf24ff767f6167ab16203b77b06e2a82 ;)
theSherwood
22:19Thanks!
GiuseppeChillemi
22:21From some months I am starting to think that that the database TABLE and KEY/VALUE concept together with linking, storing and querying is a good way to explain contexts. It is an universal paradigm as databases are used by every programmer in any language.
22:39Now I have a question for me: nested stack calls of the same function do not delete the values set with the previous calls. So when the most recent one ends the previous values are recovered. How does this happen if the function context is just one?
22:41(@hiiamboris this has been the source of my confusion: recursive calls and context(s) )
23:03(*nested calls/stacked calls)

hiiamboris
08:27I believe I stressed *at least* four times to you (or in your presence ☻) that function context behaves like a stack.
GiuseppeChillemi
08:51It was not in my presence, I have been searching for my graph when you have told to Adam that stacks values are layered. Now that you have written this have scrolled backward and found your message to him:
08:51> No. func creates a context. But function context is a stack. That is, it is layered ;) You call f1 - a layer of values is added. You return - the layer is stipped away.
08:52Thanks that was a missing part in my knowledge. You have always great patience, at least four times bigger than other members!
hiiamboris
09:53Thanks
Red-Beginner
15:35Hello all.
When I use this codes I want coordinate of face to change. But it isn't work.
view [
  size 300x300
  at (face/offset) 
  button red
]

Note: I know there is "loose" face.
9214
16:14Hi @Red-Beginner, what is it that you are trying to do, and what the error message you get says?
Red-Beginner
16:41Hi, Vladimir. There is no any error. I want to change coordinate of button when a move mouse.
9214
16:43When you move a mouse or when you click on a button and drag it?
17:04@Red-Beginner either way, if you want the button to follow mouse pointer:
view/flags [size 500x500 on-over [print ["Button is at" foo/offset: event/offset + 20 "coordinate."]] foo: button] 'all-over

And if you want the button to be draggable:
view [size 500x500 button loose on-drag [print ["Button is at" face/offset "coordinate."]]]

Red-Beginner
17:07Thanks. I will try.
wallysilva
17:14@9214 On the first example, why is foo necessary and what 'all-overdoes?
9214
17:17@waglebr you need to refer to the button somehow (in this case by a name foo) in order to update its position. all-over flag is described in [View documentation](https://github.com/red/docs/blob/master/en/view.adoc#2-face-object).
wallysilva
17:19@9214 But why referring to the button as button/offset doesn't work?
9214
17:19@waglebr what's your guess? Hint:
view [button button]
wallysilva
17:20print can't access the button properties?
9214
17:22No, button is a VID keyword which describes a type of the face; you can have many buttons, but you cannot refer to either of them by their type.
17:23You can call your button a button of course:
view [button: button "Click" [probe button/text]]
wallysilva
17:25I'm a bit confused because this works though:

view [button "Move text" on-over [face/offset: 30x20 face/text: "Now I'm here"]]
hiiamboris
17:26Nice to see you back @9214 ☻
9214
17:27This works because face inside on-over actors refers to that particular button face. Internally each actor is a function with two arguments, face and event.
17:30@waglebr since you work as a translator, a linguistic analogy might help. Each thing has a [common name](https://en.wikipedia.org/wiki/Proper_noun#Common_and_proper_nouns) and a proper name. The common name of faces is their type, it describes to what "class" of graphical widgets they belong. The proper name of a face is whatever you call it, and sometimes it can be entirely omitted, e.g. you can use face so that face can refer to itself even without knowing its proper name, or you can index a face by a path to it, or by any other indirect means:
view [button "Click" [face/parent/pane/1/text: "Clicked!"]]

17:37@hiiamboris [a menace to the entire city!](https://www.youtube.com/watch?v=UJ5dwtRxI0Q)
hiiamboris
wallysilva
17:47@9214 My bad, I misread your code!
You declared the button at the end of the code and I thought you had already declared it at the beginning.
What I was trying to do was a version of your code without foo and now it works:

view [button on-over [print ["Button is at" face/offset: event/offset + 20 "coordinate."]]] all-over
17:47Thank you for your explanations!
9214
17:53@wallysilva I see what you mean. Inside VID block, actors that follow right after (optional) container settings are related to the container (i.e window) itself.
view [on-down [print ["I am a" face/type]]]
wallysilva
18:12@9214 Oh I see, thank you!
Red-Beginner
18:12Vladimir, I think so I made a error by use "face/offset" . Maybe it will work to use like thing "/offset".
9214
18:14@Red-Beginner can you show me an example?
Red-Beginner
18:15I did not use yet!
view [
  size 300x300
  at (/offset) 
  button red
]

or
view [
  size 300x300
  at (x/offset) 
  x: button red
]
9214
18:27@Red-Beginner I'm afraid none of the two examples will work. at takes an expression which specifies where the next widget should be placed, so this expression should return a pair!:
view [at random 300x300 base red]

Furthermore, VID has no knowledge of x at the time it evaluates x/offset, you can refer to x only after the button was defined, e.g. inside a do block:
view [x: button do [x/offset: x/offset + 10x10]]

Remember that both [VID](https://github.com/red/docs/blob/master/en/vid.adoc) and [View](https://github.com/red/docs/blob/master/en/view.adoc) have reference documentation that specifies how they work. If it looks too complicated, try out examples at [Red by example](https://www.red-by-example.org/vid.html) or [Helpin' Red](http://helpin.red/GUI.html).
Red-Beginner
18:34I will work on it. Thanks.

Palaing
14:28How could I force "keep" result to string? For instance in:
>> list: "abc, a, bc"
== "abc, a, bc"
>> parse list [collect [some [keep to ", " 2 skip] keep to end]]
== ["abc" #"a" "bc"]

I would need the #"a" to be "a"
toomasv
14:41@Palaing You’ll have to use copy.
Palaing
14:42@toomasv thanks. I tried but missed the right way to combine copyand keep
I'll try again :)
14:53@toomasv got it:
thing: [copy x [to ", " | to end] keep (x)]
>> parse list [collect some [thing 2 skip]]
== ["abc" "a" "bc"]

I was trying to put the "keep" within the parentheses...
Thanks again!
hiiamboris
15:06Just keep copy to ", " and keep copy to end.
9214
15:06
text
>> split "abc, a, bc" ", "
== ["abc" "a" "bc"]
hiiamboris
15:07Or this ☻
Palaing
15:11@hiiamboris it seems this does not work on my example...
@9214 yes this works in this case but not anymore in my real (more complex) case...
9214
15:12
text
>> parse "abc, a, bc" [collect some [keep copy _ to [comma | end] [end | comma space]]]
== ["abc" "a" "bc"]
Palaing
15:13@9214 great! keep copy _ is nice.
greggirwin
15:16Do we have a parse (basics) wiki page for things like this?
9214
15:18[We do](https://github.com/red/red/wiki/Parse-Cookbook).
Palaing
17:05That's useful. But I had never come across this use of _ (like in keep copy _). It sounds to me like a trick. Is it a feature of parse ? I did not find any mention of it in the docs
9214
17:08@Palaing see [here](https://github.com/red/docs/blob/6c63f35b92d433841cb3981dddfec88136206c01/en/parse.adoc#copy). _ is just a throwaway word.
17:27I didn't document keep copy idiom because, technically, copy here is not an option like e.g. pick, but a separate rule; it's just that Parse [handles](https://github.com/red/red/blob/a1d14954e5c906556d0e29fb4266951549db935f/runtime/parse.reds#L1061) it in a specific way.
This makes sense if you think of copy as _matching_ portion of the input (i.e. not a single value, but a series with zero or more values inside) and keep preserving the _match_.
>> parse "a" [collect keep skip]
== [#"a"]
>> parse "a" [collect keep copy _ skip]
== ["a"]
>> parse "a" [collect keep pick copy _ skip]
== [#"a"]

There's also [this](https://github.com/red/red/wiki/%5BDOC%5D-Guru-Meditations#parse-collectkeep-options-combined-with-tothru-rules) entry that described how various combinations of collect/keep work, perhaps it should be moved into Parse Cookbook.
hiiamboris
17:31I think it's worth noting in Parse docs, like done in Guru meditations - as an opposite to keep pick.
17:32Option or not, it's a question everyone asks at some point.
9214
17:32Fair point.
hiiamboris
17:37For me also keep copy didn't click right away because I thought keep would copy it, and I'm copying it with copy again, so what a waste. I wonder if it's true? ;) If not, then there should be a special case for it in parse.
17:39Just checked, there's a single copy only, judging by memory stats.
9214
17:40When Parse processes keep, it checks if there's a copy sub-rule; if there is, then it preemptively fetches the value slot into which the matched value will be eventually copied, and then appends content of that slot as-is. You can see it in the code I gave above.
17:41I mentioned at some point that Parse collect needs a design review. This particular case always seemed to me as a crude workaround.
17:45https://github.com/red/docs/pull/236
hiiamboris
17:48:+1:
Palaing
18:22:thumbsup:
greggirwin
19:53+1 both for putting this all in the cookbook, and the review. It's confusing. @Palaing if you'd extract the bits of this chat, and link to it, in the wiki, @9214 and @hiiamboris can make review notes.

wallysilva
20:04Hi guys, I already asked this question before and I thought that I had understood the answer, but I guess I didn't.
Why a: random 100 always returns 53 as the initial number? I can close and reopen the console and I always get 53.
Why it doesn't generate a different number?
greggirwin
20:11Did you try ? random? If you want different results, use /seed. The behavior is by design, so you get reproducibility by default.
wallysilva
20:18Ok, so random without a seed will always produce the same sequence of numbers, is that right?
hiiamboris
20:32Yes.
wallysilva
20:42Alright, I guess now I got it. Thanks guys!
20:43I'm adding that to the [Beginner's FAQ](https://github.com/red/red/wiki/Beginner's-FAQ)
21:05Done
hiiamboris
21:19Maybe you should split general questions from such very specific questions. Like we agreed, more info =/= better introduction.
21:20Besides, design of random is common across languages I've seen
21:21I think even in BASIC you have to seed it ;)
wallysilva
22:09I never had to seed it before when I played with Python, JS or Ruby, that's why my confusion.
In fact, in Ruby, you just do rand 100 and you get a random number from 0 up to 100.
I'm removing the random question from the Beginner's FAQ until I can find a better place for it. Thank you for your recommendation.

toomasv
03:39 @wallysilva There was an interesting chat and code snippet about random :point_up: [Aug 15 2019 21:56](https://gitter.im/red/red?at=5d55aacd4e17537f5239de0c)
wallysilva
07:14@toomasv Thank you for pointing me to that, very interesting indeed. Great conversations going on back then!
I think now is very clear in mind how random works in Red, thank you guys! :)
toomasv
08:50:+1:
wallysilva
13:51

1 - Is Red your first programming language?
2 - Coming from Rebol?
3 - Coming from other programming languages?
4 - Technical questions?

And then it could eventually be merged with the official [FAQ](https://github.com/red/red/wiki/%5BDOC%5D-FAQ)>
9214
14:17@wallysilva
1. Not addressed;
1. [Coming from Rebol](https://github.com/red/red/wiki/%5BLINKS%5D-Coming-from-REBOL);
1. [Feature wars](https://github.com/red/red/wiki/%5BDOC%5D-Red-Should...-%28Feature-Wars%29); I remember seeing a page in the form "Red for X programmer", but cannot find it;
1. [Guru meditations](https://github.com/red/red/wiki/%5BDOC%5D-Guru-Meditations).
hiiamboris
14:48@9214 knows resources better than anyone ;)
14:48Official FAQ is a mess IMO too and needs work.
14:49Like, on my memory this question "Why is the header case sensitive?" never appeared. So much for "frequently asked" ;)
14:49Why would a beginner even care?
ne1uno
15:05obscure error qualifies. *** Error: not a Red program!
hiiamboris
15:11Right. Could have been more descriptive.
15:13If anyone can come up with a good error message, I will add it to PR https://github.com/red/red/pull/4147
ldci
15:48@ne1uno is your program header correct?
wallysilva
15:50@9214 I could lazily point it out that 2-4 are not FAQs, but instead I will try to explain what I would like to achieve.
I've just joined the community a couple of weeks ago and I've already seen some repeated questions here (in fact I myself asked the same question twice in order to put a more complete answer together).
So, I think it would be nice to have a place with all those questions and answers that users could consult with a simple Ctrl+F.
And in case they needed more details or clarifications they could come back here with a better understanding of the matter.
That would save all parties involved a lot of time.
9214
16:17> So, I think it would be nice to have a place with all those questions and answers that users could consult with a simple Ctrl+F.

StackOverflow?
16:19Github wiki is ill-suited for a knowledge base for a number of reasons: no search by page's content, page's links change when the title of the page changes, no tags, and limited categorization.
wallysilva
18:07Got it
[This](https://learningred.wordpress.com/2020/07/15/a-faq-in-red/) is my personal solution for now :)
theSherwood
18:12:thumbsup:
hiiamboris
18:20Nice title ;)
wallysilva
18:21Hah
Thanks!
9214
18:39Good job @wallysilva, but consider linking to the existing wiki entries rather than copy-pasting them, that way information in your blog won't get outdated. The question about compiler accepting dynamic code, for example, does not address the Encap mode and --encap toolchain flag.
18:41And some of the questions that you addressed aren't that frequent really, e.g. Sphynx came up only once from someone with Python background.
wallysilva
18:59@9214 Linking each entry defeats the purpose since the whole point is to be able to search everything in one place either by category or Ctrl+F.
I have added a "disclaimer: This FAQ is a compilation of the official ones and may be outdated" with a link to the Wiki.
The idea behind the blog page is not to be thorough or replace the original FAQs, but rather facilitate my own studies until we can find a better solution for the official ones.

toomasv
04:38@wallysilva Good work! :+1:
wallysilva
04:43Thanks @toomasv ! 😁
Red-Beginner
20:08Hello all,
I'd like to know that how can I assigning a value to the variable while I remove it from the block?
This script didn't work. 😔
Red []
x: copy ["a" "b" "c"]
A: remove random/only x 1
remove x ""
B: remove random/only x 1
remove x ""
C: remove random/only x 1
remove x ""
print A
9214
20:11@Red-Beginner try help take in the console.
Red-Beginner
20:17Like this?
take remove random/only x 1
It didn't work.
greggirwin
20:19help random. :^)
20:20And what is 1 doing in your example?
Red-Beginner
20:21
Red []
x: copy ["a" "b" "c"]
remove random/only x 1
probe x  ; ["" "b" "c"]
remove x ""
probe x  ; ["b" "c"]
9214
20:21@Red-Beginner your code pick a random string out of 3, removes a single character out of it, then takes nothing out of remaining empty string, and then returns 1.
Red-Beginner
20:22I just want the removed value.
greggirwin
20:23@Red-Beginner play with each function separately to make sure you understand them.
9214
20:24
text
>> block: [a b c]
== [a b c]
>> value: take block
== a
>> block
== [b c]
>> value
== a
Red-Beginner
20:25But I want to choose randomly.
9214
20:25So you want to take a random value out of the block so that block is modified?
Red-Beginner
20:26Yes and remove
greggirwin
20:26@Red-Beginner are you using the Red console?
Red-Beginner
20:27No I'm on the tio.run
greggirwin
20:28Use the force, er, console. It looks like you don't yet know what args the funcs take, based on your use of 1 and "" in your examples. Use help. Try each function separately.
Red-Beginner
20:31Thank you sir. Please look at this.
x: copy ["a" "b" "c"]
remove random/only x
probe x  ; ["a" "" "c"]
; But I want "b"
greggirwin
20:32Which tells me you don't understand things yet. :^)
Red-Beginner
20:33😭
20:33Sorry
greggirwin
20:33We understand what you want. Help us to help you, by listening to our suggestions.
9214
20:33@Red-Beginner we can give you a code to solve the problem, or we can help you to learn Red. Which of the two do you want?
Red-Beginner
20:34Okay Mr. Gregg I try.
greggirwin
20:35:+1: :^)
Red-Beginner
20:35Thanks Vladimir. I want second.
9214
20:36@Red-Beginner OK, but then you really need to use help in the console and study embedded documentation for all the functions that you used.
Red-Beginner
20:38Okay I will. Thanks again.
greggirwin
20:38red-by-example.org can help as well.
Red-Beginner
20:56"take" is working well.
Is there a command like "take/random" 🤭 Because this code always gives value "a":
x: ["a" "b" "c"]
A: take random x
print A
hiiamboris
21:02No, there isn't ☻
nedzadarek
21:14@Red-Beginner keep in mind that random starts at the same "part". So every time you paste it into new console (or compile & run exe) it should "output" the same thing. In your case "a". You can change "the part" this way:
x: ["a" "b" "c"]
random/seed now
A: take random x
print A

now returns current date & time.
ps. keep in mind with such small array you can still get "seems not random" results.
21:16Why one word works and another doesn't:
extend system/view/VID/styles [
    custom-progress: [
        default-actor: on-down
        template: [
            type: 'base
            draw: copy [ 
                transform 50x50 0 1 1 20x0 [fill-pen progress-color box 0x0 20x20]
                ;transform center-of-rotation 0 1 1 20x0 [fill-pen progress-color box 0x0 20x20]
            ]
            progress-color: purple
            size: 100x100
            center-of-rotation: 50x50
        ]
    ]
]
 view/no-wait [
    cp1:  custom-progress 
]

progress-color works, center-of-rotation doesn't work. It gives me: *** Script Error: invalid Draw dialect input at: center-of-rotation 0 1 1 20x0 fill-pen progress-color box 0x0 20x20.
ps. just comment & un-comment lines with transform.
ps2. Red 0.6.4 for Windows built 20-Jun-2020/19:24:25+02:00 commit #4d864b1
Red-Beginner
21:18Yes now I get it. I did everything wrong.
21:19Thanks..
9214
21:20@Red-Beginner for example:
>> block: [a b c]
== [a b c]
>> value: take at block random length? block
== b
>> block
== [a c]
>> value
== b
Red-Beginner
21:23Oh. I'm very stupid. 🙈
9214
21:24@Red-Beginner not at all! It takes practice to arrive at any solution. Your task now is to understand how it works and come up with a better alternative :wink:
Red-Beginner
21:26I have something in my mind. I will practice.
21:26Thank you all.
9214
21:28This actually gave me an idea that random/only should rather randomize series' index.
nedzadarek
22:06@Red-Beginner

> Oh. I'm very stupid. 🙈

Maybe you are used to, from different languages, that random function returns different values at start. Just be careful when you see random without random/seed.
22:23Hmm... so some draw's commands accepts word! and some don't. Would it be possible that all commands would accept word!? For example: transform center angle scale-x scale-y translation [box start-pos end-pos]. If not all words, could it at least check for words defined in a template, for example:
template: [
    type: 'base
    draw: copy [box _start _end]
    _start: 0x0
]

would cause an error because _end is not in the template.
22:24Changing _end to 10x10 would be correct - what do you think about it?
9214
22:42https://github.com/red/red/issues/1434
nedzadarek
23:19@9214 :+1:

Red-Beginner
07:20@nedzadarek I'm familiar with "random/seed" from Lua. But I didn't realize it until you showed it to me.
Oldes
08:31Honestly I consider it as a bug that Red does not seed automatically on boot as other languages.
wallysilva
16:14@Oldes I felt like you at first, but I've been thinking about it for a while now and I came to the conclusion that having to set a seed before getting a random sequence is actually a good "reminder" to choose a proper seed according to the task at hand.
Oldes
16:16I don't think it is good reminder... but rather a good chance to forget to do it. Of course... it is always good to seed it again using own rules.
wallysilva
16:18In my case, it worked as a reminder because I kept getting the same number over and over again! 😅
Oldes
16:18But when thinking about it... maybe the seed is not used by design as Red is still in alpha version and to be able reproduce bugs is important and not using seed may help it.
16:20Anyway... I simply cannot imagine that one would have to explain all javascript folks (for example), that they have to seed random before using random function.
hiiamboris
16:25Well, seeding by default is no problem, as to reproduce bugs, we can always add random/seed 1 or smth.
nedzadarek
16:29@wallysilva > choose a proper seed according to the task at hand
What is a proper seed? Do you expect a programmer to check many seeds if it's good enough? If Red doesn't allow us to choice between different PRNG algorithms or arguments to given algorithm then I would assume that PRNG algorithm is good enough.
@hiiamboris :+1:
16:46> https://github.com/red/red/issues/1434

We cannot just use words. What do you think about draw from another block, like this:
extend system/view/VID/styles [
    custom-progress: [
        default-actor: on-down
        template: [
            type: 'base
            draw-block: copy [ 
                transform (center-of-rotation) 0 1 1 20x0 [fill-pen (progress-color) box 0x0 20x20]
            ]
            center-of-rotation: 50x50
            progress-color: purple
            size: 100x100
            center: 50x50
            
            update-draw: function [][
                self/draw: compose/deep self/draw-block 
            ]
        ]  
        init: [
            face/update-draw
        ]
    ]
]
 view/no-wait [
    cp1:  custom-progress 
]
9214
16:48@hiiamboris random is seeded with some [arbitrary constant](https://github.com/red/red/blob/7f2db9b69d69d6c0216cef23a5aafb81eaeefd03/runtime/random.reds#L133) on booting.
hiiamboris
nedzadarek
16:59> The constant 19650218 is the birthday of one of the authors,chosen without reason

Source: https://eprint.iacr.org/2005/165.pdf
wallysilva
17:04@nedzadarek What I meant is that if you're working on a simple "guess the number" game you may want to use a simpler seed than if you're working on a cryptographic program, for example. And in both situations, the respective programmers would likely be aware of what kind of seed to use according to the level of randomness they want to achieve.
nedzadarek
17:18@wallysilva in case of games, or in general, when you have to type seed for some reasons then yes, seeds with less digits would be good. But in lots of other cases (e.g. user saves seeds and load it without typing) then it doesn't matter. You still may make mistake by using very long seed, where it could make your program insecure. It depends on algorithm. For example:
> While LCGs are capable of producing pseudorandom numbers which can pass formal tests for randomness, the quality of the output is extremely sensitive to the choice of the parameters m and a.[5][2][6][7][8][3] For example, a = 1 and c = 1 produces a simple modulo-m counter, which has a long period, but is obviously non-random.

ps. as for mersene twister (used by Red):
> Is not cryptographically secure, unless the CryptMT variant (discussed below) is used. The reason is that observing a sufficient number of iterations (624 in the case of MT19937, since this is the size of the state vector from which future iterations are produced) allows one to predict all future iterations.
9214
17:31The seed does not determine the "level of randomness", implementation of the random generator does. The seed is just a bunch of bits used to feed the entropy pool; PRNG that changes the probability distribution depending on the seed value is a strange thing to use, to say the least.
wallysilva
17:32@nedzadarek The technical aspects of it are beyond my knowledge, so I can't really provide any insights on that.
Now, about the Mersene Twister, in the very first line of the Wikipedia [article](https://en.wikipedia.org/wiki/Mersenne_Twister) that you quoted says that :
> "It is by far the most widely used general-purpose PRNG."

So, I'd assume that there's a reason for that and that it's good enough for general-purpose.
17:50It seems that the Python community had a similar [discussion](https://groups.google.com/forum/#!topic/python-ideas/a-pyDvhL_Jc%5B1-25%5D) about MT.
greggirwin
17:56To seed, or not to seed, is simply a design choice. Red followed Rebol here, and that's that.
hiiamboris
17:59@greggirwin on https://github.com/red/red/issues/1706,
> We need to decide on the return value for all iterators

Do you know if this was ever discussed in Rebol or here?
9214
18:08@hiiamboris you can probably find some noteworthy discussions on [CC](https://www.curecode.org/rebol3/view-tickets.rsp).
hiiamboris
18:10> When I try to run my REBOL 2 code in REBOL 3 it doesn't work. I don't want to change anything or learn anything new. REBOL 2 is perfect and nothing should ever change.

:D
18:11thanks @9214 , there is something in fact
9214
18:11Or rather on its [Github mirror](https://github.com/rebol/rebol-issues).
greggirwin
18:16> We need to decide on the return value for all iterators and then implement it for both compiler and interpreter.

Let's do what Doc recommended, if it hasn't already been done. I think you or @9214 also had notes on until's design, and it ties to HOF as well.
hiiamboris
18:25I'll comment there in a bit.
Oldes
19:09@greggirwin interesting... I never noticed, that Rebol does not seed either.
Respectech
19:16I'm of the opinion that random should probably seed by default and allow a different seed if the programmer desires. According to Carl's motto, "simple things should be simple to do". Having an automatically seeded random is more simple than having to seed the random each time.
19:17Plus having an automatically seeded random won't break any existing programs unless they are counting on a random sequence that was predefined by the arbitrary birthday constant.
nedzadarek
19:44> The seed does not determine the "level of randomness", implementation of the random generator does.

@9214 That's right. Implementation and algorithms may cause certain seeds to be "broken".

@wallysilva I haven't tested (I mean used) many RNG but from the wiki it seems good enough.

@Respectech I agree.
greggirwin
19:53@Respectech excellent point about it being a non-breaking change. Except for automated testing, which could affect Red. Can't say without looking.
Respectech
19:59Just add a random/seed 19650218 at the beginning of any scripts that were counting on that random sequence.
greggirwin
20:50I understand the solution, just noting that it *could be* a breaking change in some cases.
21:56For those requesting automatic seeding, what do other langs use as their initial seed source?
22:02But this is not a right/wrong thing remember. Just as we can say it's not too much trouble for those who want reproducibility to seed it, it's not too much trouble for others to randomize at the start of scripts where they need it.
22:06This is my old R2 func for seeding.
randomize: func [
	"Reseed the random number generator."
	/with seed "date, time, and integer values are used directly; others are converted."
][
	random/seed either find [date! time! integer!] type?/word seed [seed] [
		to integer! checksum form any [seed now/precise] 'sha1
	]
]

nedzadarek
00:21> it's not too much trouble for others to randomize at the start of scripts where they need it.

@greggirwin Yes, it's not hard however when you want to reproduce something you know you need to either collect values or "set some seed". In case of "give me random number" some people expect the result to be random, out of the box.
Respectech
00:30Watching Carl's decision process when I worked at Rebol Technologies, I feel like Carl would agree with @nedzadarek. I understand Red isn't designed by Carl, however. But the reason I feel Carl might change his mind if he was discussing this with us here is because it is what the average user expects, and it is the more simple thing to get an automatically seeded random number when asking for it. The more complex use case is when you need a repeatable "random" sequence, and is this repeatable behavior is less expected by the average user.
theSherwood
03:16Every few days, the iframe on the downloads page returns this error: SSL_ERROR_RX_RECORD_TOO_LONG. This is one of those days.
luis-rj
19:53Is there a repository for old builds?
9214
20:01@luis-rj you can build from sources at any commit you want or grab versioned archives from Github.
greggirwin
21:05@x8x, any idea why @theSherwood would see that. Nobody has reported it before that I know of.
theSherwood
22:21Oh that's really odd. I get SSL errors on the static subdomain pretty frequently. Lasts a day or two and then it's gone again.
wallysilva
22:59@theSherwood Do you mean at [https://www.red-lang.org/p/download.html](https://www.red-lang.org/p/download.html)?
23:20I had issues to access the downloads on my laptop (but it was fine on my desktop) and it turned out that it was due to my network's "smart" filter (McAfee).
theSherwood
23:59Ahh. Okay. Yes. That's interesting that sometimes I see it and sometimes I don't. I'll have to take a look at fixing that. thanks

wallysilva
00:03Yeah, it was intermittent for me as well, but since I deactivated the smart filter it never happened again.
theSherwood
01:21:thumbsup:
x8x
01:46
We use google default setup, I trust they know what they are doing. So unless there are further reports I will leave things as is.>
theSherwood
03:00I'm using macOS catalina and I'm getting this on firefox, chrome, and brave. I'll look into the other possible issues. Thanks!
x8x
04:45Thanks for reporting and please let us know if you find something!
theSherwood
21:41:thumbsup:

wallysilva
18:56Is this an expected behavior of to-string (the spaces before and after 2)?
>> a: [0 [1 2 3] 4 5]
== [0 [1 2 3] 4 5]
>> to-string a
== "01 2 345"
9214
19:00@wallysilva yes. It simply concatenates formed values together.
>> collect [foreach value [0 [1 2 3] 4 5][keep form value]]
== ["0" "1 2 3" "4" "5"]
>> rejoin collect [foreach value [0 [1 2 3] 4 5][keep form value]]
== "01 2 345"
greggirwin
19:06It matches R2, where R3 doesn't include any spaces at all, though it fails PoLS for me. :^\ e.g.
>> to string! [1 [2 [3 [4 [5]]]]]
== "12 3 4 5"

However, to string! on rich values isn't something we want to encourage, if any kind of control over formatting is needed.

@9214, a question here is why it shouldn't use to string! logic internally, rather than form.
>> collect [foreach value [0 [1 2 3] 4 5][keep to string! value]]
== ["0" "123" "4" "5"]
>> rejoin collect [foreach value [0 [1 2 3] 4 5][keep to string! value]]
== "012345"

This may have been why R3 changed it.
wallysilva
19:13@9214 and @greggirwin I see, thank you
GiuseppeChillemi
22:26There is no Rename and make-dir, is it?
wallysilva
22:39There is: rename from to and make-dir path

GiuseppeChillemi
07:58I will try later but if they exist, I will adopt the rule to not ask question after midnight and retry the next day. 😑
08:35[![image.png](https://files.gitter.im/5780ef02c2f0db084a2231b0/9jRF/thumb/image.png)](https://files.gitter.im/5780ef02c2f0db084a2231b0/9jRF/image.png)
08:38I have found the cause: Red on that server was an older 6.4. Rename has been added somewhere on the road to 6.5.

wallysilva
23:28Hi guys, what am I missing here?
This works: view [text gray on-down [face/color: white] on-up [face/color: gray]]
But this doesn't: view [text #808080 on-down [face/color: white] on-up [face/color: #808080]]
greggirwin
23:41You're hitting the difference between VID and View. Run and click the face
view [my-face: text gray on-down [face/color: white] on-up [face/color: gray]]
my-face/color
view [my-face: text #808080 on-down [face/color: white] on-up [face/color: #808080]]
my-face/color

What happens is that VID processes the issue! in the second layout spec, and converts it to a tuple for you. But once you're in a handler, where it's regular Red code at play, that conversion doesn't happen automatically. You need to do it yourself.
view [my-face: text #808080 on-down [face/color: white] on-up [face/color: to tuple! #808080]]
my-face/color

9214
00:48View documentation, [section 2](https://github.com/red/docs/blob/master/en/view.adoc#face-object):
> color, tuple!, ... Background color of the face in R.G.B or R.G.B.A format.
wallysilva
00:58@greggirwin Wow, that's quite subtle, thank you for explaining that to me! I don't think I would have figured it out on my own.
So, the official color system in Red is RGB and color names like gray and white are just shortcut words for their respective RGB values and VID accepts Hex color but it actually converts it back to RGB.
So, I could actually write it using all those 3 options and it would work, like this:
view [text #808080 on-down [face/color: white] on-up [face/color: 128.128.128]]
01:00@9214 Thank you for pointing that out
9214
01:01@wallysilva you can list all available color shortcuts with ? tuple!.
wallysilva
01:03I used these colors just to ask the question, I'm actually working with colors that are not listed. But now it's quite clear how it works, very interesting!
9214
01:03Also:
colors: exclude sort extract load help-string tuple! 2 [transparent glass]
view/tight collect [
    until [
        foreach color take/part colors 4 [
            keep reduce [
                'base 70x40 form color get color pick [white black] gray > get color
            ]
        ]
        keep 'return
        empty? colors
    ]
]
wallysilva
01:04That's very cool, thank you!
Red-Beginner
09:32@wallysilva I use rgb codes like this 05.10.0
ldci
10:29@9214 very elegant. I made slight modifications and I'll add the code in redCV samples. Of course, you're credited for the initial code.
9214
10:43Thanks @ldci. Keep in mind that help-string is available in console only, you might want to change it to something like:
colors: collect [
	foreach word words-of system/words [
		if tuple? get/any word [keep word]
	]
]

colors: exclude sort colors [transparent glass]
10:53Ah, it's actually featured in [red/code](https://github.com/red/code/blob/master/Scripts/palette.red).
hiiamboris
11:29remove-each w colors: words-of system/words [try [not tuple? get w]]
11:32parse colors: to [] system/words [collect any [thru tuple! p: keep (to 'p p/-2)]]
11:32just having fun ☻
wallysilva
15:41@Red-Beginner That seems to be the wise thing to do as it works everywhere, thanks!
DanKokenge_twitter
17:46Is it possible to copy to "google drive' with red.. Thanks for any help..
9214
18:22@DanKokenge_twitter if you write a wrapper for [Drive API](https://developers.google.com/drive), yes.
DanKokenge_twitter
18:54Ok.. @9214 .. Thank you.. I'll give it a try
9214
19:01@DanKokenge_twitter you're welcome. You can use @rebolek's [library](https://gitlab.com/rebolek/castr) to get started.

ralfwenske
02:37@9214 Like the color-palette. Very useful for me with my bad memory (and probably for beginners too).
I did this to make it compilable and have an exe on my desktop:
;colors: exclude sort extract load help-string tuple! 2 [transparent glass]
colors: [
    aqua 
    beige 
   …

A question: I thought I had seen a compiler option somewhere that prevents the console showing up when double-clicking the app. Can’t find it with red —help though. Is there an option to prevent console showing up?
wallysilva
02:52@ralfwenske -t Windows
ralfwenske
04:56Thanks @wallysilva .. works
ldci
10:45@ralfwenske You can try this function
rcvGetSystemColors: function [
"Get system colors"
	return: 	[block!]
][
	sColors: collect [
		foreach word words-of system/words [
			if tuple? get/any word [keep word] ;--use get/any for unset words
		]
	]
	exclude sort sColors [transparent glass]
]

10:47Based on @9214 comments and now included in redCV.
toomasv
12:01Reminds me of a [color-picker](https://gist.githubusercontent.com/toomasv/d0b934170f73c765f28452ede83b08fb/raw/dcb22e1683279c45b66956c4fd1375e18809ab9b/named-color-picker.red).
ldci
13:00What 's great with Red is to find different solutions for the same problem:)

nedzadarek
16:42How do "pop" from the draw's push command:
img: make image! [255x255]
repeat i (255 * 255) [
    img/:i: to-tuple reduce [random 255 random 255 random 255 200]
    ]
view [
    base 300x300 draw[
            fill-pen red
            box 10x10 50x50 
            push
                [
                    fill-pen bitmap img 
                    box 10x10 50x50   
                ]
        fill-pen red 
        box 50x10 100x50 
        ]
]

fill-pen bitmap img isn't popped from the stack. I've tried writing pop but it doesn't work.
ps. Red 0.6.4 for Windows built 20-Jun-2020/19:24:25+02:00 commit #4d864b1
greggirwin
16:57https://github.com/red/docs/blob/master/en/draw.adoc#push
17:01Ah, I see what you mean, missed the last note.
17:02@qtxie will have to confirm, but it may be a bug. If so, for now you may need to do fill-pen off.
9214
17:41There is no pop command in Draw, at the end of the block the state is restored automatically.
17:58And, frankly, you are overlaying the boxes on top of each other so there's no way to spot the difference.
noise: make image! 255x255
forall noise [noise/1: random white]

? (
	draw 100x100 [
		fill-pen red
		box 0x0 50x50
		push [
			fill-pen bitmap noise
			box 50x50 100x100
		]
		box 0x50 50x100
	]
)

Pen's color isn't restored, even if I add fill-pen red before the last box. But with e.g. fill-pen blue it works.
nedzadarek
20:24@9214 What about this:
img: make image! [255x255]
repeat i (255 * 255) [
    img/:i: to-tuple reduce [random 255 random 255 random 255 200]
]
view [
    base red 
    base red draw [ fill-pen bitmap img box 0x0 100x100]
]

Do you see any difference between the first and the second base?
@greggirwin
Yes, fill-pen off at the end of push works. As @9214 mentioned I've tried to move few lines of code to the push and it worked:
img: make image! [255x255]
repeat i (255 * 255) [
    img/:i: to-tuple reduce [random 255 random 255 random 255 200]
    ]
view [
    base 300x300 draw[
            push
                [ ; those 2 lines:
                    fill-pen red
                    box 10x10 50x50 

                    fill-pen bitmap img 
                    box 10x10 50x50   
                    ;fill-pen off
                ]
        fill-pen red 
        box 50x10 100x50 
        ]
]

@greggirwin @9214 thank you for the answers.

qtxie
07:20> @qtxie will have to confirm, but it may be a bug. If so, for now you may need to do fill-pen off.

In the document, Saves the current state (transformations, clipping region, and pen settings) on the stack. If pen settings including fill-pen, then it's a bug.
GiuseppeChillemi
13:28Why a text file saved with RED, loaded with REBOL, saved again, then it can be loaded by RED? (It appears as empty)
rebolek
13:28example?
GiuseppeChillemi
13:32I can give it to you later.
dsunanda
16:11@GiuseppeChillemi Red can't currently handle "hi bit" ASCII files that Rebol will happily write and read, so this in Rebol cannot directly be read by Red:
rebol> write %test.txt to-char 199

If that's your problem, there is a work-around.
GiuseppeChillemi
16:33I write from RED using this code:

write to-file "calendar.txt" areacalendar/text

I read in Rebol using this code:

set-face read to-file "calendar.txt"

16:39Now the problem seems gone after a reboot. Maybe a lock on the file was the cause of my problem but I'll keep a look on it.
21:00@dsunanda which is the workaround?
dsunanda
21:53@GiuseppeChillemi Nor sure who to credit for this code - I hope the author can step forward and claim credit. Read the file as /Binary, and then use this:
; Basic UTF-8 conversion for RED:
    bin-to-string: function [bin [binary!]][
    text: make string! length? bin
    foreach byte bin [append text to char! byte]
    text
]

rebolek
04:27It's so simple I believe multiple authors came up with a similar solution. I've got one (based on collect) in my HTTP-tools (now CASTR):
load-non-utf: func [
    data [binary!]
] [
    copy collect/into [forall data [keep to char! data/1]] {}
]

toomasv
06:12@rebolek Shouldn't copy be rather before {}? Currently it keeps growing as {} is not copied:
>> length? b: load-non-utf read/binary %whatever
== 734
>> length? b: load-non-utf read/binary %whatever
== 1468
>> length? b: load-non-utf read/binary %whatever
== 2202
rebolek
06:44@toomasv thanks, good catch! I don't use the function that ofen to notice it :-)
toomasv
06:45:smile:
rebolek
06:48fixed https://gitlab.com/rebolek/castr/-/commit/13b2b3876b00a1bf64fe7b645aa66e4a0044b9b6
giesse
07:30Notice that you are converting Latin-1 to UTF-8 with that. It should perhaps be named that way to avoid confusion.

cloutiy
00:55Within a function, is there a way to use set so that it doesn't set at the global scope? Example:
myfunc:  function [ varname value ] [
   set to-word varname value
]

a: 1
myfunc "a" 3
print a
== 3

My understanding is that when using function, all words inside it are local. What I'm trying to do is programmatically do a: 3 so that a = 3 only inside the function. But set seems to set at the global scope.

00:57set/local would be nice ;)
greggirwin
01:01What is the ultimate goal? When you start writing really dynamic code like that, it can be quite tricky to maintain, dealing with non-obvious bindings and such. When I see string to word conversions for this kind of thing, my instinct is that there's a better way.
cloutiy
01:18@greggirwin Come to think about it, nevermind. Sorry about that.
01:25What I was trying to do was something that generates code. Like an AST, where each "node" is a function that returns code:
fn "myfunc" [ string "param1" integer "param3" ] [
   var [ "a" 3 ]
   var [ "b" 4 ]
   ...
]

if that makes any sense. Trying to parse a toy language (from a string), to generate an AST, where each "node" is a code generating function.

01:26But no worries, I have a couple other approaches I'll try.
9214
12:15@cloutiy set doesn't "set at the global scope", there are no scopes in the language at all. You give it a word a bound to the global context, and it changes the value to which it is set in that context, that's all there is.

If you want this change to a to be local, then you need to manually craft a context, and then bind a to it.
foo: func [word value][
	bind word: load word context compose [(to set-word! word) value]
]

>> a: 123
== 123
>> get foo "a" 456
== 456
>> a
== 123

In interpreters this is what usually happens, a piece of code is always carried with an environment where the changes need to be made.
bubnenkoff
16:32If I am passing script to red console is it possible to pass args with it?
16:34something like: >red.exe app.red -foo
16:44What can affect on GC? Sometimes app work fine half hour, sometimes crush every few seconds
16:45maybe there should be any timing between processing of new data to get GC work?
9214
16:45@bubnenkoff what makes you think that the crashes are GC-related?
bubnenkoff
16:47it's randomly, someone here that random crush is related to GC
9214
16:48Alright, does it crash if you turn GC off?
bubnenkoff
16:51it work fine until OM
9214
16:53I have no idea what that means, sorry. :smile_cat:
bubnenkoff
17:16Out of Memory
9214
17:17Ah, OK, that's expected. If you can narrow down the GC issue to a small code snippet, that would be helpful.

toomasv
07:08@Yamoon2018 Carried over from /red room
The problem is that you do not call the func you defined. Here is simplest way to make it working:
window-title: ""
open-img: func[][
	img-file-name: request-file/filter ["png" "*.png" "jpeg" "*.jpg" "gif" "*.gif"]
	only-file-name: find/last img-file-name  "/"
	window-title: rejoin ["File name: " only-file-name]
]
open-img 
menu-block: layout [
	title window-title
]
view/options/flags menu-block [offset: 0x0][resize]

Or, in this situation (may be this is contained in some other func?) you can not to use func at all:
img-file-name: request-file/filter ["png" "*.png" "jpeg" "*.jpg" "gif" "*.gif"]
only-file-name: find/last img-file-name "/"
window-title: rejoin ["File name: " only-file-name]
menu-block: layout [
title window-title
]
view/options/flags menu-block [offset: 0x0][resize]
`
07:10--------------------------
Alternatively, you may want to open files from the same window:
open-img: does [
	img-file-name: request-file/filter ["png" "*.png" "jpeg" "*.jpg" "gif" "*.gif"]
	only-file-name: last split-path img-file-name
	img/image: load img-file-name
	img/size: img/image/size
	lay/text: rejoin ["File name: " only-file-name]
	lay/size: img/size + 20
]
lay: layout [
	on-menu [switch event/picked [open [open-img]]]
	img: image
]
view/options lay [offset: 0x0 menu: ["Open" open]]


Finally, you may want easier access to files in the folder:
open-dir: function [][
	img/image: none
	change-dir folder: request-dir/keep
	files: read folder
	remove-each file files [not find [%png %jpeg %gif] find/tail/last file dot]
	list/data: files
]
lay: layout [
	on-menu [switch event/picked [open [open-dir]]]
	list: text-list 150x200 on-change [
		file: pick face/data face/selected
		img/image: load file
		img/size: img/image/size
		lay/text: rejoin ["File name: " file]
		lay/size: as-pair 30 + list/size/x + img/size/x
						  20 + max list/size/y img/size/y
	]
	img: image
]
view/options lay [offset: 0x0 menu: ["Open dir" open]]

theSherwood
07:44Is there currently any way to read metadata on a file? I thought read/info might do it but it seems to have the same behavior as read.
toomasv
07:45@theSherwood query is meant for that, but currently it returns date only.
theSherwood
07:51Thanks @toomasv
toomasv
07:53You are welcome! :smile:
07:58@theSherwood With read/info you can get metadata for web pages, e.g.
>> data: read/info https://www.red-lang.org/ second data
== #(
    Cache-Control: "private, max-age=0"
    Date: "Thu, 30 Jul 2020 07:56:51 GMT"
    Transfer-Encoding: "chunked"
    Content-Type: "text/ht...
theSherwood
08:01Ooh. I see! I wouldn't have thought to try that.

9214
12:02@bubnenkoff WRT command-line arguments: system/script/args contains a string of them, and system/options/args has a list of them in tokenized form.
Red [File: %test.red]

probe system/script/args
probe system/options/args

$ red --cli test.red some command-line arguments
"some command-line arguments"
["some" "command-line" "arguments"]
nedzadarek
14:15Can we extend draw? At least, can we add new shapes (based for example on polygon)?
greggirwin
23:58@nedzadarek remember, it's all data. You can create shape templates of your own and compose them into your draw blocks.

nedzadarek
07:21@greggirwin I meant something more modular. I meant something that I don't need to care how a block is passed (so I don't destroy something). composeing might destroy things (if not used carefully!).
greggirwin
14:201) What is context, or use case?
2) How do you see it working? Draw is implemented in Red/system, so it would have to be some kind of extension system, where you register new shapes and their associated parameters and R/S routine code, which means things have to be compiled.

nedzadarek
12:50@greggirwin I've been working on formulas related to the regular polygons so I thought I would write some code that draws the regular polygons. I wanted to share it in something easy to include. I've worked with style's templates so I was just curious whenever or not draw has something *similar*.

greggirwin
00:53OK, interesting. Draw doesn't not have anything like styles, but it's a good design space.
Yamoon2018
08:58I'm trying to add Recent images to the menu so the user can open the previously opened files, so I did the following :

img3: [img1 img2 img3 img4 img5 img6 img7 img8 img9 img10]

open-img: does[

img-file-name: request-file/filter ["png" "*.png" "jpeg" "*.jpg" "gif" "*.gif"]
only-file-name: find/tail/last img-file-name "/"

menu-block/text: rejoin["File name: " only-file-name]

repend file-name img-file-name

repend menu-block/menu/2/11 [form only-file-name first img3]
img3: next img3

menu-block/menu: [
"File"[
"Open" file-open ---
"Save" file-save ---
"Save as" file-saveas ---
"Recent images" []---

menu-block/actors: make object! [
on-menu: func[face [object!] event [event!]][
probe event/picked

switch event/picked[
file-open[open-img]
file-save[save-img]
file-saveas[
save file: request-file/filter ["png" "*.png" "jpeg" "*.jpg" "gif" "*.gif"] draw (canvas/size) (canvas/draw)
]

img1[recent-file-name-func file-name/1]
img2[recent-file-name-func file-name/2]
img3[recent-file-name-func file-name/3]
img4[recent-file-name-func file-name/4]
img5[recent-file-name-func file-name/5]
img6[recent-file-name-func file-name/6]
img7[recent-file-name-func file-name/7]
img8[recent-file-name-func file-name/8]
img9[recent-file-name-func file-name/9]
img10[recent-file-name-func file-name/10]

Any better advice/suggestions
toomasv
11:15@Yamoon2018 Here is another possibility:
open-img: function [/recent file][
	img-file-name: either recent [
		to-file replace/all to-string file #"|" #"/"
	][
		request-file/filter ["png" "*.png" "jpeg" "*.jpg" "gif" "*.gif"]
	]
	only-file-name: last split-path img-file-name
	if not recent [
		repend lay/menu/("File")/("Recent") [
			form only-file-name 
			to-word replace/all to-string img-file-name  #"/" #"|"
		]
	]
	lay/text:  rejoin ["File name: " only-file-name]
	img/image: load img-file-name
	lay/size: 20 + img/size: img/image/size
]
lay: layout/options [
	on-menu [
		switch/default event/picked [
			file-open [open-img]
		][
			open-img/recent event/picked
		]
	]
	img: image
][
	menu: [
		"File" [
			"Open"   file-open
			"Recent" []
		]
	]
]

view lay
nedzadarek
13:20@toomasv @Yamoon2018 Toomas posted nice code.
I would insert instead of append (repend reduce so there is another reduce):
insert lay/menu/("File")/("Recent") reduce [

This is FIFO -> First in first out -> It's sorted from most recent to the latest file.

I would limit number of recent files:
if 3 < length? lay/menu/("File")/("Recent") [
        remove back tail lay/menu/("File")/("Recent")
    ]

Add this after if not recent [...] part. It should show only 3 files. When you pick 4th it will delete the earliest one.

ps. I would cancel the action when the user press "cancel" instead of open.

@toomasv are you sure it's open-img/recent event/picked? event/picked returns none (tried on 20-Jun-2020/19:24:25+02:00 and recent build).
toomasv
13:24Works here (provided you have transformed the filename into word).
nedzadarek
14:27@toomasv where?
toomasv
14:35W10. July 27 build
greggirwin
15:02This is a really old R2 func:
; If you use this consistenly on a series, you will always have
    ; unique instances. If you don't, you can apply UNIQUE yourself.
    ; So this function doesn't need a /unique refinement.
    insert-MRU: func [
        "Insert value in series; removing first existing instance."
        series [series!]
        value
        /limit size [integer!] "Limit the series to the given size by removing the last item."
    ][
        remove find/only series value
        insert/only series value
        if all [size  size < length? series] [remove back tail series]
        series
    ]
toomasv
16:50BTW, @greggirwin, do you know, why does event/picked return only words from menu and none for other types, e.g. file and path? It would be much easier to implement e.g. MRU file-lists, if file type were also returned. Now we have to invent cunning ways :)
nedzadarek
18:21@toomasv > event/picked return only words from menu and none for other types
I haven't checked that it's block of "pairs" (I've been deleting only 1 element instead of 2). Fix:
if 6 < length? lay/menu/("File")/("Recent") [
        remove/part back back tail lay/menu/("File")/("Recent") 2
    ]

toomasv
05:23@Yamoon2018 When you ask for advice and someone makes an effort to make a suggestion, it would be nice if you give some feedback about how did it work for you and if it didn't, then why not. So that we all could learn something from the exchange.
Yamoon2018
07:10@toomasv , I didn't try it until now but sure once I'm done with it I will share my experience here and thanks for all
toomasv
07:23@Yamoon2018 Thanks! :+1:
GiuseppeChillemi
16:06How do I represent true and false inside a block? (Without using to-logic)

>> c: [a false] probe type? c/a
word!
== word!
>>


ne1uno
16:09#[false]
16:14c: reduce [a to-logic false] mold/all c
GiuseppeChillemi
16:16Thanks, I have just discovered to-logic before the path considers false as word because it is picked by path as this type and not for its content, so:

>> to-logic first [false]
== true
>> first reduce [to-logic false]
== false
>>
16:19(Modified)
toomasv
17:20Also
>> get first [false]
== false
>> type? get first [false]
== logic!
GiuseppeChillemi
17:33? Why ?
endo64
20:19You get the value of false word and it is false logic! value.
20:21first reduce [to-logic false], when you reduce, to-logic is not necessary as false word evaluated to false logic!.
first reduce [false] or first compose [a (false)].
Yamoon2018
21:10@toomasv , I spend a lot of time reading & studying your code and its amazing, but I had to do some modification so it will fit my requirements also there are many things I coud not do it the same way you did it but I did it my way, here is the new code after modifications along with the notes for the errors I was unable to solve
21:19

size system/view/screens/1/size

on-menu[
switch/default event/picked[
file-open[open-img]
file-save[save-img]
file-saveas[
save file: request-file/filter ["png" "*.png" "jpeg" "*.jpg" "gif" "*.gif"] draw (canvas/size) (canvas/draw)
]
qt[quit]
ed-undo[undo-drawing]
ed-redo[redo-drawing]
menu-help[alert "My paint application"]
][
open-img/recent event/picked
]
]
][
menu: [
"File"[
"Open" file-open ---
"Save" file-save ---
"Save as" file-saveas ---
"Recent"[] ---
"Exit" qt
]
"Edit"[
"Undo" ed-undo
"Redo" ed-redo
]
"Help" menu-help

]
]

open-img: function[/recent file][

img-file-name: either recent[
only-file-name: to-file to-string file
][
img-file-name: request-file/filter ["png" "*.png" "jpeg" "*.jpg" "gif" "*.gif"]
only-file-name: find/tail/last img-file-name "/"
]

menu-block/text: rejoin["File name: " only-file-name]

file-ref: to-word to-string only-file-name


if not recent [
repend menu-block/menu/("File")/11[
form only-file-name file-ref
]
]
probe menu-block/menu/("File")/11

img: load img-file-name


repend file-name img-file-name

img-type: find img-file-name "."
canvas/draw/image: img
]

Here is the notes & errors:
1) repend menu-block/menu/("File")/("Recent")
not working and give this error "Script Error: repend does not allow none! for its series argument"
so I didnt like this, repend menu-block/menu/("File")/11[

2) to-word replace/all to-string img-file-name #"/" #"|"
not working , no error , its just opening a request-file window when I click on any Recent file
so I did it like this,
file-ref: to-word to-string only-file-name

if not recent [
repend menu-block/menu/("File")/11[
form only-file-name file-ref
]

Soon I will upload my app on Github so everybody will get a chance to look at it and give me feedback

Thanks for support >
9214
21:24@Yamoon2018 please use Github gists for sharing large snippets of code. Also, Gitter supports Markdown (press Ctrl + Shift + M in the message field to see the cheatsheet), so you can format code using fences — that way people who help you will have an easier time reading what you've posted.

Yamoon2018
04:28@9214 , Thanks for the advice, I will do it next time
nedzadarek
05:49@GiuseppeChillemi you can as well add/change values in a block:
type? first append [] true
arr: [meh] arr/1: true type? first arr
toomasv
07:23@Yamoon2018 Thanks for feedback!
Unfortunately the code you pasted here is not complete, so I have to invent some missing pieces.
Anyway, here are some remarks:
1) In open-img function the first expression (setting img-file-name) seems confused, as you are (re)setting same name inside either.

2) file-name (third line from bottom) is used only once and seems superfluous.

3) About your note (1): Does this work?
view/options [
   on-menu [tx/text: form next face/menu/("File")/("Recent")] 
   tx: text 200
][
   menu: ["File" ["Recent" ["Try" It works nevertheless]]]
]

If it does, then error message in your note (1) has some other cause, not because menu/("File")/("Recent") is not working.
If it doesn't, then what platform are you on?

4) About your note (2): Does this work the same for you?
>> to-word replace/all to-string %/C/some.file #"/" #"|"
== |C|some.file

If not, then what platform are you on?

5) The solution you adopted works as long as you open images from one folder only, because you save in "Recent" menu filenames without full path and switching to another folder it cannot find these files anymore.

Yamoon2018
08:27@toomasv , wow amazing, I got it, again let me go through it and I will upload the full code on Github soon so it will be available to anyone who would like to see it. By the way, I'm using Windows 10 and Note++ as an editor, if you suggest something better, please let me know.
toomasv
08:30I use these too, so no suggestions :)
ldci
10:41@Yamoon2018 When programming under Windows, I using Crimson Editor http://www.crimsoneditor.com . We can directly run Red with this editor :-)
meijeru
10:45I have experience with both Crimson and Note++, they are both effective for Red.
greggirwin
17:42I used Crimson for a long time. Been on UltraEdit for even longer, though I only use basic features.
17:43I also used ConTEXT for a long time.
GaryMiller
19:25I use Notepad++
Yamoon2018
19:33@toomasv ,
1)
view/options [
on-menu [tx/text: form next face/menu/("File")/("Recent")]
tx: text 200
][
menu: ["File" ["Recent" ["Try" It works nevertheless]]]
]
its not working and here is the error "*** Syntax Error: invalid path! at "] tx: text 200 ][ m"

2) to-word replace/all to-string %/C/some.file #"/" #"|"
== |C|some.file
Also not working, I think because my Red folder has space its"Red programming" where I keep all the files, so when I use this code the result is this "|C|Users|pc|Documents|Yamin|Red"
toomasv
20:24Interesting. Can anybody confirm that the following snippet gives error if File/Resent/Try is selected from menu:
view/options [on-menu [tx/text: form next face/menu/("File")/("Recent")] tx: text 200][menu: ["File" ["Recent" ["Try" It works nevertheless]]]]
20:26About (2), yes spaces in folder-(or file)-names cause problem. Does something like this solve it?
>> parse file: to-string %"/C/Red programming" [any [change #"/" #"|" | change #" " "__" | skip]] fw: to-word file
== |C|Red__programming
>> parse file: to-string fw [any [change #"|" #"/" | change "__" #" " | skip]] to-file file
== %"/C/Red programming"
endo64
20:37view/options [on-menu ... works for me, I see "It works nevertheless" message on the window.
20:39@Yamoon2018 's sample code also works for me, so no missing brackets or something.
@Yamoon2018 Please use code formatting for your sample codes, you can see the details by pressing CRTL-SHIFT-M keys.
Yamoon2018
22:531) I fix it by removing "Recent" from the menu
view/options [on-menu [tx/text: form next face/menu/("File")] tx: text 200]
[menu: ["File" ["Recent" ["Try" It works nevertheless]]]]


2) works fine with me
22:54Thanks, everybody

mikeyaunish
02:45Is there a way to have a reaction lead to running a function? Other then using a timer to check changes in the variables?
Yamoon2018
04:33I found another way to do it whatever number of items in the menu
view/options [on-menu [tx/text:  form select  face/menu/("File") "Recent"] tx: text 200][
 menu: [
    "File" [
            "A" A 
            "B" B
            "C" C 
            
            "Recent" [
                "Try" YESS I DID IT]]
       ]
]
toomasv
04:58@Yamoon2018 :+1:
05:01@endo64 Thanks for checking it!
endo64
06:17@mikeyaunish Is it something object ownership you are asking?
>> o: make object! [a: "test" on-change*: func [word old new] [print [word "changed"] ] ]
== make object! [
    a: "test"
]
>> o/a: "ok"
a changed
== "ok"
Yamoon2018
06:29@toomasv , I have your drawing pad , its amazing and I'm trying to find a way to do this
f with [extra: 'line 		image: (draw 23x23 [line 5x5 17x17])]

but I still dont know how to do it and also i'm defining canvas: none out of the block, is this enough .
toomasv
07:17@Yamoon2018 May be like this:
>> img: draw/transparent 23x23 [line 5x5 17x17]
== make image! [23x23 #{
    000000000000000000000000000000000000000000000000000000000000
    0000000000000000000000000000000000000000000000000000000...
>> view [button 25x25 with [image: img]]
Yamoon2018
07:22@toomasv , thanks
toomasv
07:28@Yamoon2018 You are welcome!
If you want to do it "in-place", then:
view compose/deep [button 25x25 with [image: (draw/transparent 23x23 [line 5x5 17x17])]]

Or, without composing:
view [button 25x25 with [image: system/words/draw/transparent 23x23 [line 5x5 17x17]]]
Yamoon2018
08:06With or without compose, what is the difference , is it about speed,
08:26Here is my Red paint app link on Github, I would like to get everybody feedback on it,https://github.com/Yamoon2018/Red-paint-app
endo64
08:40@Yamoon2018 You have a missing image, temp-img.png
toomasv
08:41@Yamoon2018 Bravo!
Some quick notes:
* triangle and polygon seem not to work
* changed line-width is used not immediately on next figure but after that
08:49@Yamoon2018

> With or without compose, what is the difference , is it about speed,

It's mainly about memory IMO, as compose will copy the block. But it will matter in case of large blocks or tight loops only. It also affects how parens in other places in the block will be interpreted, which sometimes may force you to reconsider parens for grouping purposes.
Yamoon2018
09:01@endo64 , I uploaded the missing image
09:03@toomasv , It's still under development and I'm working on it.
toomasv
09:03Ah, good!
09:16@Yamoon2018
* reduce is superfluous in constructs like reduce[compose [...]]
* Instead of recording mouse-state and then using mouse-state = 'down you can use event/down?
* If you have already reduced or composed a block, then using rependis superfluous, use append instead. Or use repend but then no need for reduce or compose.
endo64
09:33Good lessons from master Toomas :)
toomasv
11:06 :neckbeard:
wallysilva
19:22Hi guys,
I want to build a little app that gets a daily background image from [Bing!](https://www.bing.com) and sets it as a Windows wallpaper.
I figure that getting the image should be rather simple with parse and I found the C++ [API](https://docs.microsoft.com/en-us/windows/win32/api/shobjidl_core/nf-shobjidl_core-idesktopwallpaper-setwallpaper?redirectedfrom=MSDN) for setting a wallpaper on Windows.
But I have no clue how to bridge Red to C++ to do that.
Could anyone please point me to the right direction?
9214
19:31@wallysilva C-level programming skills and knowledge of Red/System are the essential prerequisites. How are you feeling on that front?
19:33I'm not sure if Red/System can bind to a C++ library though, it's notorious for [mangling](https://en.wikipedia.org/wiki/Name_mangling#C++) symbol names, with results differing between compilers.
19:38Ah, good news, shobjidl.h uses extern "C" idiom mentioned in the wiki article, so symbols should not be mangled.
19:44And the bad news is that this library uses COM interface, which might be a tad bit too much for your first exposure to the bloody massacre that systems programming is :wink:
wallysilva
19:51Haha
Thanks, Vladimir!
I was avoiding Red/S for now as it seems to be deeper waters, but I guess learning its basics will be my next project. Any recommended starting point?
9214
20:02@wallysilva [K&R book](https://en.wikipedia.org/wiki/The_C_Programming_Language) is a one-stop-shop. If you know C then learning R/S is a matter of days. [Documentation](https://static.red-lang.org/red-system-specs.html), obviously. As a follow-up, I can personally recommend [van der Liden's](https://www.oreilly.com/library/view/expert-c-programming/0131774298/) book, which goes into gory details of C (undefined behavior, syntactical subtleties, and, most importantly, boustrophedonic reading of [C gibberish](https://cdecl.org/), aka type declarations) in an engaging, tongue-in-cheek style. Not that it will help you with Red/System though, but might strengthen the intuition behind some concepts.
endo64
20:07For changing wallpaper on Windows, this might help: https://stackoverflow.com/questions/46984616/how-to-set-wallpaper-from-windows-command-prompt-on-windows-10
Just replace the image file in C:\Users\yourname\AppData\Roaming\Microsoft\Windows\Themes and execute RUNDLL32.EXE USER32.DLL,UpdatePerUserSystemParameters ,1 ,True by call.
GaryMiller
20:07Easiest way would be to write a small C++ program that takes the file name of the image as a command line parameter and and calls the C++ API to set the wallpaper.

Then write the RED program to download the image and save it dist the execute the C++ program passing it the image file name .
9214
20:16Or you can start from the other end and figure out how to pull image! from Bing first.
20:45@wallysilva [here](https://gist.github.com/9214/a59855e06162e1e90dc853fb3aa4646a) is a solution WRT Bing, though you might want to figure it out on your own, for educational purposes :wink:
wallysilva
21:00@9214 Learn C?! This relationship is getting very serious! 😆
I think I will take your second advice and start on the easier end.
Wow, I can't believe you've just done it in 2 lines! You not even needed parse!
How come ? replaces view and opens a window?

@endo64 That seems to be a feasible solution to my knowledge level, thank you!

@GaryMiller I'm afraid writing in C++ is beyond me at the moment, but thank you for your suggestion, I appreciate it.
9214
21:03@wallysilva ? is a wrapper on top of help-string. You can ?? help-string to see how it behaves with image! values.
21:04Then you'll C that it's not the spoon that bends.
wallysilva
21:44@9214 Haha
Thank you for clarifying that for me, I appreciate your time. 🙏
9214
21:45You're welcome! Enjoy the ride.

mikeyaunish
00:10@endo64 Thanks on-change* is exactly what I am looking for. I seem to be having problems creating a react/link between a GUI text object and my regularly created object.
02:41Here is the code I am running:
cross-link-text: func [ o1 o2 ] [
	    o1/text: o2/text
	    o2/text: o1/text
]

my-react: make object! [ 
	object-name: ""
    on-change*: func [word old new 
        /local srs
    ][
        print ["on-change* object-name =(" object-name ") word=(" word ") old=(" old ") new=(" new ")"]
        all [
            not empty? srs: system/reactivity/source 
            srs/1 = self 
            srs/2 = word 
            set-quiet in self word old 
            exit
        ] 
        unless all [block? :old block? :new same? head :old head :new] [
            if any [series? :old object? :old] [modify old 'owned none] 
            if any [series? :new object? :new] [modify new 'owned reduce [self word]]
        ] 
        system/reactivity/check/only self word
    ]
] 
o1: construct/with [ text: "O1 TEXT" object-name: "o1" ] my-react
o2: construct/with [ text: "O2 text" object-name: "o2" ] my-react
react/link :cross-link-text [ o1 o2 ]
o2/text: "brand new text"

I assumed that this would create some kind of infinite loop but instead I
get output like this:
on-change* object-name =( o1 ) word=( text ) old=( O1 TEXT ) new=( O2 text )
on-change* object-name =( o2 ) word=( text ) old=( O2 text ) new=( O2 text )
on-change* object-name =( o1 ) word=( text ) old=( O2 text ) new=( O2 text )
on-change* object-name =( o2 ) word=( text ) old=( O2 text ) new=( O2 text )
on-change* object-name =( o1 ) word=( text ) old=( O2 text ) new=( O2 text )
on-change* object-name =( o1 ) word=( text ) old=( O2 text ) new=( O2 text )
on-change* object-name =( o2 ) word=( text ) old=( O2 text ) new=( O2 text )
on-change* object-name =( o1 ) word=( text ) old=( O2 text ) new=( O2 text )
on-change* object-name =( o2 ) word=( text ) old=( O2 text ) new=( O2 text )
on-change* object-name =( o2 ) word=( text ) old=( O2 text ) new=( O2 text )
on-change* object-name =( o1 ) word=( text ) old=( O2 text ) new=( O2 text )
on-change* object-name =( o2 ) word=( text ) old=( O2 text ) new=( O2 text )
on-change* object-name =( o1 ) word=( text ) old=( O2 text ) new=( O2 text )
on-change* object-name =( o2 ) word=( text ) old=( O2 text ) new=( O2 text )
on-change* object-name =( o2 ) word=( text ) old=( O2 text ) new=( brand new text )
on-change* object-name =( o1 ) word=( text ) old=( O2 text ) new=( brand new text )
on-change* object-name =( o2 ) word=( text ) old=( brand new text ) new=( brand new text )
on-change* object-name =( o1 ) word=( text ) old=( brand new text ) new=( brand new text )
on-change* object-name =( o2 ) word=( text ) old=( brand new text ) new=( brand new text )

My question is: have I created a valid reaction here? What's going on with all the *on-change activity? Do I need to
protect my objects from an infinite loop?


toomasv
10:19@mikeyaunish Hopefully someone who actually understands reactivity details will step in, but here are my two cents:
* cross-link-text should probably include temporary var
* probably react/link/later should be used
* infinite loops seem to be checked and interrupted
* on-change* without most of the body would give better result in this case IMO:
clear-reactions
cross-link-text: func [ o1 o2 /local tmp] [
    tmp: o1/text
    o1/text: o2/text
    o2/text: tmp
]
my-react: object [ 
    object-name: ""
    on-change*: func [word old new][
        print ["on-change* object-name =(" object-name ") word=(" word ") old=(" old ") new=(" new ")"]
        system/reactivity/check/only self word
    ]
] 
o1: construct/with [ text: "O1 TEXT" object-name: "o1" ] my-react
o2: construct/with [ text: "O2 text" object-name: "o2" ] my-react
react/link/later :cross-link-text [ o1 o2 ]
o2/text: "brand new text"

on-change* object-name =( o2 ) word=( text ) old=( O2 text ) new=( brand new text )
on-change* object-name =( o1 ) word=( text ) old=( O1 TEXT ) new=( brand new text )
on-change* object-name =( o2 ) word=( text ) old=( brand new text ) new=( O1 TEXT )
on-change* object-name =( o1 ) word=( text ) old=( brand new text ) new=( O1 TEXT )
on-change* object-name =( o2 ) word=( text ) old=( O1 TEXT ) new=( brand new text )
10:28BTW Your previous code could also be achieved as:
my-react: reactor [object-name: ""] 
insert body-of :my-react/on-change* bind [
	print ["on-change* object-name =(" object-name ") word=(" word ") old=(" old ") new=(" new ")"]
] :my-react/on-change*
mikeyaunish
14:29@toomasv - thanks for that. I was wondering what the minimum was for *on-change I like your example for modifying the *on-change function as well. What will the tmp variable accomplish in cross-link-text ?
toomasv
14:52@mikeyaunish You are welcome! Temp var - assuming you want to interchange values of two fields you’ll need the third var to temporarily keep the value of the first field, otherwise second field will get back its own original value from first. Although set-words are not variables, logic is same here.
mikeyaunish
15:17@toomasv OK - thanks for the explaination.
toomasv
17:00But Red can do better, i.e. without the third (on certain conditions):
>> o1: object [text: ["o1 text"]] o2: object [text: ["o2 text"]] ()
>> swap o1/text o2/text ()
>> print [o1/text o2/text]
o2 text o1 text

O simply:
>> swap o1: ["o1"] o2: ["o2"] ()
>> print [o1 o2]
o2 o1
wallysilva
17:20@toomasv What do the empty parens do?
toomasv
17:21Keep console clean (by returning unset!)
wallysilva
17:22Oh, interesting, thank you!

GiuseppeChillemi
13:17I am exploring conditional actions on series. I mean actions that are performed only if a condition is met. Example:

a: copy []
b: [a b c d]

if not empty? b [append b a]


In my vision, new version of instruction like empty?, tail? can pass-thru their argument if the condition is true or return false|none if the condition is not met. Also instructions like append* could have an /if refinement to act conditionally.

So you can write:

append*/if a not empty? b


The istruction will also return false|none if the condition in not met.

Which is your opinion on this, which difficulties will I meet?
13:21I have thought about /if refinement because I think that I would loose the ability to add NONE or FALSE to a series but I have still not examined how FALSE|NONE behaves on series, but if there is another way of looking at this without /IF your ideas is welcome.
18:16I have put an asterisk just to differentiate this append from Red standard one.
18:34I should have differentiated the passthru empty?* but I have forgotten to do this.

wallysilva
02:17I see, thank you for clarifying that.
toomasv
09:55@GiuseppeChillemi
I see there chain of problems with your example:
1) What arguments should append*/iftake?
I imagine normally these should be a, b and condition as argument to /if refinement. But how would append* differentiate these arguments from your above line? (append*/if a not empty?* b)?
2) Ok, it could be done with two arguments, /if just changing the way second arg is interpreted. Second arg in this case would be the result of not empty?* b. Now it needs to pass through b in case it is **not** empty, so that a could be appended to it. So empty?* should pass it through if false and then not should pass it through. It's becoming too weird indeed! :smile: You would need not-empty? to pass b through if true.
3) Another problem is totally mixed up order of arguments. I have understood that in Redbol first is the principal argument, something you are primarily operating on, in your example it is b IMO. But you give as first argument something secondary and include the main argument as an argument to an argument (condition). Blasphemy! :imp:

That said, it is not difficult to implement this:
>> not-empty?: func [series][get pick [false series] empty? series]
== func [series][get pick [false series] empty? series]
>> not-empty? []
== false
>> not-empty? [a b c]
== [a b c]
>> append*: func [a b /if][either if [either b [append b a][none]][append a b]]
== func [a b /if][either if [either b [append b a] [none]] [append a b]]
>> append*/if [a] not-empty? []
== none
>> append*/if [a] not-empty? [b]
== [b a]
>> append* [a] [b]
== [a b]
11:57append* could also be defined as
append*: func [a b /if][either if [system/words/if b [append b a]][append a b]]
GiuseppeChillemi
16:32Toomas, when I have ideas I have the urge to express them with someone and have his feedback, so yes, Redbol first argument is the Target one but while being in "hurry" I have inverted the arguments in my example!
16:38Also, yes, NOT is not passthru, so we have to define a not* to not be forced to create functions with multiple test. I have missed this too while being in "urgency to express my idea".
16:46In the meantime I have investigated series and logic values and understood that you can't implement this solution without IF or any other refinement or escaper because APPEND would lose the ability to append logic true and false to a series.
toomasv
17:35:+1:
GiuseppeChillemi
23:42@toomasv Here is an Append* with a /where refinement which accepts functions or blocks to use for any.

range1: func [data] [any [data > 10 data < 50]]
test: [data > 10 data < 50]

append*: func [
	"Conditionally append a value"
	target [series!] "The target series"
	data "The value"
	/where condition [function! block!] "An ANY block with DATA word or an arity function to pass DATA to" 
	] [

	either where [ 
		case [ 
			all [function? condition condition data] [
				append target data
			]
			all [block? condition] [
						condition: bind copy/deep condition 'data
						if any condition [append target data]
					]
		]
	]
	[
		append target data
	]
]


It works for blocks:

test: [data > 10 data < 50] append*/where [a b] 20 test
== [a b 20]


But it does not work for function:
range1: func [data] [any [data > 10 data < 50]]
append*/where [a b] 20 :range1 

*** Script Error: cannot compare true with 10
*** Where: do
*** Stack: do-file


23:43I can't understand why
9214
23:58function? condition.

GiuseppeChillemi
00:01Thank you Vladimir, I have changed it to
...
all [function? :condition condition data]
...

And now it works.
toomasv
04:41@GiuseppeChillemi Nice!
If you want to constrain range, I suggest to reconsider how it is implemented. E.g. currently:
>> append*/where [a b] 5 test
== [a b 5]

I guess it is not what you want given your test.
GiuseppeChillemi
10:24@toomasv thanks, I have written this quick test being too quick writing it as it includes everything! It's not an OR but an AND which should be here.
10:25For ranges I have to use ALL or an AND in the middle of the two ANY conditions.
10:26While if I what to check single conditions ANY is the way to go.
10:28*if I want to append on ANY of the single conditions.
10:29The deeper I go, the more I like coding in Red.
12:29I am now in front of my PC and tried changing ANY with ALL and putting the value out of range but I have had a strange surprise:

append*: func [
	"Conditionally append a value"
	target [series!] "The target series"
	data "The value"
	/where condition [function! block!] "An ANY block with DATA word or an arity function to pass DATA to" 
	] [

	either where [ 
		case [ 
			all [function? :condition condition data] [
				append target data
			]
			all [block? condition] [
						condition: bind copy/deep condition 'data
						if any condition [append target data]
					]
		]
	]
	[
		append target data
	]
]

If the value is out of range I get an error
range1: func [data] [all [data > 10 data < 50]]
append*/where [a b] 5 :range1

*** Script Error: condition is missing its data argument
*** Where: do
*** Stack: do-file

Changing the value to one in range the error disappears.
range1: func [data] [all [data > 10 data < 50]]
append*/where [a b] 18 :range1 
== [a b 18]

What is happening?
13:27> @GiuseppeChillemi Where does condition land after first test fails? What happens to it there?
13:31@toomasv I suppose you mean after the first any > 10, don't you? But I still don't see the problem.
13:39*data > 0
13:39OMG, I am too stressed these days, I am writing worse than usual.
toomasv
13:43@GiuseppeChillemi No, I mean after the first case.
9214
14:05@GiuseppeChillemi think what happens when, inside the first all, function? :condition returns true and condition data returns false — this means that all by itself returns false. What case will do if one of its branches fails?
14:08Naturally, it will go and check another branch, which reads as all [block? condition]. But condition is still a function, which gets called without an argument. Hense the error message. It's the same problem as with function? condition before.
GiuseppeChillemi
14:17Thanks to you all. I was using CASE like ALL, thinking it would not advance to the second test if the first fails. Also, has being these my first steps passing and using functions around I still tend to forget : as you @9214 are outlining.
14:37I have changed the code from:

if  condition [append target data]


to

if do condition [append target data]


So I can use either ANY or ALL writing them directly in the test code.

test: [any [((data > 10) and (data < 30)) data = 50]]


21:05@rebolek @dsunanda Regarding :point_up: [this](https://gitter.im/red/help?at=5f1efccb261ed758ea23250c) topic on Red not being able to read a Rebol saved TXT files, I can now reproduce the problem: it is the character è and similar accented ones which block Red, ASCII code 138.

GiuseppeChillemi
00:02I have had the idea for a /where refinement on series focused functions like append/rename/insert/take/change about 1 month ago. It has taken some time to boil down. but now I have it in the most complete form: *conditionally selecting item form series passed as SOURCE. *

Here it is: [APPEND+](https://github.com/GiuseppeChillemi/mezzanines/blob/master/append%2B) , it needs some refinements but the concept is fully working:



Test: 1
range1: func [data] [all [data > 10 data < 50]]
probe append+/where [a b] [5 11 89 22 55] :range1

Result:
[a b 11 22]


Test: 2
test: [any [((data > 10) and (data < 50))]]
probe append+/where [a b]  [5 11 89 22 55] test

Result:
[a b 11 22]


Thank you again for your help.



00:15* (some = a lot of refinements!!)
toomasv
05:30@GiuseppeChillemi Nice, but it needs still work. E.g. according to test appending should not happen in following (you don't check the test there):
>> append+/where [a b] 5 func [x][all [x > 10 x < 50]]
== [a b 5]
GiuseppeChillemi
11:08Thanks, I'll do. Also, I admit I don't know how to build automatic tests for my code to ckeck if it fails when I do modifications.
toomasv
12:39 May be you can use @hiiamboris ' [assert](https://gitlab.com/hiiamboris/red-mezz-warehouse/-/blob/master/assert.red)?
GiuseppeChillemi
13:18Thank you, new bread for my mouth!
13:24Can Red highlight a link to open the page when you click on it? And is there a mechanism to open a web page on request?
toomasv
13:29Look at browse.
As about highlighting/opening-on-click - it can be done in rich-text, but there is now automation AFAIK.
13:34See e.g. a little toy browser
do https://raw.githubusercontent.com/toomasv/learning/master/browser/text-browser3.red
GiuseppeChillemi
13:48@toomasv
Thank you, Also I don't remember why this code returns -1 on the first click
view  [
	links-list: text-list data ["https://red-lang.org" "http://www.slashdot.org"] on-select [probe face/selected ]
	
]


I have already asked but I can't find the answer.
toomasv
13:50Use on-change, which returns newly selected index.
13:50on-select returns previously selected index, and as you don't have anything selected originally, it returns -1
9214
13:54https://github.com/red/red/issues/4556
GiuseppeChillemi
14:04In @Henrikmk 's Vid Extension Kit on-select returns the list of all selected rows in a block. Empty block means "no selection" (it can happen after the last "unselect") otherwise it returns a block with all the indexes. IMHO, I find the block of indexes approach useful at it simplifies list selections processing without extra conditional checks. A simple forall list [] does not need to start without extra if face/selected <> none. Also, once multi selection will be implemented you will have to check multiple scenarios like having none, numbers! and block! type at the same time.
14:06(However, thanks for the link)
rebolek
14:55@GiuseppeChillemi Red reaquires all files to be UTF-8, however Rebol 2 doesn't talk Unicode and saves files as 8 bit text with code page based on your settings. you either need to save as UTF-8 from Rebol or convert the ASCII text to Unicode in Red.
GiuseppeChillemi
15:08@rebolek I know how to load from Rebol ASCII to Red, but how do I save from Red to ASCII or from REBOL to UTF-8?
ldci
17:12@GiuseppeChillemi in Red save/as none can save as plain text.
GiuseppeChillemi
17:18@ldci Plain text = including high ASCII characters like accented ones or something is somehow filtered?
17:48Again on text-list: is there a way to set select or move the list to a specified index?
toomasv
17:55Something like this?
list: ["one" "two" "three" "four" "five" "six" "seven" "eight" "nine" "ten"]
i: 0 view [text-list data list on-time [if 12 = face/selected: i: i + 1 [unview]] rate 1]
GiuseppeChillemi
18:04Now I have understood why documentation reports (read/write) on face/selected.
ldci
21:12@GiuseppeChillemi including accentuated characters e.g un exemple de texte à la volée
wallysilva
22:29Hi guys,
This function takes 3 consecutive numbers and returns true if any of their sums is equal to seven.
I managed to make it work, but I was wondering what would be a more idiomatic way to rewrite this?
lucky?: function [numbers][
    forall numbers [
        total: if (third numbers) <> none [(first numbers) + (second numbers) + (third numbers)]
        luck: either total = 7 [print true return true][false]   
    ]
    print luck
]
;Tests
lucky? [2 1 5 1 0]
lucky? [0 -2 1 8 ]
lucky? [7 7 7 7 2]
lucky? [3 4 3 4 2]
23:05*It takes a block of numbers and return true if any 3 consecutive numbers sum up to 7.
9214
23:12
text
lucky?: function [streak [block!]][
	set [width: total:] [3 7]
	also no forall streak [
		slice: copy/part streak width
		all [slice/:width total == sum slice return yes]
	]
]
wallysilva
23:32Thank you, Vladimir!
I will study your code and make sure I fully understand it. 🙏
GiuseppeChillemi
23:49Accented characters have given me headaches creating scripts for both Red and Rebol. I have spent some considerable time trying to understand why some script returns me INVALID UTF-8 ENCODING at loading and some others don't. I have converted back and forth from UTF to ASCII until I have learned (NOW) that Red does not load high ASCII characters. Having removed all accented characters I can DO/LOAD %myscript.red on both worlds without changes. Couldn't be this "INVALID UTF-8 ENCODING" be changed to something more meaningful? I admit that until the recent days I have been thinking I was encoding my scripts with the wrong standard :(
ne1uno
23:58line number too

GiuseppeChillemi
00:31+1 but we should open 2 tickets or our requests will be list like drops in the rain.
ne1uno
02:39pass, I think it's a special case of why line number for errors are NP hard or would be slow. even taking a second error tracking pass is not sure to find the same data
02:41does seem picky lately about utf errors no other editors or even R2 notice
cloutiy
03:44@9214 That is next level.
Oldes
10:50@GiuseppeChillemi Red expects UTF-8. _Accented characters_ are not [ASCII](https://en.wikipedia.org/wiki/ASCII) and ASCII is not UTF-8! So if you are not using UTF-8, you are definitely using wrong standard.
bubnenkoff
13:31What is the right way to calculate number of elements in map?
13:32i am requesting data from server that come as JSON ([{},{}, ...]) and I need to know number of elements
GiuseppeChillemi
13:43@Oldes I have just read UTF8 specs and ASCII and UTF8 are the same until hex 7F. So this is the reason why a script load flawlessy either on Rebol and on Red. Then, if I use accented characters Red does not like it, and it is OK for me but I think user should be warned. My proposal is simple: add to the previous error the following text "you may be using accented ASCII characters in your file, which are not compatible to UTF8" that's all.
9214
13:45@bubnenkoff length? keys-of map perhaps. That will give you a number of key/value pairs.
GiuseppeChillemi
13:46(our Latin language newcomers will benefit a lot from this string)
bubnenkoff
13:54> @bubnenkoff length? keys-of map perhaps. That will give you a number of key/value pairs.

not sure that it is:
code:
print response/data
   print type? response/data
   print length? keys-of response/data

result:
data: [[366 "contracts" {contracts/Moskva/contract_Moskva_2015010100_2015020100_001/contract_1770707263715000001_18887516.xml} "Moskva"] [367 "contracts" {contracts/Moskva/contract_Moskva_2015010100_2015020100_001/contract_1770707263715000002_18887624.xml} "Moskva"] [365 "contracts" {contracts/Moskva/contract_Moskva_2015010100_2015020100_001/contract_1770700350615000003_18568535.xml} "Moskva"]]
map
1

9214
14:03As far as I can see you have a #(data [...]) map, with a single key/value pair.
greggirwin
18:25@9214, your lucky number code is a deeply advanced idiomatic example. :^) Could be a fun topic for various approaches.
Oldes
19:45@GiuseppeChillemi Latin language users should appreciate UTF-8 and keep the 8bit iso encoding hell behind.
GiuseppeChillemi
20:12I agree, in fact adding that additional help string users will have more UTF-8 is better than ASCII awareness.

bubnenkoff
12:38Am I right understand that either create new scope?
x: 1
r: 0
either x = 1 
[
	r: 6
]
[
	r: 7
]

print r

result: 0

How to assign value from inside either?
ne1uno
13:04x: 1 r: 0 either x = 1 [ r: 6][ r: 7] print r works, check your format. either doesn't create a context
bubnenkoff
13:15Oh, I forgot that format is affect on logic
9214
13:37Script formatting has no effect on how the code behaves. What likely happened is that you pasted the above snippet in the console:
>> x: 1
== 1
>> r: 0
== 0
>> either x = 1 
*** Script Error: either is missing its true-blk argument
*** Where: either
*** Stack:  

>> [
[        r: 6
[    ]
== [
    r: 6
]
>> [
[        r: 7
[    ]
== [
    r: 7
]
>> 
>> print r
0

Note the error message.
13:39And, speaking of idiomatic solutions:
>> r: pick 6x7 x = 1
== 6
ne1uno
14:21was poorly worded, 'either' followed by console error was never going to work
greggirwin
18:33It's also deeply idiomatic to use the result of either.
>> x: 1
== 1
>> r: either x = 1 [6][7]
== 6
>> x: 2
== 2
>> r: either x = 1 [6][7]
== 7
Respectech
21:56^ I use that method all the time.
21:58I also use this method from time to time:
>> x: 1
== 1
>> r: pick [6 7] x = 1
== 6
>> x: 2
== 2
>> r: pick [6 7] x = 1
== 7
wallysilva
22:02It's great to learn all these idiomatic ways, thank you for sharing guys!
Respectech
23:06This is a little more convoluted, but is also interesting:
>> x: 1
== 1
>> r: any [all [x = 1 6] 7]
== 6
>> x: 2
== 2
>> r: any [all [x = 1 6] 7]
== 7

Respectech
00:06While I'm at it, you can try this one as well:
>> x: 1
== 1
>> select reduce [true 6 false 7] x = 1
== 6
>> select reduce [true 6 false 7] x = 2
== 7
00:08 I forgot to put the r: in front of the select statement, but you get the idea.
bubnenkoff
09:24I want to create local variable with same name as global and mutate it.
x: "hello"
f: function[] [
	x: copy x
	append x " world"
	print x
]
f

x: copy x I thought it will create copy of global x but I am getting error:
*** Script Error: copy does not allow none! for its value argument
toomasv
10:22x: copy system/words/x
endo64
11:48func will not make set-words local to function context, in your function's body:
x: "hello"
f: func[] [
    x: copy x
    append x " world"
    print x
]
f

11:49Similarly: f: function[/extern x] [ ... ] would also work.
11:50Or give the word itself:
x: "hello"
f: function ['word] [
    s: copy get word
    append s " world"
    print s
]
f x
loziniak
12:50Hi! What would be the best structure in Red to store sparse key/value associative array indexed with integer keys, something that could be created like this: a/2: "val1" a/10: "val2" a/1234: "val3"?
9214
13:33@loziniak would [this](https://github.com/red/red/wiki/%5BDOC%5D-Comparison-of-aggregate-values-%28block!-vector!-object!-hash!-map!%29) help?
bubnenkoff
13:47I need to change value in interface after some action
x: 123
view compose [text (rejoin ["value: " to-string x]) button [x: 777]]

I know that I can do t: text and than to access to it from button, but I do not want to duplicate text there
14:12I tried also:
x: "123"
view [text react [face/text: x] ]
toomasv
14:33
text
x: "123" 
view [
    text with [text: rejoin ["value: " x]] 
    f: field "777" 40 
    button "Change" [change/part find/tail t: face/parent/pane/1/text ": " form x: f/data tail t]
]
bubnenkoff
14:34react is only work with widgets, not with regular code?
toomasv
14:38react needs reactive source. x: "123" is not reactive source.
view compose [
    text with [text: rejoin ["value: " x]] react [
        change/part find/tail face/text ": " form x: f/data tail face/text
    ] f: field "123"
]

Reactive sources are not only faces, but any reactor! - see [docs](https://github.com/red/docs/blob/master/en/reactivity.adoc)
bubnenkoff
15:00Is it good idea to make variable reactive to track it change in GUI?
toomasv
15:31It all depends :) Like this?
view compose/deep [
    clock: field rate 1 on-time [face/text: form now/time] 
    at 10x10 text 100 hidden react later [
        if clock/data > (now/time + 5) [
            face/visible?: yes face/text: "Time has come!" clock/rate: none
        ]
    ]
]
greggirwin
16:26@loziniak I used to use blocks, with mezz funcs for set-key/get-key/.... You lose path syntax support that way, but could dialect it if you really wanted to. Now that we have maps, @9214's article will let you decide what's best for your use case.

Rebol2Red
08:42A really nice way to do smooth scrolling but i soon get out of memory and this will even freezes my laptop

After starting this program, rapidly open taskmanager and watch how it eats memory
How can i prevent this?
; create a picture with random red pixels (takes a few seconds to create)
bg: make image! 480x2400	repeat i 1152000 [bg/(i): random red]

y: 1520
code: does [
	if l = 500 [im/rate: none] ; stop after 500 iterations to prevent memory breakdown 
	im/image: copy/part skip bg as-pair 0 y 480x480 ; scroll one line down
	y: y - 1
]
l: 0
view [im: image im1 rate 24 now on-time [do code l: l + 1 ]]
09:25Note: Do'nt be afraid to run the above program. It will not freeze your computer because it will stop after 500 iterations. If the solution is posted over here you may use my code at will.
ldci
10:24@Rebol2Red Draw DSL can help you
Red[
	Needs: view
]
; create a picture with random red pixels (takes a few seconds to create)
bg: make image! 480x2400    
repeat i 1152000 [bg/(i): random red]

xy: 0x0
drawBlk: compose [translate (xy) image bg]
l: bg/size/y

code: does [
	l: l - 10
	if l = 0 [im/rate: none]
	xy/y: to integer! negate l / bg/size/y * (max 0 bg/size/y - im/size/y)
	print xy 
	drawBlk/2: xy
]
view [im: image 480x480  bg 
		rate 24 
		on-time [code]
	do [im/draw: drawBlk]
]

No memory problem
10:25@Rebol2Red for a smooth scrolling use l: l - 1
Rebol2Red
11:25Thank you very much. I overlooked draw dsl.
Though i still wonder if there is a way to use copy and release the memory used.
ldci
11:38@Rebol2Red Basically memory release is done by internal garbage collector (GC). You can try recycle/on or recycle/off and stats.
11:57@Rebol2Red Just for fun :)
Red[
	Needs: view
]
; create a picture with random red pixels (takes a few seconds to create)
bg: make image! 2400x2400  
print rejoin ["Patience! Generating " form bg/size " image..."]
  
repeat i bg/size/x * bg/size/y [bg/(i): random white]

xy: 0x0
drawBlk: compose [translate (xy) image bg]
l: bg/size/y
c: bg/size/x
inc: 1


scroll: does [
	if r1/data [l: l - inc if l <= 0 [l: bg/size/y]]
	if r2/data [l: l + inc if l >= bg/size/y [l: 1]]
	if r3/data [c: c - inc if c = 0 [c: bg/size/x]]
	if r4/data [c: c + inc if c >= bg/size/x [c: 1]]
	;--vertical scrolling
	if any [r1/data r2/data]
		[xy/y: to integer! negate l / bg/size/y * (max 0 bg/size/y - im/size/y)]
	;--horizontal scrolling
	if any [r3/data r4/data]
		[xy/x: to integer! negate c / bg/size/x * (max 0 bg/size/x - im/size/x)]
	drawBlk/2: xy
]


win: layout [
	text 100 "Direction"
	r1: radio 60 "Down"	[if face/data [l: bg/size/y]]
	r2: radio 60 "Up"	[if face/data [l: 1]]	
	r3: radio 60 "Right"[if face/data [c: bg/size/x]]
	r4: radio 60 "Left"	[if face/data [c: 1]]
	pad 20x0
	button "Quit" 		[Quit]
	return
	text 100 "Velocity" 
	slider 100  		[inc: 1 + to-integer face/data * 99 f/text: form inc]
	f: field 30 "1"
	button "Start" 		[im/rate: 24]
	button "Stop"		[im/rate: none]
	return
	im: image 480x480  bg 
		on-time 		[scroll]
	do [im/draw: drawBlk r1/data: true r2/data: r3/data: r4/data: false]
	
]
view win

12:03@Rebol2Red Have also a look here: http://redlcv.blogspot.com/2017/04/how-to-scroll-image.html
9214
12:31@Rebol2Red images are not garbage collected, and you are spawing a new one 24 times per second.
Rebol2Red
12:41@ldci Very nice, thanks
GiuseppeChillemi
13:12Is there a way to build objects without binding their function blocks to the object words?
13:29I have expressed my question in a wrong way: could we create an object without binding its funtion blocks to itself?
ldci
14:20@GiuseppeChillemi Not sure to understand your question. Do you mean an object with external functions?
GiuseppeChillemi
14:31I mean this:

my-vocabulary: [
    next: func [arg] [... any code...   NEXT arg  ...any code...]
    prev: func [arg] [... any code...   PREV arg  ...any code...]
    skip: func [arg] [... any code...   SKIP arg  ...any code...]
]


NEXT/PREV/SKIP inside functions' body are bound to my-vocabulary but I don't want this, I need to bound them to the global system/words vocabulary.
14:36Note: I know that I can use an explicit path as system/words/WORD but I do not want to use explicit paths, it should be implicit in the word binding.
15:06Don't mind, I have found a solution thanks to another [problem of the past:](https://gitter.im/red/help?at=5eb6a6940b23797ec0715d1e)
15:09
b: make object! [
  skip: func [s [series!] value][skip s 4] 
  next: func [s [series!]] bind [skip s 1] system/words]
]



15:10
>> b/next [1 2 3 4 5 6 7 8]
== [2 3 4 5 6 7 8]


15:11Also @hiiamboris has a mezzanine to [bind only](https://gitlab.com/hiiamboris/red-mezz-warehouse/-/blob/master/bind-only.red) one or few words.
15:15With this method we can create funtion bodies inside objects whose words are taken from system/words instead of the object. This is a way to change the default vocabulary to system/words for some or all the words of the function body of one or many object members.
ldci
16:24@GiuseppeChillemi Interesting
pekr
17:13 IIRC, you could use setto set function in object to global context?
hiiamboris
18:34@GiuseppeChillemi
>> x: construct compose [x: (does [? x])]
== make object! [
    x: func [][? x]
]
>> x/x
X is an object! with the following words and values:
     x  function!     []
18:35or also you can set your function words to function values after creating the object, whatever seems best for your case
9214
19:08
text
>> set x: construct [x:] does [?? x]
== func [][?? x]
>> x/x
x: make object! [
    x: func [][?? x]
]
GiuseppeChillemi
23:21Construct is new to me. I have played a little on the REPL:

It seems it creates an object with just the words, setting them to none.

>> x: construct [x:] 
== make object! [
    x: none
]


No evaluation

>> construct [x: a b] 
== make object! [
    x: 'a
]


Words after set-word sare just converted to lit-word, others are.. dropped/ignored?
23:23So, in the first part, I am creating a context with just the word x which is initialized to none.
23:29Then:

>> does [?? x]
== func [][?? x]


From: set x: construct [x:] does [?? x]

I am setting what? X in the object created by construct to the function func [][?? x]?
23:30So X inside the function body is not bound, isn't it?
23:32And:

>> x
== make object! [
    x: func [][?? x]
]
>> x/x
x: make object! [
    x: func [][?? x]
]

23:32They both return X in the system/words context.
Have I understood the mechanism correctly?

rebolek
08:26@GiuseppeChillemi I made simple codepage converter (currently it can read only, but support for write can be added easily). It doesn't contain any codepages, but grabs them from Wikipedia (tested with Windows-1250 and Windows-1252, grabber may need adjustments for other pages):

; standard READ requires UTF-8 text, but IDNES is known not only for shitty news, but also for a shitty webpage

>> page: read http://idnes.cz
*** Access Error: invalid UTF-8 encoding: #{96207320}
*** Where: read
*** Stack:

; let's switch to codepage aware READ-AS

>> do %codepage.red
== func [...
>> page: read-as http://indes.cz 'Windows-1250
== {<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">^M^/<html xmlns="http://www.w3.org/1999/xhtml"...


It's available at https://gitlab.com/rebolek/codepage
09:03write-as support added. Characters missing in required codepage are encoded as zero byte.
Red-Beginner
15:55Hello all.
I have wrote a script for to use Red on my cell phone:
https://pastebin.ubuntu.com/p/D2HcNtgXf6/
However I could not compile it.
What do I need for this?
9214
16:03@Red-Beginner by cell phone you mean Android device?
Red-Beginner
16:09Yes.
16:12Sorry for the missing message.
9214
16:16@Red-Beginner Android support for Red is pending, and is worked on in a private development branch. This means that you cannot compile your scripts to use on a smartphone, for now.
Red-Beginner
16:19I understand. Thanks for your message.
GiuseppeChillemi
17:21Does VSCode permit to open view the source of a function once you hover on its name without the needing to click on it?
21:39@rebolek thank you, nice one!
wallysilva
22:01@GiuseppeChillemi It does, but it never worked for me as I get an error when it tries to connect to the server.
GiuseppeChillemi
22:44Could separate REPL like output consoles be opened? And we could have them in a View panel?

wallysilva
02:33@GiuseppeChillemi I've seen that on Nenad's [livecode demos](https://github.com/red/community/tree/master/demos), so I guess it's doable.
GiuseppeChillemi
07:48@wallysilva try the previous version of the plugin, I was able to run it after the downgrade.
kermitaner
13:56
Red []
m: #()

o: make object! [
  name: copy ""
  list: copy []
]

a: copy o
a/name: "A"
a/list: [1 2]

put m a/name a

b: copy o
b/name: "B"
b/list: [3 4]

put m b/name b

?? m
save/all %data.txt m
n:  load %data.txt

?? n
13:57hello, I'm trying to save and load a map, however the loaded map doesn't match the original one, whats wrong ?
9214
14:12@kermitaner maps don't evaluate their keys, so your saved map cannot be properly loaded back.
>> put map: #() 'foo object [bar: 1]
== make object! [
    bar: 1
]
>> map
== #(
    foo: make object! [
        bar: 1
    ]
)
>> save %test map
>> load %test
== #(
    foo: make
    object!: [
        bar: 1
    ]
)

In loaded map, odd values are treated as "keys" and even values as "values". Not to mention that textual format that you save into is lossy: make object! [...] turns into 3 separates values.
kermitaner
14:17thx, guess i have to make an other approach, shouldn't be too difficult to work with blocks only and then convert to map again
9214
14:22@kermitaner you can use Redbin codec https://github.com/red/red/pull/4586 if you want to. I need to fix the encoder so that it accepts files first though.
>> put map: #() 'foo object [bar: 1]
== make object! [
    bar: 1
]
>> save/as %test map 'redbin
>> load/as read/binary %test 'redbin
== #(
    foo: make object! [
        bar: 1
    ]
)
kermitaner
14:26cool, i will check it, thx
loziniak
14:35@9214 @greggirwin thanks for help with indexing!
9214
15:10@kermitaner fixed, should be even more trivial now:
>> put map: #() 'foo object [bar: 1]
== make object! [
    bar: 1
]
>> save %test.redbin map
>> load %test.redbin
== #(
    foo: make object! [
        bar: 1
    ]
)
15:10@loziniak you are welcome!
theSherwood
15:30Does red currently have any means of implementing timeouts? I'm wanting to write a little daemon.
9214
15:39@theSherwood there's a rudimentary wait, although I'm not sure if it will suit your needs.
theSherwood
15:42@9214 Thanks! Hopefully it will do the job. I'm going to attempt to build a primitive file watcher.
9214
15:44@theSherwood should be doable. Your watcher can simply spin in a loop, wait and periodically query files, which right now returns the last modification date.
theSherwood
15:53Yep. That's the exact plan.
wallysilva
18:44@GiuseppeChillemi Good to know, thanks!
theSherwood
21:13Is it possible to define a third-party type from R/S for use in Red and is anyone aware of any examples?
9214
21:24@theSherwood, @BeardPower authored some [notes](https://github.com/BeardPower/red/wiki/How-to-create-a-new-datatype-for-Red) on that and left a simple [example](https://gist.github.com/BeardPower/6523871b6a60c8a3a4682b202c83ae5d). It's not a trivial process in general, which requires extending the language runtime, and ideally adding lexer, compiler, and Redbin support. I can elaborate if you have something specific in mind.
theSherwood
21:33I was thinking about some immutable collection types. But that's probably beyond my abilities at this point. But I'll be sure to come talk to you about it should I get the courage to give it a try.
9214
21:38@theSherwood there is some very old and, how to say, peculiar [proof-of-concept](https://gist.github.com/numberjay/3df8f13044145c6dde1918ea2cdfe3b8) for immutable blocks. Straight rewrite from Clojure, judging by the coding style and implementation.
21:39A reasonable thing to do first is prototyping.
theSherwood
21:40Thanks, @9214 . I remember seeing that. Thanks for reminding me

bubnenkoff
12:36How to look for in github Red projects? language:red ?
12:40Is it only implementation of xpath? http://www.rebol.org/view-script.r?script=xpath.r or there is other implementations?
ne1uno
13:46anything here? https://ross-gill.com/page/XML_and_Rebol
13:49github has advanced search, but it's not much better. adding site:github.com works on google and maybe bing
bubnenkoff
17:53is the another way to create empty map except: >> x: make map! 0?
18:16I want to create map from block, that look: {aa: false bb: false cc: false}
I can't understand how to use element w value instead of w as name:
x: make map! 0
ww: [aa bb cc]
foreach w ww [set 'x/w false]


I understand that I should evaluate w but I can't understand how to do it.
9214
18:19
text
>> m: #()
== #()
>> foreach w [a b c][m/:w: false]
== false
>> m
== #(
    a: false
    b: false
    c: false
)
bubnenkoff
18:21oh great!
wallysilva
19:18@9214 That's beautiful!
theSherwood
22:02Is there anything like a fluent interface possible for Red objects?
9214
22:13@theSherwood with external wrapper maybe, since there are no "methods" to chain, technically speaking; I'd personally consider this an anti-pattern. Fowler dubbing these DSLs made me chuckled when I read his [book](https://www.martinfowler.com/books/dsl.html) a few years back, in a sense that you can do much more than that in Red.
theSherwood
22:17Maybe something like a threading macro would be best then. I'm mostly just wanting the sequential syntax.
9214
22:19@theSherwood ah, [that](https://gitter.im/red/help?at=5e7cdbe2bf65703264de2aae). @hiiamboris has a more sophisticated [stepwise](https://gitlab.com/hiiamboris/red-mezz-warehouse/-/tree/master) version.
theSherwood
22:31Interesting. I'll have to look into this. Thanks, @9214

Rebol2Red
07:33@rebolek
do %codepage.red
page: read-as http://indes.cz 'Windows-1250
print page

I get *** Script Error: get-codepage does not allow binary for its codepage argument

I have to mention that the page is changed to: This page is registered
rebolek
07:43@Rebol2Red Thanks, I am working on some improvements, so maybe I pushed partially updated version, I will look into that.
Rebol2Red
07:49@rebolek Thanks in advance. I'll check it out later. Take your time.
rebolek
07:57@Rebol2Red The new version will have the most popular non-CJK codepages predownloaded and stored in binary format for better size.
Rebol2Red
08:13@rebolek Will it work with non-utf8 files too?
bubnenkoff
08:19Does Red have data struct that work as OrderedDict?
rebolek
08:27You can make one yourself with on-deep-change*, see an example in "Object ownership system" chapter in https://www.red-lang.org/search/label/ownership
bubnenkoff
09:43I need to create datastructure like: [[a false] [b false] [c false]]

This code produce not exactly what I need.
l: []
foreach w [a b c][append l reduce [[w false]]]

>> probe l
[[w false] [w false] [w false]]
== [[w false] [w false] [w false]]


How to create block with nested blocks?
endo64
11:52
foreach w [a b c][append l compose/deep [[(w) (false)]]]

11:52In your example even falses are not logic values, instead they are word!s
9214
12:17@bubnenkoff if you need alphabetical order and boolean flags, then consider using bitset!.
12:19But it would be better if you tell us what [problem](http://xyproblem.info/) are you trying to solve.
TimeSlip
17:50I've never had to do this until now but how do you remove a "declared" item from an object? Do I have to just redefine it or is there a word?
17:59What I mean by this is say I had a: make object! [mistake: none ok: none] and I wanted to get rid of the 'mistake.
greggirwin
18:01You can't currently change the words of an object. To remove words you need to remake the object, excluding those you don't want to keep. e.g.
remove-words: func [
	"Returns a copy of the object with the specified words removed."
	object [object!]
	words  [word! block!] "The word, or words, to remove"
	/local spec
][
	spec: body-of object
	foreach word compose [(words)] [
		remove/part find/same/skip spec to set-word! word 2 2
	]
	make object! spec
]


remove-words o 'mistake. But you can't change the object in place.
TimeSlip
18:30 @greggirwin, thank you so much. Like I said, it was the first time I ever put myself in a position having to do this.

cloutiy
15:51@TimeSlip @greggirwin I think I asked a similar question before, and Gregg suggested perhaps I should be using a map! to do what I was trying to do. Since map! allows you to extend or remove. Depends what your use case is and whether map! could be used instead of object!
9214
16:03[Comparison of aggregate values in Red](https://github.com/red/red/wiki/%5BDOC%5D-Comparison-of-aggregate-values-%28block!-vector!-object!-hash!-map!%29).
TimeSlip
22:56@cloutiy Thank you.

theSherwood
02:29Do to-string or to-block have to iterate over the series in order to convert it?
02:44Whoops. Dumb question. They both make new data structures. So yes.
Yamoon2018
20:31I dont know if I can ask such a question here or not, I apologize if not, its just I would like to know if someone can help me to get REMOTE work .
9214
20:37@Yamoon2018 well, that's not what this room is for. Regardless, it is customary to leave your CV with contact info when you seek employment, so that interested parties can reach out to you later.

Yamoon2018
06:26@9214 , so in which room should I leave my CV
9214
07:23@Yamoon2018 you should leave your CV on a job board; e.g. HN runs monthly "who wants to be hired?" [threads](https://news.ycombinator.com/submitted?id=whoishiring).
xmonader
13:30Which docs more appropriate for red? rebol 2.3 or rebol 3?
13:31also another question, when to put conditions in blocks (if / either don't require it) but for while and for it does?
GiuseppeChillemi
13:40I suggest this because Rebol3 Documentation is not complete and you would find a mixture of Rebol 2.3 and Rebol 3 documentation. Also, the only official Rebol/CORE manual if for 2.3 with updates to 2.7 where available.
xmonader
14:02thanks!
giesse
18:48@xmonader try writing your own version of while *without* using a block for the condition argument... :)

bubnenkoff
12:32I need to access by index to tags, but index is declared as: i: 2
tags: [
    ["dd" "aa" "hh"] 
    ["aa" "hh" "dd"] 
    ["aa" "bb" "cc" "dd"]
]


tags/i do not works. The task is move second element with next to get:
tags: [
    ["dd" "aa" "hh"] 
    ["hh" "dd"] 
    ["aa" "bb" "cc" "dd"]
]
9214
12:32tags/:i.
bubnenkoff
12:33Oh! Cool!
12:39What wrong with this string?
>> if (first t) = needle [tags\:i: next tags\:i]
*** Syntax Error: missing #"]" at "\:i: next tags\:i]"
9214
12:40@bubnenkoff slashes in your paths look in the wrong direction.
12:42> Oh! Cool!

[Double cool](https://gitter.im/red/help?at=5f3d6c8578f4a8018014d777) I'd say.
Red-Beginner
17:09What about it
tags/(i)
rebolek
17:10That's also possible.
17:10or pick tags i
kidd
18:38I'm just getting started with Red, and trying what's on http://helpin.red/Usingwords.html, assigning a set-word! to a get-word! and then trying with lit-word!, but the results I get are a bit different. not the extra quoting
>> p: :print
== make native! [["Outputs a value followed by a newline" 
    value [any-type!]
]]
>> p "123"
123
>> p: 'print
== print
>> p "123"
== "123"
18:38not sure even if it should work, but just trying to mess around
9214
18:44@kidd quoting in Red behaves the same way as in Lisps. p: 'print sets p to a word (a "symbol") print, not to a function to which we refer as print.

When p "123" expression is evaluated, p evaluates to print and "123" evaluates to itself. Since "123" was the last value in the expression, it then got returned as a result.
kidd
18:46aha! reduce [p "123"] has the answer!
18:46thanks!
9214
18:46There's no, how to say, "double evaluation" in Red, unlike e.g. in Scheme. When p evaluates to print, print itself is not re-evaluated at the call site.
18:48@kidd yes, so you need to add an extra layer of evaluation yourself:
>> p: 'print
== print
>> reduce [p "123"]
== [print "123"]
>> do reduce [p "123"]
123

kidd
18:48cool, that makes total sense. thanks
20:31I've another question related to indexing of blocks that was asked a bit up. the fact that [1 3 5]/2 doesn't work, is it something at the low level of Red, or it happens 'naturally'? I can't figure out when refinements apply or not (yet)
20:32it seems like it's a syntax thing, because the following works ok.
a: [1 3 5]
a/2
9214
20:37@kidd [1 3 5]/2 is a syntactically invalid path. You can construct it at run-time though:
>> as path! [[1 3 5] 2]
== [1 3 5]/2

But then the evaluator has the checks in order and will catch it right away:
>> do as path! [[1 3 5] 2]
*** Script Error: path must start with a word: 1 3 5/2
*** Where: do
*** Stack:

It's not that Red cannot support that, it's a question of the purposefulness of such construct: block with an index attached to it is akin to an "unresolved" element in a series, or none if indexing goes out of boundaries.
kidd
20:44ahm... I see. Thanks again :+1:
9214
20:44Also note that there are no actual refinements in the paths. That fould be:
>> franken: [path wut]
== [path wut]
>> as path! [franken /path]
== franken//path
>> do as path! [franken /path]
== wut
>> franken//path
*** Syntax Error: (line 1) invalid path at franken//path
*** Where: case
*** Stack: load

There's an important and subtle point in here: both run-time function and lexer essentially act as constructors for values, but the former is more mechanical and permissive, and the latter is more human-oriented and restrictive.
kidd
20:49woah noice. With all the flexibility I'm seeing (just 4 days learning), I wonder how understandable/readable are big Red/REBOL codebases. It's like you eat macros for breakfast :) . Are there concerns about That dynamism going against readability/adoption?
20:52When I type in chats/emails, I'm now aware whether I type a /, or !, or ? and what meaning do they have. This context thing grows on you I guess
9214
20:53@kidd the main hurdle newcomers face is fixed-arity and absence of any delimiters around function arguments, which means that to read an expression you need to know the arity of each function in it beforehand. Grouping sub-expressions in paren!s acts as the training wheels in such cases. And then there are embedded DSLs (aka dialects) which, I would argue, improve the readability by a significant factor.
20:55A case in point, since you know Lisps: [here](https://ahungry.com/blog/2020-04-24-Puny-GUI-Puppy-Finder.html) is a relatively small GUI program in [Janet](https://janet-lang.org/), and [here](https://gist.github.com/9214/dfa15d37342065dbf368eae35abcdc37) is its 1-to-1 rewrite in Red.
kidd
wallysilva
21:18Wow!

dsunanda
13:21How do I break out of the event loop from the console? ie if my entire script is just this one line, how do I get it to halt?
>> do-events

bubnenkoff
11:11I need to iterate thru pairs of data and set for special pairs second value to "12345".
data: [
	regNum none
	price none
	lots [
		lot [
			code none ; I need to set none to 12345
		]
	]
]

data-walk: func[data] [
	foreach [a b] data [
		either (type? b) = block! [
			print [a " is multiple"]
			data-walk b
			] [
			; a is single
			if a = 'code [
				print ["----> " a]
				b: "12345"
			]
			
			]
		]
	]
data-walk data

probe data


This code does not work. I think the reason is I should use full path when I am setting value. But probable it's possible to do in this way
kidd
11:38
; a is single
            if a = 'code [
                print ["----> " a]
                data/:a: "12345"
            ]
11:39@bubnenkoff ^ that did it for me
11:41b: "123" would be setting none (b is the value of the tuple) to "123"? I've no idea what would try to do there
11:43data/a: "123" says Script Error: cannot set none in path data/a:, which means that a is not evaluated, so you're trying to add to that /a path. What I don't know is why data can't be extended with new keys though.
11:43data/:a: "123" it had to work :). As I parse it is :a being the read-word!, and evaluating it to 'code, then the second : makes it a set-word! .
11:45But take all this with a grain of salt. I'm the new guy here
rebolek
11:52@kidd good suggestion, data/:a is a good way to achieve what @bubnenkoff wants, just some corrections:
b: "123" doesn't set none to "123", it changes value of word b from none to "123". And because there is no link between b and the original block, it's not very useful.
:a is get-word!, not read-word! and the second : makes it set-path! as it's part of path!.
Another way to achive the save result would be data/code: "12345" which is the same as data/:a: "12345" because value of ais code.
kidd
11:56oh, I missed both "*-word!" types... how cool is that? thanks @rebolek :)
rebolek
11:58you're welcome!
nedzadarek
13:48Some time ago I remember talk about pair! (e.g. 2x3) with the float! support. Do you have any news on that. Can I expected it "soon" or was it just wishful thinking of somebody?
toomasv
13:50The above code will break down if there may be several pairs with same first element. One alternative way is
data: [
    regNum none
    price none
    lots [
        lot [
            code none ; I need to set none to 12345
			some none
			code none
        ]
    ]
	price none
]
data-walk: func [data][
	forall data [
		either block? data/2 [
			print [data/1 "is multiple"]
			data-walk data/2
		][
			switch data/1 [
				code [print "----> code" data/2: "12345"]
				price [print "----> price" data/2: 54321]
			]
		]
		data: next data
	]
]
rebolek
14:03@nedzadarek it's not a wishful thinking, it's a feature that's going to be implemented but IIRC it waits for a better syntax than in R3 (3.141592653x2.7182818284).
nedzadarek
14:04@rebolek I see, so it's not near future. Thank you.
rebolek
14:05If someone comes with a nice design tomorrow, it can be implemented fast :-)
9214
14:08IIRC there was a discussion about introducing a new datatype specifically for float-based pairs/triples, of the form (x, y).
14:15@rebolek the main problem is that there's not enough space in a pair! slot for two 64-bit floating-point values, so they are limited to 32-bit only.Internally, you also need to differentiate between pairs with integers and pairs with floats, but this can be done with a bit flag in the header.
rebolek
14:18That can be solved by moving to 64bit and expanding value slot size >:-D
9214
14:24@rebolek that's the spirit!
nedzadarek
14:45@rebolek designing good syntax might be little harder. It's subjective topic. And seeing that the Red doesn't have "extendable type system" prove this a little. As fair I remember the Red had limited space for types, so you couldn't just add whatever you want... but I might be wrong.
9214
15:02> As fair I remember the Red had limited space for types, so you couldn't just add whatever you want

That's not true. You can add as many types as you want, but it is very hard to design literal forms for them, because the lexical space is very tight and at some point they will start to collide. E.g. in the example above, (x, y) looks like a paren! on the first sight. Some datatypes (vector!, function!, hash!, etc) don't have literal forms at all and can be constructed at run-time only.
theSherwood
15:06x(a b c) would have some similarity to pairs (eg 5x6) and Red uses the prefixing parens thing for map! literals. Commas feel a little strange at this point.
9214
15:07@theSherwood that's a word x followed by (a b c) :wink:
>> load "x(a b c)"
== [x (a b c)]
15:08Besides, (x, y, z) (aka point!) was chosen precisely because it mimics the human notation for coordinates.
theSherwood
15:14For sure, it's a word now. But making x() distinct from x () could open up a lot of lexical space for new literals
15:16Of course that would be a huge breaking change for lexing.
9214
15:19Well, no, actually it will take away from lexical space. What is a/b/x()? :x(), 'x()? yx()? Also, this "stickiness" of words to series delimites is used quite a lot, e.g. in Red/System #define FOO(bar baz) ... is a conventional form for macros.
nedzadarek
15:21@9214 :+1:
@theSherwood using some word + (), {}, [] without space would be confusing. X (a b c) means "run X function with (a b c)as an argument" or " evaluate X as type with (a b c) as an argument". One space could break your code... and you don't want it. Unless you want to do python like language (or hard to code language).
That's why I suggested some time ago 1-2 syntax(es) for an extendable types - https://github.com/red/red/wiki/%5BPROP%5D-User-defined-types-(UDT)-and-dependent-types .
theSherwood
15:28Interesting. I'm actually pretty comfortable with the idea of 1 space being able to break your code (1 + 1 vs 1 +1). For me, the biggest issue is the breaking change. As @9214 indicated, there's a lot of code that uses the form x(a b c) already.
15:38> Well, no, actually it will take away from lexical space. What is a/b/x()? :x(), 'x()? yx()?

@9214 I see that as adding to lexical space because a/b/x() now means something different from a/b/x (). That's creates a difference (another bit of information), strictly increasing the space of possible combinations. Before x()_, x_(), and _x() were all equivalent. But with this change, you now have new meaning. _x() and x()_ would mean one thing. x_() would mean something else.
15:39(Pretend the underscores are spaces)
9214
15:51Is a/b/x() "select from a/b, whatever it is, with key x()", or is it an entirely new lexical form that now needs to be supported (or not)? Is :x() a get-word! then paren!, or a get-point!, or neither of the two? What about @max()? Is that a ref! followed by paren!, or is it a @ma x()? http://min.max()? mad@max(), %file-x()?

By freeing x you're throwing all the other literals into a morass of syntactical ambiguity.
15:57
>> [%#()]
== [%# ()]
>> [http://#()]
== [http://# ()]
theSherwood
16:03I wouldn't have thought it would just affect x(). I was more thinking that any word char (or group of word chars) prepended to () (or possibly other delimiters "", [], {}) would constitute a possible literal form. So y(), a(), abc-1() could all be possible (though not necessarily defined) literals.
16:05I'm thinking how you solve this more general problem:

> You can add as many types as you want, but it is very hard to design literal forms for them, because the lexical space is very tight and at some point they will start to collide
nedzadarek
16:30@theSherwood user defined types. Many languages does it in a different way. In the object oriented programming you are using classes/objects, e.g.
class Foo
   data-a = 1
   fun-b = func [][data-a]
end
var f = Foo(42, func [a] [a * data-a])
f/fun-b(1) ; => 10

or if you know what types your variables are you can use words used in a different types:
type Foo = a | b
type Baz = a | b | c
var qux : Foo
qux = a

here qux knows that it is the Foo type.

There are probably more ways but I don't remember on the top of my head.

ps. of course it's a pseudocode that may resemble some common languages (Ruby & SML as fair I remember).
theSherwood
16:39@nedzadarek Lots of options for designing user-defined types, I think. I was thinking specifically of being able to create literal syntax for types (whether user-defined or no). As @9214 mentioned, the lexical space is very tight.

bubnenkoff
10:42mmm... it work, but if any other element on
> The above code will break down if there may be several pairs with same first element. One alternative way is
>
> data: [
>     regNum none
>     price none
>     lots [
>         lot [
>             code none ; I need to set none to 12345
> 			some none
> 			code none
>         ]
>     ]
> 	price none
> ]
> data-walk: func [data][
> 	forall data [
> 		either block? data/2 [
> 			print [data/1 "is multiple"]
> 			data-walk data/2
> 		][
> 			switch data/1 [
> 				code [print "----> code" data/2: "12345"]
> 				price [print "----> price" data/2: 54321]
> 			]
> 		]
> 		data: next data
> 	]
> ]
>


Many thanks! Could you explain the reason of this issue? I faced with it and only after read your example. Also I decided that it's better in my case use regNum: none instead of regNum none. Could you help me to adopt your example to this data structure:
data: [
    regNum: none
    price: none
    lots: [
        lot: [
            code: none ; I need to set none to 12345
            some: none
            code: none
        ]
    ]
    price: none
]


I tried you use foreach [a b] data [] but not sure how to code should look like at assign part: data/2: "12345" (in your example)
rebolek
10:44the easiest change would be switch data/1 -> switch to word! data/1
toomasv
11:22Alternatively add colon to switch-tests:
switch data/1 [
        code: [print "----> code" data/2: "12345"]
        price: [print "----> price" data/2: 54321]
]

rebolek
13:28It's interesting that switch requires exact value, unlike for example find: find [a b c] quote b: == [b c]
toomasv
16:37Yep, but find has /case refinement for exact matching:
>> find/case [a b c] quote b:
== none

rebolek
05:11And switch doesn't.
However:

>> switch "foo" ["FoO" [print "bar"]]
bar


So with any-word!, switch behaviour is like find/case, but with string!, it's like plain find.

Therefore I believe that switch should also get /case refinement to be more consistent with find.
bubnenkoff
10:47
data: [
	regNum: none
	maxPrice: none
	lots: [
		number: none
		objects: [
			name: none
		]
		number: none
		objects: [
			name: none
		]		
	]
]

foo: func [tag value] [
	data-walk: func[data] [
		probe data
		forall data [
			either block? data/2  [
				data-walk data/2
				] [
				 if equal? to-string data/1 to-string tag [
					data/2:  value
				 ]
				]
			]
	]
	data-walk data
]

list: ["regNum" 777 maxPrice: 950 "number" "1" "number" "2" "name" "Apples" "name" "Bananas"]
foreach [a b] list [foo a b]

probe data

result:
>> probe data
[
    regNum: 777 
    maxPrice: 950 
    lots: [
        number: "2" 
        objects: [
            name: "Bananas"
        ] 
        number: "2" 
        objects: [
            name: "Bananas"
        ]
    ]
]


I am stuck with this case. I want to travel via list and fill data. The problem that multiple sections will get latest value from list. I tried to move data with next after filling. But it's not work because I have recursion call.


12:05can't edit example above: maxPrice: 950 should be in another format of course: "maxPrice" 950
rebolek
12:13The code is doing exactly what it says. It changes every "name" to "Apples" first and then to "Bananas". But you probably want to change the value only when it's none and then exit the foo function.
bubnenkoff
12:19Yes, you are right, but I can't understand how to get it work as you said
rebolek
12:35because your function is recursive, you need some global attribute (at foo level) to know if you should reenter the function. Let's say changed? that would be initialy set to false. You would call data-walk from data-walk only when changed? is false and when you change the value, you also set changed? to true. That way you prevent second change.
bubnenkoff
12:50@rebolek I did, but it do not work:
data: [
	regNum: none
	maxPrice: none
	lots: [
		number: none
		objects: [
			name: none
		]
		number: none
		objects: [
			name: none
		]		
	]
]

foo: func [tag value] [
	changed?: false
	data-walk: func[data] [
		forall data [
			either block? data/2  [
				if (changed? = false) [
					data-walk data/2
				]
				] [
				 if equal? to-string data/1 to-string tag [
					data/2:  value
					changed?: true
				 ]
				]
			]
	]
	data-walk data
]

list: ["regNum" 777 "maxPrice" 950 "number" "1" "number" "2" "name" "Apples" "name" "Bananas"]
foreach [a b] list [foo a b]

probe data

rebolek
13:09I am on phone now, so I cannot post the working code, but it looks more or same less
bubnenkoff
13:18ok, but there is some error in mine
loziniak
14:18Hi! I got used to the rule, that result of arithmetic operation is of first argument's type. I noticed it has changed recently. Is there more info on that somewhere?
>> 21 / 5
== 4.2
14:26It makes a lot of code obsolete.
GaryMiller
14:59I ran into the same thing recently when I upgraded and had to add the to Integer! to fix it. I guess why it worked before was because EndingLine held an integer.
PatternsKnownByAI: to integer! (EndingLine - StartingLine / 5)
But I agree that the new behavior seems to be the correct one.
9214
15:05@loziniak see [here](https://github.com/red/red/issues/2433#issuecomment-612173542). It's a breaking change, but it's better to introduce it now than later.
15:07> result of arithmetic operation is of first argument's type.

There's no such rule.
>> 0 + $0
== $0.00
>> 0 + 0.0
== 0.0
>> 0 + 0%
== 0.0
>> 0 + 1.2.3
== 1.2.3


loziniak
19:30thanks! it was only in my head, apparently :-)

bubnenkoff
16:18> I am on phone now, so I cannot post the working code, but it looks more or same less

Could you post an example when you will be near PC? I am still trying to get code work, but there is still issues:
data: [
    regNum: none
    maxPrice: none
    lots: [
        number: none
        objects: [
            name: none
        ]
        number: none
        objects: [
            name: none
        ]        
    ]
]

foo: func [tag value] [
    data-walk: func[data] [
        forall data [
            either block? data/2  [
                data-walk data/2
                ] [
                 if equal? to-string data/1 to-string tag [
				 if none? reduce data/2 [
					data/2: value
					break
				 ]
					
                 ]
                ]
            ]
    ]
    data-walk data
]

list: ["regNum" 777 "maxPrice" 950 "number" "1" "number" "2" "name" "Apples" "name" "Bananas"]
foreach [a b] list [foo a b]

probe data


result:
[
    regNum: 777 
    maxPrice: 950 
    lots: [
        number: "1" 
        objects: [
            name: "Apples"
        ] 
        number: "2" 
        objects: [
            name: "Apples"
        ]
    ]
]


The issues with nested name element
toomasv
17:17
data-walk: func[data tag value] [
	forall data [
		either block? data/2  [
			if data-walk data/2 tag value [return true]
		] [
			all [
				equal? to-string data/1 to-string tag 
				'none = data/2 
				return data/2: value
			]
		]
		data: next data
		false
	]
]

list: ["regNum" 777 "maxPrice" 950 "number" "1" "number" "2" "name" "Apples" "name" "Bananas"]
foreach [a b] list [data-walk data a b]
bubnenkoff
17:21@toomasv Big thanks!
toomasv
17:25You are welcome! Do you understand why are there returns or next or false?
bubnenkoff
17:26Could you explain please! I am right now trying to understand code
17:39Wow! I got my variant work too!
data: [
    regNum: none
    maxPrice: none
    lots: [
        number: none
        objects: [
            name: none
        ]
        number: none
        objects: [
            name: none
        ]        
    ]
]

foo: func [tag value] [
	; print ["tag: " tag " value: " value]
	changed?: false
    data-walk: func[data] [
        forall data [
            either block? data/2  [
                data-walk data/2
                ] [
                 if equal? to-string data/1 to-string tag [
				 if (changed? = false)
				 [
					 if none? reduce data/2 [
						data/2: value
						changed?: true
						print ["tag: " tag " value: " value]
						break
					 ]
				  ]
                 ]
                ]
            ]
    ]
    data-walk data
]

list: ["regNum" 777 "maxPrice" 950 "number" "1" "number" "2" "name" "Apples" "name" "Bananas"]
foreach [a b] list [foo a b]

probe data

produce:
>> probe data
[
    regNum: 777 
    maxPrice: 950 
    lots: [
        number: "1" 
        objects: [
            name: "Apples"
        ] 
        number: "2" 
        objects: [
            name: "Bananas"
        ]
    ]
]
rebred
17:39how do I check if a value has been assigned to a word without getting an error ? (if the word has ever been created)
toomasv
17:41@bubnenkoff Good! Then there is no need for explanations :smile:
17:41@rebred This?
>> value? 'word
== false
bubnenkoff
17:43> @bubnenkoff Good! Then there is no need for explanations :smile:

Please explain why your version need: data: next data ?
toomasv
17:44Because forall walks every value. In your case only every second value needs to be looked at. So there is no need to check the second value of the pair. data: next data skips the second value -- you already checked it with data/2 and possibly changed it.
rebred
17:49@toomasv that's great !!! thank you!!
toomasv
17:50@rebred :smile:
17:54@bubnenkoff Constructs like
if test1 [
    if test2 [
        if test3 [
            ...
]]]

get quickly messy. Better use all [test1 test2 test3 ...]
rebred
17:58how do I delete a word from memory ?
toomasv
17:59unset 'word ?
rebred
18:01@toomasv great!! thank you!!!
toomasv
18:07:+1:

bubnenkoff
11:07How to set delimeter to rejoin? I need to get from ["aa" "bb"] next result: "aa_bb"
rebolek
11:11there's no such function yet, you need to write one yourself. For example:
format: func [value delim /local v][collect/into [keep first value foreach v next value [keep delim keep v]] copy ""]
>> format ["aa" "bb"] #"_"
== "aa_bb"
nedzadarek
15:08What do you think about [this](https://github.com/nedzadarek/red-extra-shape) that let's you add new shapes and other things to a draw block. I have written this for small projects (like [power point presentations](https://www.youtube.com/watch?v=Gjev8RkqO1k) - adds some shapes and other simple things) so I am not sure how it would scale.
toomasv
19:54@bubnenkoff Have a look at [concat](https://gist.github.com/toomasv/fd651f24e18d7bc85d05204cc5f828d2) too.

theSherwood
04:51Any idea why this throws an error?
mapping: function [transform][
	function [reduce*] compose [
		t: (:transform)
	]
]

a: mapping function [id][id]
probe a :reduce*

error:
*** Script Error: ?function? is missing its id argument
*** Where: t
*** Stack: probe a

Why is t being called?
rebolek
05:24How old is your version? I get different error:
>> a :reduce*
*** Script Error: = does not allow unset for its reduce* argument
*** Where: a
*** Stack: a
theSherwood
05:28Red 0.6.4 for macOS built 23-Jul-2020/13:50:28-06:00 commit #171adb6
05:29Ahh. Sorry. reduce* is a function i wrote but didn't include.
05:29
reduce*: function [
	coll
	reducer
	/into
		buffer
][
	accumulator: either into [buffer][to type? coll []]
	foreach i coll [
		accumulator: reducer accumulator i
	]
	accumulator
]
rebolek
05:31I still have a different error.
>> probe a :reduce*
*** Script Error: ?function? is missing its id argument
*** Where: =
*** Stack: probe a


I probablt need more tea before investigating it :D
theSherwood
05:32:thumbsup:
toomasv
06:43@theSherwood In a: mapping function [id][id] you give as argument to mapping not a construction of the function but a constructed function. This function is assigned to t. When you call a, t is not assigned but called already.
>> length? probe body-of :a
[
    t: func [id][id]
]
== 2

To get what you intend, construct the function in mapping, and for that give it unevaluated construction:
mapping: function [transform][
    function [reduce*] compose [
        t: (:transform)
    ]
]
a: mapping [function [id][id]] ;<-- construction only
a :reduce
;== func [id][id]

Now func is constructed in a, not evaluated
>> length? probe body-of :a
[
    t: function [id] [id]
]
== 4
theSherwood
06:52@toomasv Ah. Okay. Interesting. Is there a way to do this in which one could pass in a constructed function to mapping? That would seem like a more natural interface.
06:53I tried using source but ended up with the same results.
toomasv
07:14@theSherwood After playing a bit with it I got this:
mapping: function [transform][
	function [reduce*] compose/only [
        t: function (spec-of :transform) (body-of :transform)
    ]
]

a: mapping function [id][id]
a :reduce*
;== func [id][id]
07:16In other words, you have to deconstruct function again.
theSherwood
07:17Oh, of course! Thanks, @toomasv! That's a huge help
toomasv
07:18:+1:
melcepstrum
22:53Hi,
I wrote a piece of code that works interpreted but not when it's compiled. I was here few months ago and ran into similar problem, someone told me then to stay away from object-oriented programming. I gave up then and now it's my second attempt to red :)
Can someone have a look at my [code](https://gist.github.com/melcepstrum/ba9b8c92bec3d61d7e27dfd6dcfc455c) and give me advice how to rewrite this the red-way to make it work when compiled? and will this kind of code compile correctly in future versions of red?

toomasv
06:44@melcepstrum The easiest way seems to be wrapping dynamic function calling into do block:
redraw: func [fig] [
	repeat i 4 [
		do [eq/:i/setPeakEQ params/:i/omega params/:i/gain 1.0]
		do [eq/:i/magnitude omega mag/:i]
	]
	plot fig mag/1 + mag/2 + mag/3 + mag/4
]

Tried on W10 with red -c eq.red
melcepstrum
08:32@toomasv thanks!
toomasv
08:33You are welcome!

bubnenkoff
15:11
data: [
	lot: [
		number: none
		object: [
			name: none
		]
	]
]


I next rule for generation:
ar: [lot obj obj lot obj]

first lot should have two obj second lot should have one obj. In result I want to get:

data: [
	lot: [
		number: none
		obj: [
			name: none
		]
		obj: [
			name: none
		]		
	]
	lot: [
		number: none
		obj: [
			name: none
		]	
	]	
]


Is there any way to do it without hardcoding names? Am I right understand that I should use this data-struct as prototype and copy result to another? Can parse save my time?
toomasv
15:26What do you mean by "hardcoding names"? And why do you have in one structure object: and in other obj:? Should object be replaced by obj? If yes, then how should application know this, if you don't want hardcoded names?
bubnenkoff
15:40I renamed all to same names. It was my issue when i did this example to show problem
toomasv
16:18I keep coming back to my earlier func, adapted of course:
data: [
    lot: [
        number: none
        obj: [
            name: none
        ]
    ]
]
walk-data: func [list /local out found] [
    out: make block! 30
    main: first list
    rest: copy data/:main 
    foreach tag list [
        either tag = main [
            out: skip insert tail out copy/deep data -2
            forall rest [rest/2: 0 rest: next rest]
        ][
            if 1 < rest/:tag: rest/:tag + 1 [
                append out/:main to-set-word tag 
                append/only out/:main case [
                    series? data/:main/:tag [copy data/:main/:tag]
                    true [data/:main/:tag]
                ]
                new-line skip tail out/:main -2 true
            ]
        ]
    ]
    head out
]
ar: [lot obj obj lot obj]
probe walk-data ar

I assume first word in ar is top-level, rest are inside block. There are no hardcoded words in walk-data
16:29Errata: walk-data: function [list][...
GiuseppeChillemi
16:55Which is the problem here?

https://gist.github.com/GiuseppeChillemi/b9a23523450090a094ca306adf951aa4#file-test-list-test1-red

If I select an item in the list and click EDIT and modify it, the text list in not updated but the original list is.
16:56There is also a version 2 which does not work too.
bubnenkoff
17:14@toomasv thanks! I am reading code...
toomasv
17:16@bubnenkoff You are welcome!
@GiuseppeChillemi Add links-list/data/(links-list/selected): before main-list/(links-list/selected) in edit-button action.
17:25For some reason links-list/data does not refresh itself when main-list changes. Alternatively to the above enforced renewal you can enforce the refreshing by adding links-list/data: links-list/data to the end of edit-button action.
bubnenkoff
17:29@toomasv pretty hard to understand this magic, but I will try. What is head out do? Same question with main: first list
rebolek
17:30@bubnenkoff see help: Returns a series at its first index.
17:30it makes sure that you get whole out if the index is else than at beginning.
17:31
>> block: [1 2 3 4 5]
== [1 2 3 4 5]
>> block: skip block 2
== [3 4 5]
>> block
== [3 4 5]
>> head block
== [1 2 3 4 5]
bubnenkoff
17:32oh I remember it, it's not fully clear the idea of how it's all works...
rebolek
17:40every series keeps its index. You can get index value with index? function:
>> index? block
== 3
bubnenkoff
17:40out: skip insert tail out copy/deep data -2
it insert copy of data in second level?
17:42@rebolek yes, I was asked a little bit stupid question, because I pretty familar with series, the problem that all code is look as magic for me
rebolek
17:43let's break it down:
out: skip (insert (tail out) (copy/deep data)) -2

You are inserting at out's tail (not sure, why isn't there append out that does the same) deep copy of data. Then you skip 2 values back. that's the minus.
toomasv
17:43It inserts copy of data into tail of out and hops 2 elements back from out tail, so as to be able to reference latest lot.
17:44Ah, sorry, @rebolek is already on it :smile:
GiuseppeChillemi
17:44@toomasv So it is not my mistake, it is for "some reason", my method is correct.
I was trying to understand if main-list is the same data of links-list/data, in other words if they are the same block.
17:45Also, are the displayed strings the same data or copied?
toomasv
17:45Yeah, may be bug, dunno.
>> same? links-list/data main-list
== true
GiuseppeChillemi
17:47I have a second version of the script which has only 1 text-area and 2 buttons, no panels at all. There the same method works. So it could be a bug.
17:53Here it works:

list-data: [
	"hello"
	"my"
	"beautiful"
	"world!"
]


view [
	 data-list: text-list data list-data 

	 btn-edit: button "edit" 80x20 [
			
			if all [data-list/selected data-list/selected > 0] [
	 			view ask-input-panel: [
					ipt-fld: field 150x20 [list-data/(data-list/selected): face/text unview ask-input-panel] with [text: list-data/(data-list/selected)] 

	 			]   
			]
	 ]		
]
17:54I will signal it in Red/Bugs
18:48How RTF TEXT can be compared against a normal text string for its text content without considering any text style in the RTF?
bubnenkoff
18:52@toomasv why you are specified pre-allocated size as 30?
out: make block! 30Who not 10 оr 50? Is there any logic?
toomasv
19:15Nope. Just a guess. I don't know the size of your data (or out-block rather) :)
19:21@GiuseppeChillemi Do you mean the real-real RTF or Red's rich-text?
stmungo
19:33Is it possible to obtain the current matrix transformation of the Draw dialect, please?
toomasv
19:40@stmungo Do you mean examples?
Try this: do https://tinyurl.com/y3lgh2vm
See it [here](https://gist.github.com/toomasv/e77df7ac18beee352f343b0729fb0a7a)
GiuseppeChillemi
20:08@toomasv Red rich-text
stmungo
23:40@toomasv I apologise for the delay in resonding: we had a fire alarm (false). Thank you for the suggested example of Draw dialect use which answered several other questions I had about Draw commands work. The reason I asked about accessing the current transformation matrix (ctm) was that I wanted to see how the draw commands, such as rotate, scale, translate, skew and transform affected it, if at all, to see if the commands were just convenient ways of composing transformation matrices. I now realise that accessing the ctm is impossible, as the draw property is a sequence of constant draw dialect codes which, once composed, does not allow Red function calls.

toomasv
04:55@GiuseppeChillemi As there are several ways to compose rich-text, so there are several ways to access its text too.
1) Simplest

>> rtx: rtd-layout [<b> "Rich text" </b>]()
>> rtx/text = "Rich text"
== true


2) Same in view

>> view [rtx: rich-text data [<b> "Rich text" </b>]] ;...
>> rtx/text = "Rich text"
== true


Or

view [
    below 
    rtx: rich-text "Rich text" with [data: [1x9 bold]] 
    return 
    fld: field "Rich text" 
    button "Compare" [txt/text: form rtx/text = fld/text] 
    txt: text ""
]


3) Multi-box

>> view compose/deep [rt: rich-text draw [text 10x10 (rtx)]] ;...
>> rt/draw/3/text = "Rich text"
== true

04:58
rtd-layout and single-box rich-text create faces with plain text in their text facet. Multi-box rich-text contains this face in appropriate position in itsdraw facet.>
06:15@stmungo I'm not sure I quite understand what you are saying :flushed: Anyway, here are some thoughts on it:
1) Different transformations are applied in order of their position in draw block
2) You can change the draw-block at any time adding, changing or deleting transformations - changes are reflected in view either immediately or when show command is used, depending on value of system/view/auto-sync?.

E.g. in following horizontal slider changes value of translate, vertical slider changes y-value of matrix:

view [
    below pad 10x10 
    base 101x101 draw [
        tr: translate 0x0 
        mx: matrix [1 0 0 1 0 0] 
        circle 0x0 10
    ] 
    pad -10x0 
    slider 120x20 [tr/2/x: to-integer 100 * face/data] 
    return 
    pad -8x0
    slider 20x120 data 1.0 [mx/2/6: 1 - face/data * 100]
]
07:25@rebolek :point_up: [September 3, 2020 8:43 PM](https://gitter.im/red/help?at=5f512b24a5788a3c29d05e41)

> not sure, why isn't there append out

Yes, it might have been append too. As I needed to skip -2 from tail, either tail append out or insert tail out had to be used.
bubnenkoff
11:23@toomasv I studied your code. It's pretty hard for me to reproduce or to modificate it. Sorry that I sometimes showing a little bit structure of data. I am doing some researching in attempt to understand how it would be easier for me to solve problem. Today I got new idea about how to form needed data structure. I decided split every nested element as separate component and try to reduce it.

The next PoC is showing that I want to do.
wanted data structure:
data: [
	lots: [
		lot: [
				number: none
				objs: [
					obj: [
						name: none
					]
					obj: [
						name: none
					]					
				]
			]
	]
]


code for it's generation:
lot: [ number: none objs: [	] ]
obj: [name: none code: none]

data2: []

foreach w [lots lot obj obj] [
	if w = 'lots [append data2 [lots: []] ]
	if w = 'lot [append data2/lots reduce [ lot]] ; problem is here
        ; ...
	]
probe data2


the problem is on last line. I can't understand how to add lot in proper format to lots
toomasv
11:33@bubnenkoff Why doesn't your wanted data structure include code: none?
11:40Here is supplemented foreach loop. But you'll be in trouble with this when you intend to run it on repetitive structures, e.g. [lots lot obj obj lot obj] -- your first lot/objs will get the last obj too. Or e.g. should you add another lots, first one will get all the rest lots and objs. That's why I used skip earlier.
Here is the loop:
foreach w [lots lot obj obj] [
	switch w [
		lots [append data2 copy/deep [lots: []] ]
		lot  [append data2/lots reduce [quote lot: copy/deep lot]]
		obj  [append data2/lots/lot/objs reduce [quote obj: copy obj]]
	]
]
bubnenkoff
11:45Big thanks! I will try this approach! Thanks for mention about problems! This code is more readable!
11:47> @bubnenkoff Why doesn't your wanted data structure include code: none?

oh sorry! I missed it! Yes it should include
toomasv
11:50Here is a formatter for resulting data:
parse data2 rule: [any [ahead block! d: (new-line/skip first d true 2) into rule | skip]]
probe data2
bubnenkoff
11:52>But you'll be in trouble with this when you intend to run it on repetitive structures

Could be this fixed in current aprouch ?
11:56Yeah, I faced with problem on repeated structure. All adds to first
toomasv
11:59I think this will fix it:
foreach w [lots lot obj obj lot obj lots lot] [
	switch w [
		lots [data2: skip tail append data2 copy/deep [lots: []] -2]
		lot  [lots*: skip tail append data2/lots reduce [quote lot: copy/deep lot] -2]
		obj  [append lots*/lot/objs reduce [quote obj: copy obj]]
	]
]
data2: head data2
parse data2 rule: [any [ahead block! d: (new-line/skip first d true 2) into rule | skip]]
probe data2
bubnenkoff
12:01really big thanks! What asterisk mean?
toomasv
12:03I used asterisk just to remind me that this is different from lots as in data2, but you can delete it, it doesn't matter.
bubnenkoff
12:07-2 is because word is word and it's value (block in current case)?
toomasv
12:15Hmm.. first level of data2 was not wrapped. You can use new-line/skip data2: head data2 true 2 instead of data2: head data2 to wrap it.
nedzadarek
12:38Can I set some kind of background to a face's text : view [b: base 52.52.52 draw [box 0x0 100x100] "foo"]. b/text is not *very* visible. I want to make it more visible, like this: view [base 52.52.52 draw [box 0x0 100x100 fill-pen yellow box 30x30 50x50 text 30x30 "foo"]] but without doing it programmatically (calculating bounding box etc). I want something like face/text-background: true.
toomasv
12:55@nedzadarek How about this:
view [p: panel 80x80 52.52.52 [b: box 30x20 yellow "foo"] do [center-face b]]
13:09Or, why not change the color of text view [b: base 52.52.52 yellow "foo"]
nedzadarek
13:21@toomasv I'm doing something like this:
view [
    base draw [
                fill-pen red
                box 0x0 50x100    
    ]"50%"
 ]

and depending on data (50%) I'm changing b/draw/5/x(progress bar). User can change color (fill-pen red), so while I guess I could change text's color (probably using fonts) I thought backgrounds looked better and where less problem-friendly.
toomasv
13:24Remember that draw is drawn over face's text, so that your text will not be seen.

toomasv
05:50@nedzadarek I played with panel-approach, using slider to simulate progress:
view [
    below 
    p: panel 81x81 52.52.52 draw [
        fill-pen red box 0x0 0x80
    ] [b: box 30x20 yellow "0%"] 
    slider [
        p/draw/5/x: to-integer 80 * face/data 
        b/text: form round face/data
    ] 
    do [center-face b]
]
06:02Alternatively for text b: box 30x20 glass yellow bold "0%"
GiuseppeChillemi
19:33I would like to use Cheyenne web server but probably I will need help. Could I make questions about it here?

endo64
06:51@GiuseppeChillemi chit chat may be better fit. I'm still using Cheyenne on production, will try to help.
GiuseppeChillemi
08:22@endo64 Thanks, I will ask there.
vazub_gitlab
14:02 A question regarging comment function. The guidlines say the it is used for multiline comments in form of: comment {}. But the function source says it accepts any 'value, which technically means that you can use: comment (), comment [], comment "", or even comment 1 2 (1 gets ignored). This suggests it may have some other practical uses aside of pure multiline commenting, right?

I am currently working on Red syntax highlighting for micro editor and face some regex parsing challenge, trying to honor all use cases. So my question is - should I trust the guidelines, and colorize multiline comments only for one form - comment {} (would make life simpler), or all possible forms?
rebolek
14:06@vazub_gitlab IMO all possible forms, I guess that putting code in comment [ ... ] may be usual practice.
OTOH due to the way how Red works, putting code in a block is enough to make it being ignored and you don't need comment anyway. Trying to determine if such a block is a comment is beyond the abilities of syntax highlighters.
vazub
14:16That is what I feared :(
rebolek
14:32Then just go with comment {}. It's better than nothing and can be extended.
vazub
14:38Funny observation, the Wikipedia article on comment styles comparison across languages says that Res uses {...} for block comments (no mention of the comment function) https://en.m.wikipedia.org/wiki/Comparison_of_programming_languages_(syntax)#Comment_comparison
endo64
16:40I think syntax highlighter should not highlight the value after the comment as a comment. because comment is a regular Red function and that takes one regular Red value, and does nothing eith that value (but the function still evaluated). So syntax highlighter should treat the value as a value (block, integer, string, etc.)
vazub_gitlab
17:24Current official highlighter in VSCode colorizes both comment [] and comment {} together as an actual "comment", but in every other case, comment remains colored as a function
17:25The documentation seems to be a bit inconsistent in this regard, hence my confusion

nedzadarek
15:18> Remember that draw is drawn over face's text, so that your text will not be seen.

Oh, that's why I don't see it. To be honest face's text should be drawn after draw code. Never mind, thank you for reminding me this.

> @nedzadarek I played with panel-approach, using slider to simulate progress:
>
> view [
>     below 
>     p: panel 81x81 52.52.52 draw [
>         fill-pen red box 0x0 0x80
>     ] [b: box 30x20 yellow "0%"] 
>     slider [
>         p/draw/5/x: to-integer 80 * face/data 
>         b/text: form round face/data
>     ] 
>     do [center-face b]
> ]
>


Interesting, I think I will use panel approach as it is the easiest way to display text over draw code.
Thank you once again.
rebolek
15:20> face's text should be drawn after draw code.

This is debatable. Good points can be found for both ways.
nedzadarek
16:58> > face's text should be drawn after draw code.
>
> This is debatable. Good points can be found for both ways.

@rebolek why you want to draw something over text?

bubnenkoff
08:26Does copy/types not still implemented?

Am I right understand that next code should copy from x to y only string!:
x: ["Hello" foo]
y: copy/types x string!
probe y ;  y become "Hello"
09:07oh, I found issue https://github.com/red/red/issues/2254
toomasv
10:14@bubnenkoff Temporary substitute:
context [
    copyable!: make typeset! [series! map! any-object!] 
    copyable?: func [e][find copyable! type? e] 
    is-type?: func [element [any-type!] type [datatype! typeset!]][case [
        typeset? type [find type type? element] 
        datatype? type [type = type? element]
    ]] 
    set 'copy-types function [block [block! paren! hash!] types [datatype! typeset! block!]][
        if block? types [types: make typeset! types] 
        collect [foreach e block [if is-type? e types [
            either copyable? :e [keep/only copy/deep e][cause-error 'user 'message rejoin [e " cannot be copied!"]]
        ]]]
   ]
]

>> a: copy-types b: ["string" [block [and another]] %file 1 2 <tag>] string!
== ["string"]
>> a: copy-types b: ["string" [block [and another]] %file 1 2 <tag>] any-string!
== ["string" %file <tag>]
>> a: copy-types b: ["string" [block [and another]] %file 1 2 <tag>] [block! string!]
== ["string" [block [and another]]]
>> a: copy-types b: ["string" [block [and another]] %file 1 2 <tag>] integer!
*** User Error: 1 cannot be copied!
bubnenkoff
10:30Thanks! @toomasv I have new question about your example.
*data: [
	lots: [
		lot: [
				number: none
				objs: [
					obj: [
						name: none
					]					
				]
			]
	]
]

;lot: [ number: none objs: [] ]
;obj: [name: none code: none]

copy-words: function[from] [
	list-of-words: copy [] 
	foreach [k v] from [
		either block? v [ 
				append list-of-words compose [(k) [] ]
			] [
				append list-of-words compose [(k) none ]
			]
		]
	return list-of-words
]

data: []

foreach w [lots lot obj obj lot obj] [
    switch w [
        lots [data: skip tail append data copy/deep [lots: []] -2]
        lot  [lots: skip tail append data/lots reduce [quote lot: copy-words *data/lots/lot] -2]
        obj  [append lots/lot/objs reduce [quote obj: copy *data/lots/lot/objs/obj]]
    ]
]
data: head data
parse data rule: [any [ahead block! d: (new-line/skip first d true 2) into rule | skip]]
probe data


I decided to try use *data insetead of commented fragment. Because I want to see complete data structure
I got problem that on every step I am getting extra obj so
I created function copy-words that do shallow copy. But now I am getting 3 obj in every objs. And I can't understand reason

10:47it seems that problem with: copy-words that placed instead of copy/deep
11:20
lot: [ number: none objs: [] ]
obj: [name: none code: none]

copy-words: function[from] [
	unset 'list-of-words
	list-of-words: copy [] 
	foreach [k v] from [
		either block? v [ 
				append list-of-words compose [(k) [] ]
			] [
				append list-of-words compose [(k) none ]
			]
		]
	return copy list-of-words
]

data: []

*data: [
	lots: [
		lot: [
				number: none
				objs: [
					obj: [
						name: none
					]					
				]
			]
	]
]

foreach w [lots lot obj obj lot obj] [
    switch w [
        lots [data: skip tail append data copy/deep [lots: []] -2]
        ; lot  [lots: skip tail append data/lots reduce [quote lot: copy/deep lot] -2]
        lot  [lots: skip tail append data/lots reduce [quote lot:  copy-words lot] -2]
        obj  [append lots/lot/objs reduce [quote obj: copy obj]]
    ]
]
data: head data
parse data rule: [any [ahead block! d: (new-line/skip first d true 2) into rule | skip]]
probe data


What is difference here between copy/deep and copy/deep?
toomasv
11:28@bubnenkoff You should use copy []:
either block? v [ 
                append list-of-words reduce [k copy []]  ;<-- here

Otherwise this block will be shared by all objs:. All three obj are appended to the same block.
11:31> What is difference here between copy/deep and copy/deep?

What do you mean :question:
bubnenkoff
11:49Oh! I feel that there is some issue with copy but did not understand exact place of problem so I tried even copy/deep. Thanks!
toomasv
12:07@bubnenkoff The probem was, that although compose (and reduce) make copies of their argument-block, series inside this block are not copied automatically. So, if you need inner series to be copied too, then you need to either insert copy inside block or copy/deep the whole block in addition to composing/reducing.
>> x: "abc" a: reduce b: compose [(x) []]
== ["abc" []]
>> append b 1
== ["abc" [] 1]
>> a
== ["abc" []]      ;a is copied (by `reduce`) from b, so appending of `1` to `b`does not affect it
>> append b/2 2
== [2]
>> a
== ["abc" [2]]     ;but series inside `b` is shared with `a`, so `2` appended to block in `b` appears in `a` too
>> append a/1 #"d"
== "abcd"
>> b/1
== "abcd"          ; and *vice versa*, string changed in `a` is the same that is in `b`
loziniak
18:39> Current official highlighter in VSCode colorizes both comment [] and comment {} together as an actual "comment", but in every other case, comment remains colored as a function

I'd like the most if every use of comment with subsequent value was colored as a comment. Function's name is more than enough to deduce programmer's intention :-)
18:40@vazub ↑
vazub_gitlab
18:49Yeah, there are some peculiar challenges with regexp parser in micro-editor, so no guarantees it will work for every case, but I'll have a look what can be done.

bubnenkoff
10:09I need to load block data as block to be able to edit it from GUI and save back. How I can display it content as is?
a: ["aa" "bb" "cc"]
view [field a]

to string! is not suitable for it
toomasv
10:18@bubnenkoff Do you mean something like
view [field with [text: mold a]]
bubnenkoff
10:18yeah!
toomasv
10:20To see contents only, without brackets, use mold/only.
bubnenkoff
10:41Thanks!
And how to save back modificated map? For example I have test.red file with follow content:
Red []
foo: make map! [
    a ["Hello"]
]
; ...

I want to modificate some data to a: append foo/a/1 " World"
But how to write result back and do not overwrite all file?
toomasv
11:40There are several ways to change a. You can do it directly/implicitly:

>> a: ["Hello"] view [f: field with [text: a/1] button "World" [append f/text " World!" probe a]]
["Hello World!"]


Or indirectly/explicitly:

>> a: ["aa" "bb" "cc"] view [f: field with [text: mold/only a] button "Add b" [insert find f/text "bb" "b" probe a: f/data]]
["aa" "bbb" "cc"]


As about changing some part of file only without touching the rest of it - you can do it with write/seek if you have the index. E.g.:

save/header %foo [foo: make map! [a ["Hello"]]] []
i: index? find read %foo "Hello"
write/seek %foo "B" i - 1
read %foo
;== {Red [^/]^/^/foo: make map! [a ["Bello"]]}


But I'm pretty sure you don't want to do it with text length changing in the middle of file, as is your case above.
bubnenkoff
14:57Thanks!
I have on-change event on my field that triger function and pass field ID:
save-value: function[i] [
     f: to word! rejoin ['f-tagname- i]
     print f
 ]

this code is print proper field name like:
f-tagname-5
But how to access to it's value? I tried f/text but it does not work. Or maybe I can get access on rejoin?
toomasv
15:34@bubnenkoff Sorry, I don't understand, what value do you want to access. f? It is local to save-value. You can access it inside func only. If you want to have it outside of func you can just return it. And print does not return it. print returns unset. Use probe instead to see it and return.
bubnenkoff
15:38f-tagname-5 is field. I want to get its text
toomasv
15:39Ah, if it has value already, then use get.
bubnenkoff
15:40get to word! rejoin ['f-tagname- i] text ?
toomasv
15:41
>> f-tagname-1: "Value1" ()
>> f-tagname-1: "Value1" save-value: function [i][get to word! rejoin ['f-tagname- i]] ()
>> save-value 1
== "Value1"
15:43And if you want to set it, then use set :)
>> f-tagname-1: "Value1" ()
>> save-value: function [i value][set to word! rejoin ['f-tagname- i] value] ()
>> save-value 1 "Other value" ()
>> f-tagname-1
== "Other value"
bubnenkoff
18:18Let me explain my problem. I am generation UI in next way:
ui-tags-list: collect [repeat i 20 [keep compose [
    (to set-word! rejoin ['f-tagname- i]) field 220x25 hint "Tag Name" extra (i) on-change [save-value face/extra] 
    (to set-word! rejoin ['f-tagstack- i]) field 960x25 hint "Tag Stack" ; wip: ... on-change [save-value face/extra]
    pad 0x-11 
    return] ] ]

And fill in with values from tags-tapes-map:

foreach cell ui-tags-list [
            if set-word? cell [
                row: row + 1 
                fld-name: to-string cell
                if not none? tags-tapes-map/lots/(row) [ ;
                        if find fld-name  "f-tagname" [ 
                            face: get cell
                            face/text: mold tags-tapes-map/lots/(row)/1 ; 
                            
                        ]
                        if find fld-name  "f-tagstack" [ 
                            face: get cell
                            face/text: mold tags-tapes-map/lots/(row)/2 ;
                        ]
                    ]  
                ]
        ]

But then I want to save result of fields if they are was changed. So I need pass values from them back to tags-tapes-map.

I am not sure that I am going in right way. Maybe there is better solution.
19:18it seems that this approach is work:
save-value: func[i] [
    x: reduce to word! rejoin ['f-tagname- i]
    print get in x 'text
; than I hope to set it back to tags-tapes-map
 ]

But I would be very grateful if you could point me in the direction if the is better approach.
toomasv
19:42@bubnenkoff Sorry, I'll look tomorrow.

toomasv
03:41@bubnenkoff Would you post example of tags-tapes-map?
theSherwood
05:39I get errors when is use body-of. Is that expected? spec-of works fine.
05:40Ahh. Nevermind, it's when I use native!s.
bubnenkoff
06:17> @bubnenkoff Would you post example of tags-tapes-map?

sure!
#(
    lots: [
        ["purchaseNumber" ["purchaseNumber"] false] 
        ["docPublishDate" ["docPublishDate"] false] 
        ["responsibleOrg_inn" ["purchaseResponsible" "responsibleOrg" "INN"] false] 
        ; ...

    ]
)
toomasv
06:54@bubnenkoff Here is one possibility:
row: func [i][to-integer i - 1 / 2 + 1]
col: func [i][to-integer i - 1 % 2 + 1]

save-value: func [face][
    print ["Changed value:" face/text]
	print ["Original value:" mold/only tags-tapes-map/lots/(row face/extra)/(col face/extra)]
]

get-text: func [i][
	tags-tapes-map/lots/(row i)/(col i)
]

tags-tapes-map: #(
	lots: [
		["purchaseNumber" ["purchaseNumber"] false] 
		["docPublishDate" ["docPublishDate"] false] 
		["responsibleOrg_inn" ["purchaseResponsible" "responsibleOrg" "INN"] false] 
	 ]
)

ui-tags-list: collect [
	repeat i 3 [
		keep probe compose/deep [
			tagname extra (j: 2 * i - 1) with [text: (mold/only get-text j)]
			tagstack extra (j: 2 * i) with [text: (mold/only get-text j)]
			pad 0x-11 
			return
		]
	]
]
view compose [
	style tagname:  field 220x25 hint "Tag Name"   on-change [save-value face]
	style tagstack: field 960x25 hint "Stack Name" on-change [save-value face]
	(ui-tags-list)
]
bubnenkoff
07:04thanks! Why minus one on this place: j: 2 * i - 1?
toomasv
07:05To enumerate fields, so that extra facet identifies it uniquely.
07:13Hm.. Second print in save-value could use get-text face/extra; and get-text itself could include mold/only.
07:37@bubnenkoff A bit cleaned and improved IMO:
row: func [i][to-integer i - 1 / 2 + 1]
col: func [i][i - 1 % 2 + 1]

save-value: func [face][
	if face/text <> get-text face/extra [
		print ["Changed value:" face/text]
		print ["Original value:" get-text face/extra]
	]
]

get-text: func [i][
	mold/only tags-tapes-map/lots/(row i)/(col i)
]

tags-tapes-map: #(
	lots: [
		["purchaseNumber"     ["purchaseNumber"]                             false] 
		["docPublishDate"     ["docPublishDate"]                             false] 
		["responsibleOrg_inn" ["purchaseResponsible" "responsibleOrg" "INN"] false] 
    ]
)
rows: length? tags-tapes-map/lots
view compose [
	style tag: field on-created [face/text: get-text face/extra] 
					 on-enter   [save-value face] 
					 on-unfocus [save-value face]
	(collect [repeat i rows [keep compose/deep [
		tag 220x25 extra (2 * i - 1) 
		tag 960x25 extra (2 * i) 
		pad 0x-11 return
	]]])
]

07:50Hmm.. /deep not needed anymore in last compose
bubnenkoff
07:54Oh! Big thanks!
theSherwood
08:09So I'm trying to write a transducer library and I've got this foldl implementation that I'm using as the base of it:
foldl: function [
	reducer
	coll
	/init
		initial
][
	either init [accumulator: :initial c: coll][accumulator: coll/1 c: next coll]
	foreach i c [
		accumulator: reducer :accumulator :i
	]
	:accumulator
]


But I'm splashing get-word! types around in order to deal with possible function! parameters. Is there a better way to do this?
08:11I mean, it works. But I haven't noticed Red code written by anyone else that does this. I suspect I may be doing something that isn't idiomatic by passing function! values all over the place.
toomasv
08:41@theSherwood It seems ok to me, although I'm not sure why you use get-words :initial, :accumulator and :i, unless you intend to have list of functions folded. Which is possible but then coll/1 should also be get-path. Another remark is that you might feed in ops as reducers, e.g. :+ or something, for which you'll need different ordering in foreach.
theSherwood
08:46Thanks, @toomasv . Yes, I need to be able to fold a list of functions. Good catch on both coll/1 and ops
toomasv
08:47I am no expert on this but from what I have read paucity of functional-style code is probably connected with waiting for tail-optimisation.
theSherwood
08:48Is that on the roadmap?
toomasv
08:49Yes, but I don't know details.
17:12@theSherwood :point_up: [September 10, 2020 8:39 AM](https://gitter.im/red/help?at=5f59bc09c3aa024ef9d34327) This reminded me of [console tools](https://github.com/toomasv/console-tools) where you can explore native's and action's bodies too ([example](https://toomasv.red/images/Console/define.gif)]).

It is half-baked, so don't expect it work smoothly. Source is expected to reside relative to your %console.red on path ../source/red/.

@rebolek, @hiiamboris and @meijeru have also tools to explore sources, IIRC.

theSherwood
20:41Thanks, @toomasv ! That's a handy tool.
21:00Is there any way to get a block as a syntax tree without actually evaluating it?
GiuseppeChillemi
21:12Something like [load/unbound](http://www.rebol.com/r3/docs/functions/load.html) ?
theSherwood
21:33Hmm. I'm not sure. I'll need to dig into that. Basically, I want a tree I can traverse to see how the code would execute before it does.
21:48This could be useful for debugging or in REPLs or editors and for symbolic programming. It seems like the kind of thing Red could be capable of given how reflective it is. Something between load and do?
ne1uno
22:06http://www.rebol.net/cookbook/recipes/0042.html prettyprint. might need minor changes for new-lexer, it's a starting point?
theSherwood
22:10@ne1uno, thanks! I'll have to experiment with that.
dander
22:28@theSherwood, @toomasv has done some experiments which certainly do some of that over in the [sandbox](https://gitter.im/red/sandbox?at=5ee84922013105125a39d14f) room
theSherwood
22:36@dander That's incredible stuff
GiuseppeChillemi
23:26@theSherwood You have to consider that the syntax three evolves at every step of the code. The one you have at a given moment could be different at the next code step because words have changed their content and bindings in the previous instructions.
theSherwood
23:35Yes, that's certainly tricky. I wouldn't expect the syntax tree representation to be accurate after the code was evaluated. But I think it could be quite useful to be able to grab a traversible snapshot.

toomasv
03:51@theSherwood I did some experiments last year about drawing trees of Red data/code:
:point_up: [April 12, 2019 8:10 PM](https://gitter.im/red/sandbox?at=5cb0c68c1f6e900d5e20cecf)
:point_up: [April 9, 2019 10:32 PM](https://gitter.im/red/sandbox?at=5cacf334b34ccd69e78f9dfd)
Do you mean something like that?
theSherwood
05:34Yeah! Something along those lines. For starters, I'm wanting to be able to identify unset! words in a block and then to be able to selectively evaluate all syntax subtrees which do not contain unset! words. Symbolic programming for systems of equations and the like.
05:37But to do that I need to be able to build a syntax tree, as far as I can tell.
toomasv
10:19@theSherwood Don't know if this is of any help but in spring I made a [toy solver](https://github.com/toomasv/solver) for equations:

do %solve.red
set-values [a: none b: 5 c: 4 d: 3 e: 2 f: 1]()
formula: [a = b + c / (d * e) - f]()
solve/eval formula
;== 0.5
get-values
;== make object! [
;    a: 0.5
;    b: 5
;    c: 4
;    d: 3
;    e: 2
;    f: 1
;]
solve/eval/for formula b
;== 5.0
formula
;== [[b] [a + f * (d * e) - c]]
set-value a 1 set-value f none ()
solve/eval/for formula f ()
get-values
;== make object! [
;    a: 1
;    b: 5.0
;    c: 4
;    d: 3
;    e: 2
;    f: 0.5
;]


Exponentiation works too to some extent (no words as exponents). E.g. Pythagorean solution:

set-values [a: 5 b: none c: 3]()
solve/eval/for f: [a = (b ** 2 + (c ** 2)) ** 0.5] b
;== 4.0
set-values [a: 5 b: 4 c: none]()
solve/eval/for f c
;== 3.0
f
;== [[c] [a ** (1.0 / 0.5) - (b ** 2) ** (1.0 / 2)]]
GiuseppeChillemi
10:37@greggirwin I remember you having created something regarding composing and placeholders replacement but I can't find it. It should be a replace function or a compose like function. Have you a link?
theSherwood
10:47@toomasv That's in the vein of what I was thinking of, yes. I'd like to be able to do that with arbitrary red code thrown into the equations. The interface you have there is very similar to what I was envisioning.
toomasv
11:30So, you want to traverse Red block splitting it into expressions, leave expressions that cannot be evaluated as is, and evaluate the rest? Partial evaluation.
theSherwood
16:21Yes!

greggirwin
04:54@GiuseppeChillemi [composite](https://gist.github.com/greggirwin/d40a0e3b4c8de31a7d3b82695b9b4b03)

bubnenkoff
11:35Is it good practice to use compose? I need to display dict. Next code is work, but is there better way?
m: #(a: 10% b: 15% c: 20%)
view compose [area (to-string m)]

toomasv
12:07I think it depends. If you are going to compose relatively small blocks relatively few times then it is ok; but if you are going to compose blocks in tight loops you may want to reconsider it as it is going to eat your resources (lot of garbage to clean up) and slow your program down because of excessive copying.
greggirwin
18:09Using it with view is low impact, unless you're composing a huge amount of work that might slow the display (it would have to be a *lot* though). My general approach is to do the easy and obvious thing, that makes the code and intent clear. Only if I hit performance issues, or can see ahead of time that you'll get a 10x+ improvement where it counts do I worry about optimizing.
bubnenkoff
18:21Thanks! What is the best way to sort dict by it's value end pick highest value?
m: #()
m/a: 2%
m/b: 4%
m/c: 1%
m/d: 3%
greggirwin
18:25Map!s are unordered. If you need ordering, you a block and sort. Sort has a number of refinements that give you detailed control.
bubnenkoff
18:27Am i right that I should find top with take sort/reverse values-of m and than take key-value by it's result?
greggirwin
18:29Play in the console to get a feel for how each piece works. Some things seems simple, but you may need to consider if values can be duplicated under different keys, etc.

rebolek
06:01@bubnenkoff I have sorted-set pseudotype that is able to do what you want:
>> do %set.red
== func [/local value][
    value: make sorted-set! []
    value/data
]
>> s: make-sorted-set
== []
>> append s [a 5]
== [a 5]
>> append s [b 3]
== [b 3 a 5]
>> append s [c 1]
== [c 1 b 3 a 5]
>> append s [d 3]
== [c 1 b 3 d 3 a 5]
>> highest: copy/part tail s -2
== [a 5]
>> lowest: copy/part s 2
== [c 1]

As you can see, keys are sorted by value, so picking ighest/lowest is very easy. If two or more keys have same value, they are sorted lexicographically.
https://github.com/rebolek/red-tools/blob/master/set.red
bubnenkoff
09:41> @Phryxe May be something like:
>
> >> sort/skip/reverse/compare sort/skip/reverse to-block x 2 2 2
> == ["cc" 9 "dd" 5 "de" 4 "ab" 3 "aa" 3]
> >> sort/skip/reverse/compare sort/skip to-block x 2 2 2
> == ["cc" 9 "dd" 5 "de" 4 "aa" 3 "ab" 3]
>


Thanks Toomas, I have found here your another solution that work fine in my case. I have only few elements in map. It looks like magic, but it's working:
m: #()
m/a: 2%
m/b: 4%
m/c: 1%
m/d: 3%
sort/skip/reverse/compare sort/skip/reverse to-block m 2 2 2

== [
    b: 4% 
    d: 3% 
    a: 2% 
    c: 1%
]


Boleslav, thanks for suggestion!
toomasv
11:54I don't remember why sorting was duplicated:
sort/skip/compare/reverse to-block m 2 2
== [
    b: 4% 
    d: 3% 
    a: 2% 
    c: 1%
]
GalenIvanov
12:26@rebolek I started working on a ePub reader (in fact just started reading docs :) ) and used parts of your zip.red to read the contents of several .epub files. Do you have any idea why Red doesn't know how to decompress certain .jpg file from an .epub container, even though the compression metod is deflate? Here's a temporary link to the epub: https://we.tl/t-p33WBuneDN
The problem is with OEBPS/Images/cover1000.jpg
12:27Red gives the following error:
12:27
*** Script Error: data not in correct format: none
*** Where: decompress
*** Stack: load-zip
rebolek
12:34@GalenIvanov Thanks, I take a look. I guess there may be there may be some limitations in the decompressor, I would have to look at the decompress source to tell exactly what's the problem (I'm not an author).
GalenIvanov
12:35@rebolek Thank you!
rebolek
12:45we may ask @bitbegin who wrote the Red/System function
GalenIvanov
12:53Yes, I just found that he's the author of compress.reds and deflate.reds
rebolek
13:10unzip on Linux doesn't show any errors. I may change the decompressor to ignore ivalid files and skip them, so you can get get at least the rest of archive.
GalenIvanov
13:15@rebolek I'm on Win 10. I don't use your zip.red directly - I stripped it down to the bare minimum I need for reading archieves. I can add try to get rid of the 'faulty` files :)
rebolek
13:42@GalenIvanov yes, a simple try is what I meant :-)
GalenIvanov
13:44:+1:

theSherwood
04:18Is there any way to use set to set values within some context other than the global context?
greggirwin
05:05@theSherwood, you can use in.
>> o: object [a: b: none]
== make object! [
    a: none
    b: none
]
>> set 'a 1
== 1
>> set in o 'b 2
== 2
>> a
== 1
>> b
*** Script Error: b has no value
*** Where: catch
*** Stack:  

>> o
== make object! [
    a: none
    b: 2
]
05:07You can also use a temporary word to refer to the word in the other context.
>> o: object [a: b: c: none]
== make object! [
    a: none
    b: none
    c: none
]
>> oc: in o 'c
== c
>> set oc 'Whaaaat?
== Whaaaat?
>> o
== make object! [
    a: none
    b: none
    c: 'Whaaaat?
]
theSherwood
05:08Thanks, Gregg. That's a big help!
bubnenkoff
09:20How to make append block element on new line?
list: [
	["aaa" "bbb" "ccc"]
	["ddd" "ddd" "fff"]
	
]

append list [["ggg" "hhh" "jjj"]]

== [
    ["aaa" "bbb" "ccc"] 
    ["ddd" "ddd" "fff"] ["ggg" "hhh" "jjj"]
]

rebolek
09:40@bubnenkoff there is a way to do this, but don't forget that what you see is just a representation of the data in memory, so lines make no sense in such context. However, as people view the data and don't want to spent time writing helper function that would pretty-print data, Redbol has concept of a new-line bit, that can be set for each value. So, to make it short, there is a function new-line allowing you to set this bit:
>> a: [1 2 3]
== [1 2 3]
>> new-line/all a true
== [
    1
    2
    3
]


See help for new-line for detailed info.
bubnenkoff
09:46Thanks! that works! Yes I understand that it's just representation, but I need to dump it in human readable view. The follow code is working:
list: [
	["aaa" "bbb" "ccc"]
	["ddd" "ddd" "fff"]	
]

append list [["ggg" "hhh" "jjj"]]
new-line/all list true

write %1.txt list

1.txt:
[
    ["aaa" "bbb" "ccc"] 
    ["ddd" "ddd" "fff"] 
    ["ggg" "hhh" "jjj"]
]
toomasv
09:50helper:
append-nl: func [list appendum /only /skip n][
   n: either n [0 - n][-1] 
   either only [append/only list appendum][append list appendum] 
   new-line (system/words/skip tail list n) true 
   list
]

>> append-nl/only list ["ggg" "hhh" "jjj"]
== [
    ["aaa" "bbb" "ccc"] 
    ["ddd" "ddd" "fff"] 
    ["ggg" "hhh" "jjj"]
]
rebolek
13:45> people (...) don't want to spent time writing helper function

and then there's @toomasv :smile:

bubnenkoff
10:07is there any build-in way to do from [aa bb cc] block of strings: ["aa" "bb" "cc"] ? mold\form not suitable for it
10:41
r: []
foreach el [aa bb cc] [append r to-string el]
probe r

that's work, but it's too long
endo64
10:41We don't have map-each yet. You can write your own function:
form-each: func [b] [collect [forall b [keep form b/1]]]

form-each [a b c]
;== ["a" "b" "c"]
bubnenkoff
10:42thanks
greggirwin
17:04> that's work, but it's too long

A true reducer's mindset. :^)
17:05Here's another way, if you want to change the series in place.
change-all: func [
	"Change each value in the series by applying a function to it"
	series  [series!]
	fn      [any-function!] "Function that takes one arg"
][
	forall series [change/only series fn first series]
	series
]
bubnenkoff
18:49Very interesting solution! Thanks!
18:49What was changed between latest released? I am getting differenet behaviour of two consoles. Fiesr - june build, second latest:
>> change-dir %\F\code\
== %/F/code/


second:
>> change-dir %\F\code\
*** Access Error: cannot open: /C/red/\F\code\
*** Where: do
*** Stack: change-dir cause-error
18:53It's seems new builds require another slash. It's bug or planed future?
greggirwin
19:07Backslashes are not normal Red file syntax. You can work around it with to-red-file if needed.
>> change-dir %/d/temp/
== %/d/temp/
>> change-dir to-red-file %\d\temp\
== %/d/temp/

Oldes
07:08@greggirwin isn't it a bug? In Rebol it is normalized automatically:
>> %\d\temp\
== %/d/temp/
bubnenkoff
09:07is it's enough to call unset to free memory from object? Or is there any way to force GC to run?
rebolek
09:08recycle
bubnenkoff
09:14call it after unset?
endo64
09:21yes. you set your word to none, unset it, or clear a big series, then you can recycle to gain some memory.
09:22But it is not necessary if you don't have too big series, images, objects etc.
bubnenkoff
09:25I am generation very big list of words and than filling it.
It seems that recycle work without unset if the objects do not use more. At last I did test and recycle free memory
10:07Why next code is print aa and bb although there is return between them:
>> f: func [] [
[    print "aa"
[    return
[    print "bb"
[    ]
== func [][
    print "aa" 
    return 
    print "bb"
]
>> f
aa
bb
rebolek
10:08because return takes value
10:08so it also evaluates print "bb"
10:09you are looking after exit if you don't want to return value
bubnenkoff
11:52I read docs but still not fully understand if is:
foreach xml list-of-files [
		auto-processing
		do-events/no-wait
	]

to prevent GUI freeze. I tried to add /no-wait to main view/no-wait [...] but it did not help.
12:15I need to display result between processing steps in text-area, with do-events/no-wait I see that it's trying to display sometimes result but most of time I am see only gray background instead of area
greggirwin
15:21@oldes, it's by design. I support the idea of making Red file syntax match path syntax, being explicit when you need to work with local file names. For interactive shell functions, it's a harder call. Being able to copy file names and paste them for use with change-dir, etc. is very nice.

In this case, it's normalize-dir that has a specific check for a forward slash which causes the extra path issue. But even if we change that, supporting backslashes means making changes everywhere to allow them, including telling users they need to check for them in their own funcs.
theSherwood
16:35@theSherwood
Could someone help me understand the convention of using "?" at the end of some words? Almost all of the functions that have "?" return a logic! type, such as zero?, odd?, dir?, etc.. But there are exceptions to this, such as type?, size?, length?. Is there an overarching logic that ties these different uses together?

I just automatically think a word ending in "?" must be a predicate, but that's not the case here. So I'm trying to have a concept for what "?" is indicating.
toomasv
17:03@theSherwood I tend to consider ?-words as querying info about some aspect of entities, i.e. they return information about, not any contents of the entity under question. Not sure if this appplies thoroughly though, most probably not. In the end this is just convention which sinks in with practice IMO.
theSherwood
17:11@toomasv I see. Is the convention to imitate this in user code? I use "?" for predicates but am unsure of which other, less easily defined cases merit a "?".
toomasv
17:14I do use sometimes "?" when it feels natural, but not systematically. I hope I'll pick up more systematic way of using it, so that it would help to clarify the intent.
theSherwood
17:23Yes, I think that's my concern. If it takes a lot of experience for the intent of "?" to become clear, then it might not actually be a very good signal.
greggirwin
21:16It's a soft convention. Think of it more in terms of what reads naturally, as in non-synthetic languages. As programmers we sometimes want things defined in black and white, e.g., strict typing and statically analyzable code. But that's not how humans work. Synthetic languages, Lojban being a great example, are unambiguous, which makes it hard to tell jokes or write poetry. I will argue that the same thing applies to code and data; anything we use to communicate.

You can be strict in very specific cases, and it works comfortably. But as you write more general code, or very general functions that are meant to be used in combination with others, in sentences, a certain amount of "softness" can yield big benefits. This comes back to the importance of context. We live and die by it.
21:17Dialects are the ultimate example of this view applied.

GalenIvanov
09:25All these words -zero?, odd?, dir?, type?, size?, length? etc. - represent nouns, although functions are (something like) verbs - that's why there's a ? at the end, adding a meaning of query.
theSherwood
09:53Seems like there are lots of query-like words that don't get a "?" though.
dsunanda
11:27@theSherwood There is an attempted newer convention to use "-of" as a name suffix to mean "get me the value(s) of" - eg SPEC-OF and WORDS-OF.
If this had been in place when Rebol was first designed (in the 1990s) we would have LENGTH-OF instead of LENGTH?, etc.
That would have avoided some of the head-scratching the the current "soft convention" can cause.
greggirwin
15:45https://github.com/red/red/issues/255 Most of the chat is very old, and there is probably a curecode ticket for it as well. It's a tale as old as time.
theSherwood
18:27Thanks @dsunanda @greggirwin that's a lot of good context. This is an issue with a lot of history to it.

bubnenkoff
14:18what is the best practice of using func? All set words inside it is public, but it can be cause of name conflicts. It's usage should bu minimized?
15:38> I read docs but still not fully understand if is:
>
> 	foreach xml list-of-files [
> 		auto-processing
> 		do-events/no-wait
> 	]
>

> to prevent GUI freeze. I tried to add /no-wait to main view/no-wait [...] but it did not help.

I have solved this problem with adding few do-events/no-wait in code to get it look:

foreach xml list-of-files [
	do-events/no-wait
	file-name/text: xml
	do-events/no-wait
	auto-processing ; cpu bound operation
	do-events/no-wait
]


If only one do-events/no-wait I am seeing gray zone instead of area with result.
toomasv
15:38If most set-words in your function are local, use function(possibly with /extern ), otherwise use /local with func.

bubnenkoff
10:23What is the right way to stop (not break) foreach loop?
rebolek
10:31go thru all items
10:31what is the difference between breaking and stopping?
bubnenkoff
10:40I need to display value at field and wait for user press button. So I process should continue. But setting value to field will not cause stop of foreach loop
rebolek
10:43GUI is async, this is not how you should do it.
bubnenkoff
10:55And how I should do it?
10:56My case: I doing iteration of tags and need to display unknown tag if field and wait for user action. Then continue
rebolek
14:10@bubnekoff Write a function that will display one item. Have a list of items. When user clicks button (in button's action) do something like:
list: next list
unless tail? list [show-item first list]
14:13So there is no foreach and the list advances only on user's interaction

XANOZOID
06:51How can I query Red for functions that are used on a specific data-type? I want to list out hash! related functions
rebolek
06:54@XANOZOID Try for example ? "hash!"
XANOZOID
07:03Thanks rebolek! I found union . . looks like one way to extend a hash (creating a new one)!
rebolek
07:04I'm not sure what you're after, you can extend hash! by simple append or insert.
XANOZOID
07:19That's definitely what I was looking for . . . Thanks rebolek 😄. I'm going to continue reading docs and such for now
bubnenkoff
08:31it's seems that I have found bug and create minimal reproducible example. Should I create issue or it's already well-known?
The next code is crush after ~ 15 clicks to button:
f: func[] [
	loop 500 [append t/data "aaa"]
]

view [
	t: text-list 200x400 data []
	button [f]
]
08:35if make "aaa" not 3 letters but 100 it's crush after less than 10 clicks
endo64
10:22Better to discuss on /bugs room. it looks like a bug, but before filing a ticket search for similar issues on GitHub, try words like crash, text-list etc.
bubnenkoff
11:22Could anybody mention me how to remove element at position. For example drop second element: [1 2 3 4] to get: [1 3 4]
I tried: remove at [1 2 3 4] 2 and other
toomasv
11:23Use head. :)
bubnenkoff
11:27mix at and head?
toomasv
11:32head remove at [1 2 3 4] 2
bubnenkoff
11:33oh...! huge thanks!
toomasv
11:35You are welcome. remove returns series at removed index, so you have to move to the head of series.
XANOZOID
14:27hi! What options do we have in Red for debugging code - stepping through it and pausing execution?
14:27Also what is the standard way to profile programs in Red?
14:27Thanks!
cloutiy
14:33@XANOZOID You could just create a function to pause execution:
show: func ['items] [
    ?? :items
]

breakpoint: func [msg] [
    print ["breakpoint:" msg]
    until [
        print do cmd: ask "debug> " 
        cmd = ""
    ]
    exit
]

Then just call breakpoint where you want to "pause" execution. Execution is "paused", but you can still type in any red code while paused. This allows me to probe the value of variables or even change values while execution is paused. To continue with the execution, just do enter. I have a show helper function that I also use to probe variables while execution is paused. But Im just a beginner. I'm sure the veterans have more advanced tooling they've created.
XANOZOID
14:48That looks nice! Already potentially capable of making some form of rudimentary extension in VSCode or other too I think! Thanks for your example :)
endo64
20:04probe is your best friend during development and quick debugging.
For profiling, not for the whole program but you can profile and compare two blocks of codes using @greggirwin 's profile function: https://gist.github.com/greggirwin/908d44dc069ed84cf69f053e1308390d

Here is how you use it:
>> profile/show [[3 * 5] [multiply 3 5]]
Time                 | Memory      | Code
1.0x (107ns)         | 452         | [3 * 5]
2.14x (228ns)        | 404         | [multiply 3 5]

XANOZOID
08:27Thanks Semseddin!! That's super sweet looking!
bubnenkoff
09:41Can be compose used not for all view but only in particular place? I need to display value in text but do not want to make all view compose (because I am not sure that I need it, or it's OK?)
xml-count: 0
view compose [text (to-string xml-count)]
rebolek
09:42compose accepts block, so it works on that block
bubnenkoff
09:43
>> view [text compose [(to-string xml-count) ]]
*** Script Error: VID - invalid syntax at: compose to-string xml-count

rebolek
09:43That's wrong, obviously, as compose is not part of VID dialect
09:43Why don't you use something like this:
09:44
view/no-wait [t: text 100]
t/text: form xml-count


09:44and then do-events
bubnenkoff
09:45do-events is doing step inside event loop?
rebolek
endo64
10:02@bubnenkoff compose [text (to-string xml-count) button (form my-count) ... ] is perfectly OK and fast enough, no need to optimize by sacrificing readability.

XANOZOID
14:33So I'm definitely aware of Red's/Rebol's parsing and its ability to make writing dialects much more streamlined . . . However, I haven't read much on the common approaches "reducers" take to extend the functionality of some dialects, or reuse the grammars. The best example of this sort of thing I'm aware of is more of a "compounding" of dialects that work over each other - but nothing that's like "add a word/segment/phrase/group" to an existing dialect or update parts of a grammar and so forth. This sort of thing is technically a feature of Raku - and they have an entire syntax dedicated to defining grammars that are reusable and extensible. I feel like this is directly comparable and translateable between Raku and Red . . . Maybe someone can point me in a direction here?
14:38I also feel like if this isn't already a concept or approach floating around the Red ecosystem, having some sort of grammar-system dialect could definitely be implemented in Red. . . Could even perhaps make some of the "uncertainties" of compiling Red-code that uses the parse library more streamlined and practical to compile as well if integrated into the standard/library somewhere. . .
rebolek
14:44@XANOZOID I would say that Red is certainly lacking in this area. I guess that everyone has their own 3-4 solutions to this problem (at least I do), but nothing standard. It's not that it's hard or impossible, it's fairly easy, but probably the free form of Red may make it bit harder to implement some standard? In the R2 days, there was parseen by Ladislav Mečíř, compile-rules by @giesse and other stuff to improve parsing, I believe some ideas were adapted in R3/Red parse, but there is still lot of stuff that is missing.
I think that currently this isn't very high on the list of things that are going to be implemented, however, if someone is willing to write a proposal and maybe some example code, it would certainly be appreciated and could be incorporated to Red.
14:47Just some ideas:
* add/modify/remove a rule
* rules with local variables
* rules that can take arguments
* ... (many many others)
XANOZOID
15:38Thanks for the quick reply, rebolek! I like the idea - I'd definitely be interested in helping further this since I think it could progress some initiatives. I'm a novice though, not a single real Red/Rebol scriptlet/app under my belt yet.
15:38On the other side of things - is creating compounding dialects the way to go for extending things then? Otherwise I'm not sure what resources are available in this regard
rebolek
17:26> is creating compounding dialects the way to go for extending things

I believe so, some current features weren't available but people implemented them using then available parse commands. Once it was proven it's worth adding it, it was implemented natively.
greggirwin
18:00We've talked internally about wanting to build higher level parsing features, including an IDE. A dialect designer would be great, and we can take inspiration from Raku, ANTLR, and others.

XANOZOID
22:03That's great to hear! Thank you for that bit of information Gregg :)
22:04I was following Monkey2 development for a while, Mark Sibly of the Blitz line was making it for a while, and towards the unfortunate end of its development the last article mentioned re-writing the parsing and related part of it in ANTLR. Don't know why, but completely forgot about that one haha

XANOZOID
17:25Hi everyone - what's the best way to implement a red script that loads a file relative to the script and not the active/current directory?
17:26For me I can only think of one hacky way, or I'd be forced to save the absolute path
17:26The hacky way being to sort of pass that in with an execution script or something
cloutiy
17:54@XANOZOID Perhaps you could post your attempt here and others can provide helpful pointers.
greggirwin
17:54Use system/options/path.
17:57Yes, @cloutiy, that helps. Because (I think) we don't have system/script/path in place yet, and how things are executed makes a difference. Red has the same issues as Rebol here, where flexibility can make some things trickier. We need a good reference and best-practice doc on this.
XANOZOID
18:05Thanks both
18:06@greggirwin I did a quick probe on system/options and unfortunately none of the fields held the information of the actual script . . . I have it ran through a bash-script that runs red. I've put it in my path variables on Windows 10.
18:07@yc It's really just
do %scripts/my-script.red

@"%~dp0exe/red-app.exe" --cli scripts.red
18:07First is Red, second is my bat file
18:09What I meant by "held the information of the actual script" - I meant boot was in ProgramData, cache was in AppData/Roaming, and path was the active directory. So none held the script directory which was coming from a subfolder in documents. .
18:11If anything I figured perhaps I could pass in the path through a command line argument but I was running into problems trying to do something like
red arg1 --arg2 # etc...
red "file" arg1...
red "file" "arg1 arg2"

None seemed to lead to any successful solution
greggirwin
18:14Did you use do/args?
9214
18:16> I did a quick probe on system/options and unfortunately none of the fields held the information of the actual script

Did you probe it from within the script itself?

Red [File: %test.red]

print what-dir
print system/options/path

Placed in the home directory, called from the sub-folder:
>> do %../test.red
/home/isheh/
/home/isheh/
XANOZOID
18:28Sorry guys. You know what? I'm really dumb.
18:28The problem was the bat file call
18:29
bash
@"%~dp0exe/red-app.exe" --cli "%~dp0scripts.red"

I needed to use the dp0 modifier to reference the script too
9214
18:33> ... and The Blind Gun, who zeroes in with bat squeaks.
XANOZOID
18:39@9214 does Red [File: %test.red] have any programmatic meaning or difference vs do %test.red? Right now I've designed my script to conditionally import the code . . . but perhaps I should actually make sure to only do that once instead of multiple times 😅
9214
18:40@XANOZOID no, it's just a metainfo. At least on Windows, some of the header fields are used to fill in the details about the compiled PE binary (see the bottom of [this](https://www.red-lang.org/2016/03/060-red-gui-system.html) blog post for the details).
XANOZOID
18:47Thanks Vladimir :). Still trying to catch up to you pros . . . I've been trying to absorb tons of blog-posts, articles, web-pages and all. Still somehow so much depth to the conversations everywhere!
18:47That's what I thought, but like you said I do see that some parts of the Red[ ... ] are actually utilized by the runtime/compile-time stuff
18:52So one more thing before I get back to some homework here. . . Rebol is a data format as much as it is a programming language (hence 2 in the same here). But Red is in the same family for all that I have to say. But I bring this up to put context behind my question.
So then Red, like Rebol, is a data format as well. So with my first project in Red I've created a configuration file . . . basically "config.red", and then I loaded it. However I was thinking about the semantics and decided against adding "Red []" at the beginning - because it wasn't a "script". It's a little weird to me in that regard. But is this the right approach? I knew I couldn't just do a straightforward do %config.red because of this, so I did do read %config.red. That ended up working nicely. So the question is, am I going about this right, learning common approaches in Red correctly?
9214
18:58@XANOZOID you are on the right track with a data-driven approach. Conceptually, Red works in two phases: loading (i.e. conversion from a serialized data to the aforementioned data format) and interpretation, either with do (a facade for the Red interpreted) or with a dialect, such as Parse or View.

In your example, do is smart enough and loads the string that read returns before interpreting it. You could also write do load %config.red, which amounts to the same thing.
19:03Actually, one could say that there are three phases: the last one is "molding", i.e. conversion from the data format back to a serialized form, typically a string. This is what you see printed out in the Red console prompt.
XANOZOID
19:12Thanks a ton Vlad :). I took a look at the manual for load and played around with it a bit . . . Found out that it "loads" my configuration file as a block and I realized from that point I can reduce it! So would that really be better than just "do(ing)" the config? Everyone here's been so helpful and I really appreciate it :)
19:14I think I've gotten a little comfortable with the loading and interp phases - molding I'm thinking is a matter of conversion? Kind of like something you'd probably want to do more often with Parse?
19:14I'm really enjoying this language though . . . thinking about using it for everything I do even if it's in alpha 😅
9214
19:22> So would that really be better than just "do(ing)" the config?

Ideally, all the information in the script header should be stored automagically in system/script/header, but that's TBD. In the meantime, it might be better to construct a dedicated object from the header block (which, like anything else, is just a passive data), that way all the configuration options are localized and can be applied to specific parts of your script, e.g. with bind.

>> script: [date + 10]
== [date + 10]
>> date: 10-10-10
== 10-Oct-2010
>> config: context second load %../test.red
== make object! [
    File: %test.red
    Date: 28-Sep-2020
    Author: @9214
]

>> do script
== 20-Oct-2010
>> do bind script config
== 8-Oct-2020
>> date
== 10-Oct-2010
19:26Or you can turn it the other way around: your main script can be a stateful object, and config can be an expression used to modify a state.
>> script: object [foo: 0]
== make object! [
    foo: 0
]
>> config: [set 'foo 6 * 7]
== [set 'foo 6 * 7]

>> do bind config script
== 42
>> script
== make object! [
    foo: 42
]
XANOZOID
19:27Oh wow that second part . . . it's making me think for sure
19:28I'm a game developer by heart, been toying with making games and stuff since I was like 10 - this seems like some really good stuff and I plan on taking Red somewhere for game dev for sure :). Data is huge in Game Dev, and being able to make little configuration-based plugin like scripts in such a way is super awesome expressivity
9214
19:33IIRC there is some game engine that uses (or planned to use) Rebol/Red for scripting, but I might be mistaken. @BeardPower can say for sure.
XANOZOID
19:35Ahh that's awesome :). I'm definitely going to be hooking up Raylib when I get the chance. A lot of people look to Raylib and find cool languages for tinkering with games and I think adding Red to their list can add an additional spotlight for this language :)
19:37Also planning on creating bindings for Kinc . . . Less known, but a really fantastic multi-platform library that runs on more targets than I can count on my hands. Pretty sure the developer has targets like the Amiga lol - he loves that os.
9214
19:41Never heard of these libs, sounds cool! I'd suggest to get the grasp of the Red fundamentals first, and only then delve into Red/System and library bindings. R/S by itself is trivial if you know C, the most challenging part is interfacing with the Red runtime.
XANOZOID
19:54Yes I'm familiar with C! I'm familiar with MIPS assembly too haha. I've done lots of stuff :).
19:54I like Red the most out of all the languages I've used xD
19:55And I've used more than 30 languages over the years for a range of things . . . maybe I haven't been using them right, but using Rebol/Red right seems to be easy to start and fun to master
19:55Not just fun but rewarding too haha
19:56Yeah the libs I mentioned are super game-dev forward stuff. Probably won't hear about them unless you're really into the do-it-yourself sort of game dev :)
19:58But I can say confidently that Raylib has a big list of language bindings that I browse once in a while. It's a great way to get a language presented to a group of like minded individuals who like to express themselves!
BeardPower_gitlab
20:05@9214
orx engine. It’s using Rebol for scripting the project templates but they want to switch to Red for that.
They also think about using Zig in the future. The engine is implemented in C and C++.
XANOZOID
20:12Ahh orx, orx is pretty cool
BeardPower_gitlab
20:29It's the best engine. Period.
XANOZOID
20:35You use it :)?
Oldes
20:57@XANOZOID I'm sort of game dev (former Flash dev) and never heard about these libs too. Thanks for mentioning theses. I will have to try them oncd I will have samo time again.
20:58@BeardPower_gitlab don't know Orx either.
XANOZOID
22:36@Oldes 😄 always fun to get into engines. If you're a former flash dev you'd be right at home with my former daily-language Haxe. It's got lots of devs who dropped off from the Flash days and you'll see many parallels. OpenFL was created in it as well, essentially the closest you can get to Flash! I'm not of a Flash background though so that never interested me haha.
22:38Well . . . for me I'm far more interested in just multiplatform multimedia kits. Kha/Kinc, by far, fits that bill perfectly 🙂
BeardPower_gitlab
22:55> You use it :)?

Yes.
22:59Raylib is a nice collection of tools but does not come close to orx's performance. orx was created by a former Ubisoft developer. It's optimized for performance, resources and a lot more. It features a great built-in profiler and the data-driven features are awesome.
23:07https://wwx.silexlabs.org/2016/assets/presentations/robert-konrad/images/bunnymark.png
23:18@Oldes You don't know orx despite creating a shim for the creator of orx?
"oldes wrote a shim for me in Red/System for SteamWorks a year or two ago".
greggirwin
23:20@XANOZOID Using Red as data is more than half the battle. :^) Along with what @9214 said, bear in mind that do is like eval in some other langs, and you don't want to use it on untrusted data. But load is safe, and (without worrying about bind), you can use construct to make objects without evaluating their specs, which makes it safer as well.

As we sometimes say: In Red everything is data until it's evaluated.
XANOZOID
23:43@BeardPower_gitlab Awesome! Yeah, I like Raylib because it's simple enough that I can create my own things around it :) - it's just a set of functions and structures . . . not really anything "fantastic" in its own regard, but I like to start small and grow big . . . Kind of like the "Forth" mentality of things.
23:47@BeardPower_gitlab And definitely - I am super aware of Orx as a very very capable engine :). Raylib and Kinc are certainly not "engines" in the same regard . . . and neither are, technically, able to compete with it in terms of rendering. However Kinc _can_ be faster than Orx only because it's not an engine, it's really just a toolkit that compiles in a cross-platform way to other APIs like DirectX, OpenGL, Vulkan, Metal, and even proprietary protocols (new-school and old-school ones). It's not just graphics though - it has bindings for your usual multi-media needs including disk stuff and input. It's got a tool for compiling an adaption of GLSL to different platforms. The guy's been working on so many platforms professionally and for fun it's great to get insight from him!
23:51@greggirwin Thanks a lot Gregg! I appreciate hearing from everyone :). Also - very good to know, that's exactly the sort of thing I'm looking for while I'm learning 😄. So I went on the right path then investigating a combination of reduce load ... then? If so - then there must be a fundamental difference between doing and reduceing, right? Only other way I can think of getting around untrusted data is I've seen something called "use" which I'm guessing allows context to be more specific? Or I guess I'd just have to parse the data haha. Thanks, Gregg!
23:51Ahh okay - construct . . . I'll spend more time looking into those too today after I get some things done :)

9214
08:10@XANOZOID do evaluates and returns the result of the last expression (if any), reduce evaluates and retains the result of every expression. They both rely on Red interpreter: do, by design, invokes interpreter at runtime (which sometimes helps to bypass AOT compiler limitations), but IIRC reduce's body, if it's a block!, is statically compiled.

>> do [add 1 2 3 * 4]
== 12
>> reduce [add 1 2 3 * 4]
== [3 12]


The "untrustness" of data is entirely dependent on how it is evaluated: some evaluators, like do, are Turing-complete and allow for the possibility of arbitrary code execution, and some (notably dialects) are completely harmless no matter what you feed them. Rebol had a special [Secure](http://www.rebol.com/r3/docs/functions/secure.html) dialect for sandboxing, Red plans to expand on it at some point.
08:14use is an equivalent of let in other languages, it introduces a throw-away "local scope" to evaluate a piece of code that contains "variables". Red doesn't have it by default (and Red/System has, OTOH with a bit different semantics in mind), but it's a very common idiom.
bubnenkoff
09:07is there any another new conceptual language except Red? I know that there is Rocket but maybe something else?
XANOZOID
09:26@9214 thank you :) This makes sense to me
9214
11:09@bubnenkoff you surely mean Racket, which is AFAIK a Scheme derivative and isn't that new. It positions itself as a world-first platform for programming language design and is quite popular in academia, also having some success stories in the industry.
bubnenkoff
12:03@9214 thanks you are right
13:37I want to move all words with values from data to object with foreach loop (the would be some processing inside):
o: object []
data: [id: 1 name: "foo"]

foreach [k v] data [
	; print [k v]
	append o [k v]
]


I am getting error:
Script Error: = does not allow object for its series argument
9214
13:43@bubnenkoff how is that different from object data?

To begin with, object! is not a series and so you cannot append anything to it. Moreso (and assuming that o is, say, a block!), you append [k v] literally, i.e. it should rather be reduce [k v], or even repend o [k v].
bubnenkoff
14:55How to make lots array instead of map?
o: object [ id: 1 price: 777 lots: object [obj: object [a: 1 b: 2 c: 3]] ]

>> to-json o
== {{"id":1,"price":777,"lots":{"obj":{"a":1,"b":2,"c":3}}}}

Something like:
{{"id":1,"price":777,"lots":[{"obj":{"a":1,"b":2,"c":3}}]}}

14:59this does not work:
o: object [ id: 1 price: 777 lots: [object [obj: object [a: 1 b: 2 c: 3]] ] ]
9214
15:33@bubnenkoff block! :point_right: array; object! :point_right: map; you want a map within an array, so just combine the two.
greggirwin
17:55@XANOZOID reduce is not safer than do because... reduce [do [print "gotcha!"]]
bubnenkoff
18:46> @bubnenkoff block! :point_right: array; object! :point_right: map; you want a map within an array, so just combine the two.

Should i use to-block? Or I can simply use block word?
9214
18:51@bubnenkoff well, try it and tell me why it doesn't work :wink:
bubnenkoff
19:00@9214
o: object [ id: 1 price: 777 lots: to-block object [obj: to-block object [a: 1 b: 2 c: 3]] ]
to-json o

== {{"id":1,"price":777,"lots":["obj:",["a:",1,"b:",2,"c:",3]]}}

strange that obj: to-block object [a: 1 b: 2 c: 3]] is getting "obj:",["a:",1,"b:",2,"c:",3]] as result
9214
19:08@bubnenkoff

> Something like:
>
> {{"id":1,"price":777,"lots":[{"obj":{"a":1,"b":2,"c":3}}]}}
>


>> to-json object [id: 1 price: 777 lots: reduce [object [obj: object [a: 1 b: 2 c: 3]]]]
== {{"id":1,"price":777,"lots":[{"obj":{"a":1,"b":2,"c":3}}]}}
bubnenkoff
19:11big thanks! Why reduce is need here?
9214
19:13@bubnenkoff you can answer it yourself by inspecting and comparing the contents of [object [foo: 'bar]] and reduce [object [foo: 'bar]] blocks.

XANOZOID
07:02@greggirwin That makes sense . . . has me thinking a lot! Well, what it really makes me think about are the ways of developing in Red/Rebol-like stuff without evaluating code . . . Somewhere I recall reading about the idea of things not really evaluating unless they're reduced or already out of a "block" - because blocks need to be reduced/evaluated or (I think?) composed/morphed before being usable. Then again the exception from what I'm thinking are functions. The more Red code I write the more it'll make sense I'm sure :).
07:03So far I've made a nice little script setup for my own daily "automated" tasks and such . . . or at least the start of which.
07:05Other than that I'm playing around with Red/System, with success, and got it connected with Raylib! Running into trouble with a specific function in Raylib though that seems to keep throwing exceptions. I'm having trouble figuring out what errors are the Red/System side, the dll side, or the stuff in between. The feedback loop in the System dialect isn't _very_ strong being that there's no repl like regular Red (obviously) but so far it has been nice to have a setup, like this, where very similar grammars can be used for the high and lows of the software stack!
09:56@Oldes Hi Oldes, I saw you authored this submission, https://github.com/red/code/pull/66, to Red/Code repo and noticed your vulkan red bindings were noted as being "generated". I was doing a quick look for anything related to this but didn't find one too fast . . Was this a hand-made thing or can I find such a tool to use myself? Thanks!
Oldes
10:03I used just a quickly hacked Rebol script to parse the header files with some manual modification of the result.
9214
10:05@XANOZOID some binding generators off the top of my head (non of which are finished AFAIK):
* [c2reds](https://github.com/iceflow19/c2reds)
* [RGB](https://github.com/Pebaz/RGB)
* [parse-c-header](https://github.com/rebolek/parse-c-header)
Oldes
10:06@XANOZOID https://gist.github.com/Oldes/69dfe24089655446547678d721b6bdc9
rebolek
10:18Parsing C header means parsing whole C.
Oldes
10:20@XANOZOID https://github.com/Oldes/parse-opengl-headers
9214
10:21@XANOZOID if you are interested, feel free to create a [wiki page](https://github.com/red/red/wiki) that lists all the available generators.
XANOZOID
15:20Thanks all! And I'll do that some time when I get the chance today then :)! Very nice to see there's some stuff to look into 🙂

XANOZOID
09:05So I took a look, and I think I'm going to try to see if I can write my own quick generator. Gives me a practical reason to learn parse - which I really wanted to start learning sooner than later 😄
rebolek
09:13@XANOZOID Good luck! If you get stuck, don't forget that you can always ask in https://gitter.im/red/parse
bubnenkoff
12:50I am doing request to server with function foo. The request can be failed because server is down.
But I am using result of server response in function bar. So what I should to return from foo? Dhow I throw exception or I can exit and someway check from bar?
greggirwin
16:31That's a general design question we all face at times. Do we throw exceptions or use return codes. Both can work, and consistency in their use is the main thing. Mixing them makes life hard. With Red, you can also return multiple results easily, like HTTP and some other langs do now. Another consideration is how the data might be used in chained calls. e.g., look at some Red funcs like remove which can silently handle none! values, so find remove ... won't throw an error on you if the value isn't found.

I don't recommend exit, though you can check for unset results. Unset is special and shouldn't be passed around like a regular value if you can avoid it.

A key question I often use: Is none! ever a meaningful result for a call? That depends on the call of course. If you are doing something like a query against a server, none may mean "not found" and can't be used to indicate failure.

Oldes
18:12@bubnenkoff why you just don't return the error from the foo function?
>> foo: func[url][try [read/info url]]
== func [url][try [read/info url]]
>> error? foo http://rebol.com
== false
>> error? foo http://rebol.abc
== true
18:16You can even check http response code.. like:
either all [
	block? result: foo http://google.com
	result/1 < 400 ;<--- http response code check
][ ?? result/2 ?? result/3 ][ print "Read failed!" ]

bubnenkoff
12:16@Oldes @greggirwin thanks for explanation!
13:23Am I right understand that 'return codes' = 'errors'?
Oldes
13:56@bubnenkoff codes => https://www.restapitutorial.com/httpstatuscodes.html
bubnenkoff
14:04@Oldes I did however think that @greggirwin mean error codes. I read a little bit more. If I right understand I can simply return make error! "some text" from function and than check it with error? than doing throw "some error"and that catching it. Am I right?
Oldes
14:06As you can see, you can do many things ;-)
bubnenkoff
14:07So if I am returning errors than I should not use try catch, right?
Oldes
14:12You don't have to.. you can put the try out of foo function as well.. hard to say how it looks in your real life.
bubnenkoff
14:18If I am returning error how to extract text of it?
9214
14:36
text
>> ? (make error! "Error message")
make error! [
    code: 800
    type: 'user
    id: 'message
    arg1: "Error message"
    arg2: none
    arg3: none
    near: none
    where: none
    stack: none
] is an error! value.
bubnenkoff
14:54oh it's object!
Oldes
15:08It's error!... or if you want a pseudo-object. It's not object!.
9214
15:10
text
>> any-object!
== make typeset! [object! error! port!]
bubnenkoff
15:51Should I always use do in do make error! "Empty response from server"?
For example the next code is work fine without do:
a: 1
f: func[] [
	if a = 1 [ make error! "some error"]
]
bar: func[] [
	either error? f [print "there was an error"] [print "all ok"]
]

bar


but in real project I faced with problem that line:
print "1111"
if none? res [make error! "Empty response from server"]
print "2222"

is printing 1111 and 2222 without do make ...
9214
15:56@bubnenkoff creating an error! value and evaluating it are two different things.
bubnenkoff
15:56but why first code is working?
9214
15:58Because f returns an error! that you created and that error? recognized?
bubnenkoff
15:58oh! Yes! I am understood! Thanks!
9214
15:59There's also cause-error wrapper:
>> cause-error 'user 'message "Error message"
*** User Error: "Error message"
*** Where: do
*** Stack: cause-error
XANOZOID
17:36Red is a gradually typed language right? Where it's okay to leave out types? I think so
17:40Also - is it possible to refine your parameter types to specific prototypes? I was thinking I could do something like
my-type!: object [ is-alive: true ]
is-alive?: func [ obj [my-type!] ] [ obj/is-alive ]
17:41But this wouldn't make for a valid type specifier
17:48So, if this is the case, is Red only gradually typed up to only the language-provided types? I read a post on the Red website made by Gregg-Irwin about "user types" and modifying something in the system language stuff as some sort of debate. That's not exactly what I have in mind . . . I understand that Red is far from being a static language and there's things you can do (and should be able to do) that just make following the types near impossible, but to what degree of type-checking during "script-compilation" is there for Red? If Red (not R/S) has run-time level type-checking enforced at the end of the day why not allow for what I have here? It's almost no different than If I were to define my own "run-time type check" function, which is definitely possible.
9214
17:52@XANOZOID that's correct, Red is gradually typed, OTOH "gradual" means a bit different things in type theory. See [here](https://github.com/red/red/wiki/%5BDOC%5D-Type-system) on the topic of type system and its loose classification.
XANOZOID
17:54Anyhow . . . I enjoy duck-typing as much as the next person, but I still think there's room for expanding on the "gradually" typed idea - even if it can't be fully realized due to the nature of Red's transformational programming approach. When I think about it, the next step could be "structural typing" - which is just something I want to throw out there for others insight or if it's been given thought in the past
9214
17:59Datatypes and object prototypes are entirely different things. That being said, nothing stops you from creating a scaffolding in the form of function constructor and object wrappers that would work the way you want. The question is: how much sense does that make in the context of the problem that you're trying to solve? Chances are high that there's a more idiomatic solution.
XANOZOID
18:00There could also be a new "type" function which extends the lookup table associated with types and associates it with a structure
18:02Then there's also the possibility of extending the object [...] so that it identifies a specific object a type from the table on creation - under some form of meta information
18:02But that's implementation details I'm not trying to get into right now - I'm throwing around ideas that are cool to me
9214
18:04> so that it identifies a specific object a type from the table on creation

It's called a class ID and already exists in a rudimentary form as a part of object ownership system.
XANOZOID
18:05Going back to what you said -- The problem I'm trying to solve will be explained given another question I have in a second . . . I'm sure there is an accepted train of thought here, just want to get feedback on it since I find this to be concerning to me. Working on the code of a large organizations codebase has brought me much anxiety about scalability and productivity and a number of other problems that just stop me from making progress in life . .. working on such a long-term codebase has been both an eye-opening experience and a crippling one.
18:10Going on a bit further . . . from those of experience writing redbol for a while . . . what's been the hardships writing long-term, and potentially complex, applications for a language that doesn't necessarily have types? Have you found working with a language without static typing more difficult to maintain? Or what have been your approaches reducing the amount of unexpected run-time issues that are so common in projects that use languages like that? Where do you think the value comes from in an untyped language (let's ignore gradually typed for this discussion) in the long run? Do you think that what statically typed languages provide isn't actually beneficial to creating a maintainable scalable project?
9214
18:13@XANOZOID I am sorry, what makes you think that Red is untyped? It's strongly-typed, dynamic language. There are no shenanigans with implicit type conversions. All the questions are more-or-less addressed in the link to a wiki article I gave above.
XANOZOID
18:14I'm saying statically typed
18:15And I mean fully-statically typed where compilation is enough to prevent you from type related errors
18:15Strongly, weakly, dynamic has nothing to do with my questions really
9214
18:19So, if I understand it correctly, you are asking why Red is not statically typed and what are the practical benefits and downsides of its existing type system?
18:24[Here](https://gitter.im/red/red?at=5f3808001226fc213356c24d) is a similar thread from a month ago.
XANOZOID
18:34@9214 I actually continued my writing as a thread above as not to detract from "help" since there's a lot to it
18:38I suppose I should clarify that from "statically" typed I mean *strongly* and *statically*. No point in an argument about what typing means - I hope the real concepts I wanted to discuss were there.
ALANVF
21:54Would someone care to explain the behavior of date! values here? I thought they were passed by reference.
Red[]

n: 1-Oct-2020

print n ;=> 1-Oct-2020

n2: n
n/day: 2

print n  ;=> 2-Oct-2020
print n2 ;=> 1-Oct-2020  ;-- ???
21:56actually, this seems to happen with any datatype that supports accessors
21:57still confused though
23:46...?
XANOZOID
23:46@ALANVF by accessors do you mean refinements? Also: https://github.com/red/red/wiki/%5BNOTES%5D-Dates-and-Times
But which part about this is confusing if I may ask
ALANVF
23:47by accessors I mean the /day: 2 in n/day: 2
XANOZOID
23:47Oh yeah I also see what you're talking about by the way
23:47Interesting
ALANVF
23:47and the confusing part is that I can modify the original value, but it's copied when assigned to n2
XANOZOID
23:48That _is_ interesting
ALANVF
23:48I'm trying to figure out how to implement this correctly in my Red.js project, but I don't see this behavior documented anywhere
23:48it also even happens in Rebol

XANOZOID
00:02Yeah I'm not exactly sure why Date is not a referenced value type . . . but maybe it needs to go on the list?
ALANVF
00:03"on the list"?
XANOZOID
00:03of values that don't get shared between words
ALANVF
00:03ah ok
00:03so it's technically supposed to be a reference type?
XANOZOID
00:04If it was a reference type what you were trying would work - so it doesn't appear to be one as of right now
ALANVF
00:04yeah I'm asking if that's a bug or intended behavior
00:05R/S stuff seems kinda finicky in general, so I assumed it was a bug
XANOZOID
00:07IMO it should be a reference type if you can mutate it
ALANVF
00:07sounds good then, thanks :thumbsup:
XANOZOID
00:07(you are the pro here though lol, not me!)
ALANVF
00:08nah I rarely touch R/S stuff, unless I'm converting R/S code to work in Red.js
XANOZOID
00:11Oh lol I have no idea how it's supposed to be implemented low level . . . I know about as much as you do so I guess the next person will be more helpful identifying an actual problem . . .
greggirwin
05:32@XANOZOID I boil typing in Red down to: values are strongly typed, variables are not.

As with methodologies, there is no "one size fits all" solution in type systems. There are pros and cons on each side, and the biggest benefit comes when you can leverage each where needed. It's also true that the architecture of a program or system goes hand in glove with the language. My Redbol systems have been architected quite differently than I would have done in a static language before finding Rebol.

My largest Rebol system, IIRC, was around 75KLOC, made up of many cooperating processes and subsystems, but all in a single codebase. Without detailing that system, while 75KLOC doesn't sound large, consider how much leverage and power you get for each line of code in Rebol, and also how much of that code was shared because the system could do that easily. e.g. a sub-system might have 5 programs that are each 1KLOC or less, but share 10KLOC of libraries. Ultimately, systems should not keep growing linearly. I'll hazard a guess that many systems do even worse than that.

A benefit of separating work into communicating processes is that you are *forced* to think about what's being communicated, and the very fact that data is being passed around makes it easier to introspect and analyze. Whether you use blocks, objects, dialects, or something else, this creates loosely couple systems which are (generally) more resilient. Of course, there are many other principles and practices that come into play as well.

A criticism of my approach is that it's not as efficient. My default view is that if you're concerned about efficiency first, you're probably worried about the wrong thing.
05:36Before I read into the date! chat, you can use typesets to learn a lot about related types. e.g. ? scalar!.
05:38And if you want to see how Red does it, the [source](https://github.com/red/red/blob/master/runtime/datatypes/date.reds) is the ultimate reference.
06:00Most importantly, this is not a bug.

Another helpful research tool is looking at funcs to see what types they support. This isn't foolproof, because of Red's flexibility, but we do try to have things make sense. In this case, do ? copy. You'll see things that can be copied, which you might think of as reference types, or mutable, but we don't use those terms in Red. Another typeset to look at is immediate!.

Notice that there are *some* scalar types which are not series, but can be changed in place. @ALANVF if you look in %datatypes/structures.red, you'll see clearly that date! values are self contained. That is, a date! doesn't reference a separate time! value for its time component.
9214
06:52@ALANVF Red uses call-by-value by copying arguments (value slots) onto evaluation stack, but some values contain references to external data outside them, thus giving the ability to mutate said data in-place (unless you explicitly copy it), which looks like a call-by-reference to the uninitiated. Datatype having accessors doesn't mean that it's indirect (i.e. contains references).
bubnenkoff
09:17Question about naming. I want to logic word. How would it better to name it? is-process-started-by-user? is-process-started-by-user or maybe something better?
rebolek
09:19If would use something shorter like user-process? but it's up to you. If it's logic value, ending with question mark is a good idea.
ALANVF
14:45Thank you @greggirwin and @9214 for the explanation, although it would be nice if this behavior could be documented somewhere
14:49would it be correct to assume that n/day: 2 is actually more like n: n + make date! [day: 2]?
14:49in the sense that n itself is given a new value, rather than the date value
9214
14:57@ALANVF in the former case the content of the value slot is modified in-place ([day field](https://github.com/red/red/blob/ba500c73bfc20952b1030ead14533f444faf4124/runtime/datatypes/structures.reds#L324) specifically). In the latter case it is copied on the evaluation stack, another date! value is added to it, and n gets re-set to this newly created value.
ALANVF
17:24yeah I'm not saying that it works exactly like that
17:25I think a better way to ask this is if day is associated with n or n's value
9214
17:31@ALANVF With n's value, which is a date!. [Here](https://github.com/red/red/blob/ba500c73bfc20952b1030ead14533f444faf4124/runtime/datatypes/date.reds#L964) is how such named accessors are resolved: name is simply mapped to a corresponding integer, and then a [gigantic switch](https://github.com/red/red/blob/ba500c73bfc20952b1030ead14533f444faf4124/runtime/datatypes/date.reds#L998) is dispatched on it. So:
>> date: now/date
== 2-Oct-2020
>> date/3
== 10
>> date/month
== 10
ALANVF
17:43I think I get it, but that behavior is a bit unintuitive ngl
9214
17:45@ALANVF in what sense?
ALANVF
17:45allowing values with copy semantics to be mutable is unheard of afaik
17:46well, for builtin types at least
17:47actually, I think it's more because most mutable types in Red have reference semantics
17:47so I didn't expect other mutable compound types to have copy semantics instead
17:48I think everything has been cleared up though, so thanks
17:49(I mean it still makes the implementation in red.js annyoing, but eh :stuck_out_tongue:)
9214
17:49It seems that you are overthinking things a little bit.
ALANVF
17:49yeah probably
greggirwin
17:50> it would be nice if this behavior could be documented somewhere

@ALANVF it would be great (and easy) for someone to copy the notes above out to a wiki page, as a starting point. Copy them for real, don't reference them. ;^)
ALANVF
17:50yeah possibly soon (once I get the time)
17:51I had assumed that any type with accessors had reference semantics
greggirwin
17:51Maybe @XANOZOID could do it.
17:51When you assume... :^)
ALANVF
17:51yeep ;)
17:52despite how much c++ I've done this past year, it somehow didn't even occur to me that these values could have copy semantics
17:52thanks y'all, really appreciate it :)
9214
17:55@ALANVF values are passed around on the evaluation stack, that's all there is. Don't overcomplicate it. _All_ of them are mutated internally. Some values can hold their data in its entirety, but others had to keep references to external buffers, that's the only difference there is to make.
ALANVF
17:55:thumbsup:
17:56will definitely keep it in mind
greggirwin
17:57I think that's the key point. Values are treated consistently, and we sometimes talk of elements in blocks as "value slots". Look at %datatypes/structures. reds and you'll see there's no raw int or anything. R/S works differently of course.
17:57Nice summary statement @9214.

luce80
15:09I am trying to use Red with Visual Studio Code but I can not run the script because it puts too many quotes on the command line. It outputs:
cmd /c '"E:/Programmi/red.exe" "e:/Dati/color-slider.red"'

And gives me an error,
instead of:
cmd /c "E:/Programmi/red.exe e:/Dati/color-slider.red"

How can I fix it ?
15:20I am on Win7

wallysilva
04:40@luce80 Just double check the extension's settings. It should be something like this:
04:41[![image.png](https://files.gitter.im/5780ef02c2f0db084a2231b0/Naq6/thumb/image.png)](https://files.gitter.im/5780ef02c2f0db084a2231b0/Naq6/image.png)
XANOZOID
21:02@greggirwin Thanks! I'd love to write an entry :). I've been busy between work and school these last few days . . . not getting a lot of sleep. I'm not trying to ignore anyone!

dsunanda
08:14Red download page - https://www.red-lang.org/p/download.html - is unwell (has been so for at least 30 mins):
Error: Server Error
The server encountered a temporary error and could not complete your request.
Please try again in 30 seconds.
endo64
08:31Confirmed
greggirwin
15:51OK here right now.
dsunanda
16:33Download is back...It was just a long 30 seconds :)
greggirwin
16:41It was a temporary config issue.
XANOZOID
18:21@greggirwin I would like to document the behavior that's going on with the whole "Date", copy, slot, and evaluation stack - but I'm not quite catching what detail is important to be noted . . . What kind of value is Date? All I know of are two cases in Red. Either a value is scalar and each word contains its own scalar OR a value gets bound to a word/words. I was thinking Date! would not be under the same behavior as a scalar . . .
18:27Also - thank you for your words and experiences in a large production redbol application! I've been thinking a lot 😅
giesse
18:47@XANOZOID words don't store values. to simplify a bit, values are stored in contexts (to which words in turn refer); all values have the same size, that's why you've heard of value slots or cells. some values refer to external data such as blocks (an array of value slots), strings, etc.
18:48so the distinction is simply about mutating the value itself (in the value slot) or the data the value refers to (which may be referred to by multiple values)
9214
18:48@XANOZOID that's not specific to date!, but rather falls under the general description of Red evaluation model.
giesse
18:49passing values to functions copies the value slot, so you can't modify a date from a function argument for eg.
18:49
>> f: func [d [date!]] [d/day: 2 probe d none]
== func [d [date!]][d/day: 2 probe d none]
>> dd: now
== 5-Oct-2020/20:49:32+02:00
>> f dd
2-Oct-2020/20:49:32+02:00
== none
>> dd
== 5-Oct-2020/20:49:32+02:00
9214
18:50To avoid any confusion: what @giesse describes doesn't mean copying as in copy, but copying as in memcpy.
giesse
18:50right, copy the bytes that make up the value slot (is it 128 bits in Red?)
9214
18:51@giesse I prefer to say that the value slot is 4 machine pointers in size. In Red that's 4 * 32 = 128 bits ATM.
mikeyaunish
18:58I am having problems unlinking using the following scenario:
link-text: function [ text-tgt text-src ] [	text-tgt/text: text-src/text ]
== func [text-tgt text-src][text-tgt/text: text-src/text]
>> F1: make reactor! [ text: "F1" ]
== make object! [
    text: "F1"
]
>> F2: make reactor! [ text: "F2" ]
== make object! [
    text: "F2"
]
>> G1: make reactor! [ text: "G1" ]
== make object! [
    text: "G1"
]
>> G2: make reactor! [ text: "G2" ]
== make object! [
    text: "G2"
]
>> probe re-res: react/link :link-text [ F1 F2 ] 
func [text-tgt text-src][text-tgt/text: text-src/text]
== func [text-tgt text-src][text-tgt/text: text-src/text]
>> probe re-res: react/link :link-text [ G1 G2 ] 
func [text-tgt text-src][text-tgt/text: text-src/text]
== func [text-tgt text-src][text-tgt/text: text-src/text]
>> probe re-res: react/unlink :link-text [ G1 G2 ] 
none
== none

The last unlink isn't working. This only shows up if I have linked both pairs of objects first.
9214
18:58@XANOZOID of course you can be devious and implement Red/System functions that _will_ mutate the value slot in place: it's enough to pass a pointer to the value, or to get a hold of the node pointer of the buffer where it resides. But Red functions (and by extension routines) always push values on the evaluation stack and are accessed as offsets from the frame base (e.g. stack/arguments + 1).
19:07@mikeyaunish it appears to work if you unlink them in the same order (i.e. f1 f2 and then g1 g2). Although in your case only f2 and g2 are reactive sources, so you don't need to unlink f1 with g1.
mikeyaunish
21:00@9214 - Is this a feature or a bug? I want to be able to unlink them in a different order depending on need.
9214
21:01@mikeyaunish either a bug or a subtle reactivity quirk.
mikeyaunish
21:43@9214 Is there someone who can say if this is already a bug?
XANOZOID
23:37Hmm all of this talk makes me think there should be a crash course sort of deal that starts small and builds up to the bigger picture :)
23:42I would like to try, but I'll need to still understand some basic things . . . no time just yet though. I'm keeping this in my head while I do work though

XANOZOID
05:14So are slots the abstract idea here that I'm not really seeing? Might I infer that a "slots" is terminology for some value at an index in a series? I kind of just understand everything to be a value or a symbol (word I guess) and a series at this point. Slots, although I have seen a few posts briefly using the terminology, have not brought much more meaning to my understanding of redbol evaluation. However, I kind of understand where Gabriele is coming from, in regards to context-symbol relationship - so that much I sort of had the impression of. If I am going to relate it back to the "source" code you provided, though . . . Going back to the whole "Date!" being "weird" thing, I realize I didn't capture everything correctly the first few times I read it. I sort of get what's going on - but that in itself is enough for me to look forward to investigating the source code more 😄. Pretty motivating!
05:15So I'll take some time and look at Date!'s source and ponder the implementation a bit. Maybe I'll come back and ask a few more questions and write something up. I plan on making some sort of video tutorial for Red in the future so that'll be good to know.
05:16On another note - does anyone know where this seemed to have gone: https://web.archive.org/web/20190331164123/https://doc.red-lang.org/en/libred.html ?
05:17I'm thinking I might want to use Red as an embedded language for a mobile app in the future so I'm hoping this is still a thing and not missing for a reason
rebolek
05:58@XANOZOID slots are implementation of values. Each slot is 128bits of memory reserved for one value, be it integer!, date!, string!, block! or whatever else. Most of these 128 bits are metadata, some hold actual value (in case of scalar! types like integer) or pointer to actual value (for series! types). See actual layout of slot here https://github.com/red/red/blob/master/runtime/allocator.reds
So if you have this piece of Red data: [1 "hello" 2-3-2023], Red allocates four slots: one for block! that holds other values, one for integer!, one for string! and one for date!. integer! and date! slots hold the value, block! and string! slots holt pointers to actual values as you won't fit that data in the slot.
endo64
06:11@XANOZOID About libRed, it is not missing, just the doc page redirected to github temporarily. See https://www.red-lang.org/2017/03/062-libred-and-macros.html and https://github.com/red/docs/blob/master/en/libred.adoc
giesse
08:14@XANOZOID
> everything to be a value or a symbol (word I guess)

Everything is a value, words are values too. They are no more special than integers or blocks.
08:18things only get confusing when talking in the abstract, because people tend to map those abstract concepts to what is familiar to them (eg. other languages) and that causes confusion
08:18if you're familiar with C, or even just how computer hardware works, it's all very easy to explain.
GiuseppeChillemi
09:31>> things only get confusing when talking in the abstract, because people tend to map those abstract concepts to what is familiar to them (eg. other languages) and that causes confusion

It is the "prior knowledge" problem I have faced in the early days. You tend to see everything under the light of what you already know about other languages.
09:33It is influenced by multiple factors.
XANOZOID
09:33I wasn't referring to other languages when I used that terminology 😅
09:33It's what I've read on Rebol
09:34But I read a post by Nenad just recently that was pretty dang good at explaining things
09:34within the last hour or so
GiuseppeChillemi
09:34Have you a link?
09:34(To Nenad Post)
XANOZOID
09:36Sure do! It's unrelated to me referring to "words" and "values" as being different by the way. That was still prior reading I've done. But Nenad's post does a lot more clarification for me: https://www.reddit.com/r/redlang/comments/4ecs9n/insane_behavior_in_rebol_lets_put_an_end_to_this/d2lt4fi/?utm_source=reddit&utm_medium=web2x&context=3
09:43"saving snapshots of 'code'" < His remarks related to this are kind of making me think about why Redbol languages are the way they are. It's starting to make a lot more sense.
GiuseppeChillemi
09:45When you are in front of a door and its handle, you will try to open it rotating the handle down by 45 degrees. But if the door works rotating the handle UP instead of down, you will need some time either to discover it and to break this automation (you will have the tendency to rotate the handle down every time you will encounter this door). This is the whole "prior knowledge" concept applied to this new adventure in Red and on every new adventure you will face in your life.
I have not the time to read the whole topic but from Gabriele's message, I suppose you are currently in this scenario.
09:47Give you some time and you will break your how neural network (friendly called The Matrix) and you will acquire the new knowledge. The TOP Rebol/Red programmers are answering your questions.
XANOZOID
09:56😅 I was not confused by what Red is and the things that are different from other languages but I was trying to contextualize some terminology and a minor misunderstanding in implementation that I barely missed. But the conversation so far has been very productive and today I feel much more aware of Red than I was a week or so ago when I started 😊. Thanks to everyone here of course!
09:59@endo64 Thanks! I had found the broken link I posted earlier through the exact blog-post you mentioned . . . perhaps the API Docs link needs to be updated? Currently it brings you to a white page with red text "Not here"
GiuseppeChillemi
10:03Maybe it is the opposite, the prior knowledge mechanism is influencing us, so we think you are applying other languages concepts, like everyone who has approached Red, when it is currently not happening. I will read all and make my opinion (but I tend to believe in Gabriele's words because of his 20 years of experience in this field).
10:05However, welcome aboard and enjoy Red!
XANOZOID
10:05@GiuseppeChillemi Sure :). I had gotten a few things mixed up - specifically "Date!" not doing what I had expected it to do based on other redbol code I've seen - and then having read that words "bind" to data somewhere online had thrown me off too. Then the terminology of "slots" was something I've read a lot and never actually "seen".
10:07I tell you I think I get it, but coming this far I bet I'll think that many more times 😂
10:08Thanks! At first I liked it . . . now I'm *really* liking it :)
9214
10:12@XANOZOID value is a box. Like a box, it has a content (or payload). There are a lot of values in Red, and so there are many boxes, all are uniform in their size and neatly arranged. To differentiate which box contains what kind of payload, there's a tag sticked on each box. Because this tag says what type the data stored inside the box has, we call it datatype. This leads to Red motto number one: everything is a value, and each value has a datatype.
10:16Of course, one size doesn't fit them all. Uniform shape of a box might be too small to hold data of a given type in its entirety. To work around that, box can contain a reference to an arrangement of other boxes, e.g. it's position in the storage room. This "arrangement" is called a buffer, and it is external to the box that references it. So, this gives us the basic taxonomy of boxes: whose that contain references to external buffers and whose that do not. The former values are called indirect, the latter direct.
10:21Because the box is uniform and can hold "stuff" in it, we call it a value slot, or just a slot. This term is reserved for values in which the datatype is somehow differentiated, e.g. "date slot". For values in which the datatype doesn't matter (i.e. generic value, unit) a term "cell" is reserved, as in "allocate 3 cells".
10:27Now if you imagine yourself playing sokoban and pushing such boxes round and around, that's what Red evaluation would look like. A bunch of boxes get arranged in some meaningful way, and because some boxes refer to other boxes, this arrangement forms a tree. In computer-sciency lingo it's called a concrete syntax tree, because this is what you get when you type "boxes specifications" (i.e. literal forms of values) in a REPL, constrained by syntactic rules. Literal form of date!, for example, is one of such specifications that results in the creation of a "box" in the "storage room" of RAM.
10:46Then there are different sokoban players, [each pushing boxes differently](https://store.steampowered.com/app/316080/Parcel/) (dialects interpreting blocks, aka a bunch of boxes, differently, according to their semantics), and boxes interacting with each other when they are pushed together, as in some sort of artifical chemistry where Red runtime constitutes the physical laws of molecule interaction. You get the idea :alien:
endo64
16:18Another great explanation!
XANOZOID
16:42Thanks Vladimir! I'm curious of a concrete syntax tree, will be looking at it a bit :)
theSherwood
16:48So the value slot of a word contains a pointer to a cell in some particular context?
16:56In the case that the word has not been bound to any value in any particular context, is it set to point to the value of unset!?
9214
17:01@theSherwood it contains a reference (called binding) to a value that provides a context, which is either an object! or a function!. Context, in turn, contains symbol/value pairings. Specific value can be found if you know its index (which every any-word! value also holds alongside the binding). See [this](https://gitter.im/red/help?at=5accc5a91130fe3d36c0b7e9) ad-hoc diagram.
17:02Words are always bound to some context, the default one is system/words aka "global context". unset! is used to indicate that word is not set to any meaningful result of a computation, i.e. it's just a filler.
17:02See also [this](https://gitter.im/red/help?at=5dc6026e4adf071a84f6afb7) hand-wavy explanation of the binding concept.
17:11And https://github.com/red/red/issues/4552 for the gory details and more pretty pictures.
theSherwood
17:13Okay. Those are great diagrams. So when a block is reduced and expressions are evaluated, the word is replaced with the appropriate value in the context it references.
9214
17:15If the value it refers to is "passive", yes. "Active" values (most notably functions) perform some actions associated with them; this is how evaluation proceeds.
theSherwood
17:17Okay. That makes sense. And this system with cells will be the case whether the script is compiled or interpreted, is that right?
9214
17:19Naturally, yes. If you imagine interpretation as a set of various calls to Red runtime that happen as you evaluate the expressions, then compilation is a freezing of one such chain of calls according to static heuristics, followed by compilation of such chain (which is a Red/System code) to machine code. The evaluation model stays the same.
17:20Actually, the other "active" type is unset!; I can't come up with any other one.
17:22This helps to understand the distinction between word!s and get-word!s: the former "activate" whatever can be activated, the latter always treat everything passively by fetching values as-is.
theSherwood
17:24Okay. So the cost of this design (from a perf perspective) is that word!s always introduce at least 1 extra reference between themselves and the values they will evaluate to? Due to the evaluation model, there's no way to inline those values during compilation because then you lose the words which are an essential part of Red semantics.
17:26That distinction between "active" and "passive" types is very useful.
9214
18:03@theSherwood words are values too, just like everything else in Red. Word can be set to another word, which is in turn set to yet another word, ad nauseam. If you do such inlining then you are essentially corrupting the data.
>> this: copy that: [a b c d e]
== [a b c d e]
>> set this move that tail that
== [b c d e a]
>> get 'a
== b
>> get get 'a
== c
>> get get get 'a
== d
>> get get get get 'a
== e
>> get get get get get 'a
== a
>> get get get get get get 'a
== b
...

You are correct in saying that there's always a level of indirection between a word and its value. It doesn't affect performance negatively though, and is marginally faster than doing a scope resolution in the languages that have scopes.
theSherwood
18:12That makes sense. Thanks, @9214 !
9214
18:13@theSherwood you're welcome.
theSherwood
18:16Oh, follow-up question: what happens at a function call? The words of the function spec are bound to the same values as the words that were passed in as arguments?
18:19Of function calls have their own context. So the word from the spec is bound to the function call context which then gets a copy of the data from the arguments?
9214
18:25Functions have their own context; if you think of context as a two-column table of (1) symbols and (2) values associated with them, then in functions the first column is constructed from the spec, and the second column remains vacant, and gets filled only during function call by the content of stack frame. If there's no stack frame, then the word that is bound to function's context has no value:
>> foo: has [bar][bar: 'qux do block]
== func [/local bar][bar: 'qux do block]
>> block: [get bind 'bar :foo]
== [get bind 'bar :foo]
>> do block ; FOO is not called, so there's no stack frame
*** Script Error: context for bar is not available
*** Where: get
*** Stack:  

>> foo ; stack frame is laid down
== qux
theSherwood
18:27Okay. So the second column of that table is essentially just a reference to the stack frame? When the stack frame is popped off the stack, there is no second column again?
9214
18:28And then there's also a generalization between function! and object! which are not really that different between each other:
foo: func [a b /bar c][a + b - c]
foo/bar 1 2 3

Is the same as
do bind [a + b - c] context [a: 1 b: 2 bar: true c: 3]

With a few caveats:

1. function! provides "protocoling" in the form of argument's order and typing;
1. function! provides optimization by keeping argument values off the heap and on the evaluation stack;
1. function! provides niceties like embedded docstrings and different modes of argument passing.
18:33@theSherwood that's correct. It's not even an explicit reference, just a [bit flag](https://github.com/red/red/blob/master/runtime/allocator.reds#L35).
18:34And context-type! in turn is [just an enumeration](https://github.com/red/red/blob/5e2956277dc3d7f203e9dfd66edb597ad7fd585c/runtime/definitions.reds#L70).
theSherwood
18:43This is really enlightening.
9214
18:45[It is](https://www.youtube.com/watch?v=uwmeH6Rnj2E).
theSherwood
18:47Haha. Brilliant
18:52Somewhat unrelated question, but is there any way currently to get a block parsed into the CST without actually fully evaluating it? By which I mean, getting the values that words refer to without activating "active" values? I'm guessing this has to be happening at some point in the runtime but isn't exposed as a function! or action! users can call.
giesse
18:55@theSherwood actually, that never happens in the interpreter. the compiler (probably) does a bit of that, but it's limited in how much it can do.
9214
18:55> is there any way currently to get a block parsed into the CST without actually fully evaluating it?

@theSherwood there is. It's called transcode (or load for that matter). Nothing is evaluated until you say so.
giesse
18:56@9214 i think that that's not exactly what they are asking for... I suspect @theSherwood knows about load :)
theSherwood
18:56So load doesn't seem to group the expressions into a traverable tree, which is what I'm after.
9214
18:57There are no expressions to speak of. It's all just a bunch of values. "Expression" as a semantic construct occurs only when you do a block. It's like a second-order structure emerging from the arrangement of values. You can traverse this bunch of values whichever way you want.
theSherwood
18:59Yes. I basically want to be able to see what expressions do is going to construct but not fully evaluate them.
19:00@giesse So the interpreter is just evaluating as it is grouping, rather than doing 2 complete passes. That makes a lot of sense.
9214
19:01Like this?
Red [
    Title:  "Group expressions"
    Author: 9214
    Date:   07-Jun-2018
]

group: function [
    list [any-list!]
][
    gather: [to paren! copy/part list mark]
    also list until [
        mark: preprocessor/fetch-next list
        tail? list: change/part/only list do gather mark
    ]
]

>> group [add 1 2 reverse [a b c]]
== [(add 1 2) (reverse [a b c])]
19:02I guess that would constitute an abstract syntax tree, not a concrete one.
theSherwood
19:03Wow, yeah. Just like that. You're right. I should have said "AST"
9214
19:03It's not an ideal solution though, because it's too coarse-grained, but it gives you an idea.
>> group [add 1 2 + 3]
== [(add 1 2 + 3)] ; rather than (add 1 (2 + 3))
theSherwood
19:03Can it handle nested functions and functions with refinements?
19:04Oh, right. Wrapping the op! would be very nice.
19:04That is very cool.
9214
19:05The bulk of the job is done by [fetch-next](https://github.com/red/red/blob/5e2956277dc3d7f203e9dfd66edb597ad7fd585c/utils/preprocessor.r#L161). So whatever it can do, this wrapper can do also.
theSherwood
19:06I see. So does fetch-next not identify op! in quite the same way as it does function!?
9214
19:08It identifies only the top-level expression and ignores the sub-expressions.
>> group [add 1 add 2 3]
== [(add 1 add 2 3)]
theSherwood
19:09Oh, I see. So it would need to be applied recursively is all.
9214
19:16So, yes, @giesse was right in saying that the compiler already performs similar form of ["chunking"](https://github.com/red/red/blob/5e2956277dc3d7f203e9dfd66edb597ad7fd585c/compiler.r#L4411).
theSherwood
19:33Great! Thanks @9214 and @giesse

giesse
07:01There are two fundamental problems:
- No matter what kind of "AST parser" you write, I can write a piece of code that works fine in the interpreter but is not parsed correctly by your code. This is a fundamental difference between REBOL and other languages.
- Even assuming you're ok with that (more than 90% of the code people actually write would not be too hard to parse), you have to have some kind of interpreter phase before you attempt to parse the code, otherwise you have no way of knowing if something is a function call, and if it is, how many arguments it takes.
07:04my main plan for the Topaz compiler was for it to compile function! values, not block! values. So, you let the interpreter do as much work as possible beforehand (kind of a super-powered pre-processor), then compile a "main" function that represents your program. Even then, the compiler needs to do a LOT of static analysis to be useful.
That being said, the Red compiler proves that as long as you are willing to deal with a bunch of limitations, you can still do quite a bit.
theSherwood
07:54@giesse Good points. My use case is for a dsl that allows for some kind of Mathematica-esque partial evaluation. Basically allowing me to reduce a block but without evaluating any expression that contains an unset! word. Any nested blocks where mini-dialects might be lurking, I will simply not attempt to reduce (I think).
9214
10:29Grokking Futamura projections can also be really enlightening :wink:
bubnenkoff
10:37If I want to run some function after starting view[] where\how I should to call it? I need to start it without any user-action
9214
10:50@bubnenkoff [skimming thru documentation](https://github.com/red/docs/blob/master/en/vid.adoc#do) every now and then helps :wink:
view [... do [...]]
bubnenkoff
10:52oh! Thanks! I really started thinking in the wrong direction.
XANOZOID
15:17@9214 does that work for every dialect? Because otherwise I wouldn't have thought to look there as a feature of the "view dialect" . . .
15:17How does one modify an object's or function's body in place? I was hoping to be able to modify the block they refer to as a way of changing the behavior of the block rather than creating a new object or function. Was thinking you could do something like append x body-of func/object [ additional code ]. Also noticed there's an "extend" (action? or function) word that might not have a finished implementation yet. I was also hoping perhaps I could "bind" the words from one object/context to another at some-point during run-time but that also seems to only be supported for context-onto-block for now. So what's the right way to create a namespace/object that can extend its number of accessible properties (paths) during runtime? I'm not trying to do something like some-word: make some-word [new things] or copy.
9214
15:19@XANOZOID could you please clarify what is "that"?
15:19Objects are not extendable at the moment, so to add new entries you need to use the old object as a prototype.
15:22Function's bodies can be modified though, and that will affect function's behavior. But there's a sublety of so-called precompiled functions which won't react to such changes, so you need to reconstruct them at run-time first.
>> sin 90.0
== 0.8939966636005579
>> clear body-of :sin
== []
>> sin 90.0
== 0.8939966636005579 ; no change, even though the body is empty
XANOZOID
15:23@9214 I noticed you linked to docs of VID dialect - nice :). My brain said "why would do [...] work for view unless it's supported? Silly me
9214
15:25
text
>> clear body-of :math
== []
>> math [1 + 2 * 3]
== 7

... in another session ...

>> math: func spec-of :math body-of :math ; reconstruction
== func ["Evaluates expression using math precedence rules" 
    datum [block! paren!] "Expressi...
>> insert body-of :math bind [print ["Math evaluates" datum]] :math
== [print ["Math evaluates" datum] 
    order: ['** ['* | quote / | quote % | quote //]] 
    in...
>> math [1 + 2 * 3]
Math evaluates 1 + 2 * 3
== 7
XANOZOID
15:25Great! Good to know that you can dynamically re-word a function. So then I must have been doing something pretty wrong yesterday when I was trying to bind a function's body with an object then
9214
15:26@XANOZOID so you were trying to create a form of closure?
>> foo: does bind [a: a + 1] context [a: 0]
== func [][a: a + 1]
>> foo
== 1
>> foo
== 2
>> foo
== 3
>> ? (context? first body-of :foo)
     a  integer!      3
XANOZOID
15:29I'm aware of that ability there - and I was playing around with making my own "func" that wrapped the body of it under a specific context. But what I was trying to achieve was that, only after the function was defined
9214
15:29@XANOZOID yes, do in this case is a VID keyword; there's also support for embedded expressions for certain facets:
view [text data 1 + 2 * 3]

15:30So you want to create a function and only then to bind words in its body to some context?
XANOZOID
15:31Oh nice! I thought I had tried that some time ago but failed - but I've only scratched the surface with my "view" experience so far though. Good to know - I was going to be looking into composable layouts sometime in the near future and thinking I'd try more stuff out like the embedded expressions
15:32@9214 yeah, sort of like executing some function under some context it wasn't initially defined in
15:35Going back to the whole "prototype" situation - so because prototyping calls for a new object, and because you can't change the body of the prototype due to objects not being extendable, my intentions of "building" a namespace as time goes on is not possible**yet**
9214
15:35Well, functions don't execute "under some context", nor are they defined for some specific context. Context is a word-specific thing; each word in function's body can be bound to a separate context for that matter. But anyway:
>> foo: 0 bar: does [foo: foo + 1]
== func [][foo: foo + 1]
>> bar bar bar
== 3
>> foo
== 3
>> bind body-of :bar context [foo: -3]
== [foo: foo + 1]
>> bar bar bar
== 0
>> foo
== 3
>> get in context? first body-of :bar 'foo
== 0
XANOZOID
15:37I imagine my phrasing of "under some context" would be understood as late binding of the words in the body of a function - but still I find myself unable to express my intentions without there being some confusion from time to time 🙂
15:38@9214 sweet!
9214
15:44Body of an object is, how to say, a virtual thing. It doesn't exist as a ready-made block!, but can be constructed from the two halves that constitute object's context, which is a list of symbol and a list of associated values. This is what body-of called on object! [does](https://github.com/red/red/blob/5e2956277dc3d7f203e9dfd66edb597ad7fd585c/runtime/datatypes/object.reds#L1088) by the way. You can do whatever you want with it, but it won't reflect onto the object's state.

To return to you question: if you model namespace as an object, then yes, it cannot be gradually extended with new symbol entries, but rather needs to be re-created with each new entry (or a set of entries).
XANOZOID
15:50I was hoping to avoid that but that's okay for now!
16:03@9214 So I noticed that when using the repl the "words" I define are located in system/words - which appears to be an object. In a way, it seems like this is a simulation of an extendable object . . . perhaps I may find it useful to look into that
16:04It sort of makes sense though if the repl was treating the entire session as one big "word" body and giving me feedback for each line
9214
16:05It is extended automatically by the runtime system, there's not much you can borrow from it in terms of functionality. Words need to be bound to some context, and the global context (i.e. system/words) is a default one for that. Each words that gets introduced appears in it first, even if it is never used afterwards.
XANOZOID
16:06That makes sense 😄. Speculation is what it is without looking at the implementation . . . but gets me thinking! Anyhow . . . had one more question
16:12Last one for now, was to do with modules. I read on the Red blog modules are intended for release in version 0.8 so . . . Right now I am aware that some people recommend creating a "context" for your definitions. In this case, you'd end up doing things like module/functionality/refinement x y z. So if I wanted the user to opt-out of writing the module name and use it like some functions are available globally (I guess system/words?), what would be the idiomatic approach? I'm thinking anyone here would really just do something like foreach word in words-of x [ set . . . . ]?
9214
16:16You can "export" a portion of your API by setting corresponding words globally. Or you can provide a "gateway" in the form of dialected interface that will bind words to that module and do the job.
XANOZOID
16:17Thanks Vladimir :). I'm thinking I'll do both 😄! Awesome
9214
16:17set/any bind words-of x system/words values-of x should be enough, but that would export absolutely everything, which defies the purpose of a module.
XANOZOID
16:18Right - perhaps providing something like module/public-words to be used with that would be a nice-to-include*
9214
16:19Good idea. I'd call it exports though.
XANOZOID
16:20Love that! Okay great - I really appreciate your insight!!
9214
16:21You are welcome :smile_cat:
giesse
17:57@theSherwood

> My use case is for a dsl that allows for some kind of Mathematica-esque partial evaluation.

Don't try to parse any Red code, just write your own dialect. E.g. help math. Otherwise... you're going into one deep rabbit hole. :)
theSherwood
18:59@giesse Essentially all I'm wanting to do is prevent the evaluation of unset! words (and any expressions which contain them). Otherwise, I'm wanting to maintain the same red semantics that you have with do. I don't see any way to do this without producing an AST.
9214
19:03@theSherwood you cannot know beforehand the value of a word. And even if you manage to statically deduce it, it then can change at run-time, more than once, or even be re-bound to a context that did not even exist at the time of the static analysis. Even words themselves can be introduced at run-time, and be unset.
theSherwood
21:00@9214 Yes. I must not be explaining what I'm trying to do very well because I don't intend to do any of this statically. That seems like a recipe for madness with Red. I intend to use something like that group function, but to selectively reduce expressions with no unset! words.

Usage would be something like the following:
a: 1000
symbolic-reduce [a + x + 2 * a]
== [((1000 + x) + 2000)]
9214
21:08> I don't intend to do any of this statically

But you just did! I get the idea though. Indeed, it's a mathsy partial evaluator that ignores "free variables" or any expression that contains them.
theSherwood
22:12Hmm. I wouldn't have thought to describe preprocessor/fetch-next as doing static analysis. Surely it takes live values into account?

And yes. That the general idea.
9214
22:16What do you mean by live values? "Static" means that it does the job before the code runs, just by looking at it and poking around, "dynamic" means that it does the job _as_ it runs: e.g. speculatively evaluate the infix sub-expression, see if it fails with the unset error, backtrack and deduce which of the two (or both) arguments caused it, then substitute it for either result of the evaluation.
XANOZOID
22:19It sounds to me that Adam wants to parse the "words" and literals conditionally on what they evaluate as and their actual symbol
9214
22:22@theSherwood note also that there are a lot of assumptions baked in: judging by your example, only scalar! values get substituted, but e.g. op!s are not. What if + is not set to an op!? What if something that doesn't look like + is set to addition op!? What if left and right arguments both look like +? Etc, etc.
22:24That is, returning to my recent example between "passive" and "active" values, you want to substitute only "passive" ones, without triggering any function application or unset-related errors.
theSherwood
22:26@9214 Fair. I guess I’m making the assumption that preprocessor/fetch-next is looking up the value of words that it encounters in the relevant context, words that may have been set by the program while it runs. So the analysis is static with respect to the block but not with respect to the entire program. I suppose I’m more accustomed to the idea of static analysis being something that happens before the program runs. Though with the way Red works, that isn’t a useful model.
22:26That’s a good question. Would fetch-next catch what + has been set to, for example?
22:27I would like to be able to trigger some function application if the args are not unset!
9214
22:28@theSherwood in your case, block is the entire program. What operates on it (an evaluator, an analyzer, a compiler) is a different, external matter. But yes, it can happen that this external program affects the behavior of this particular one.
theSherwood
22:29That makes sense

giesse
07:27@theSherwood

> Otherwise, I'm wanting to maintain the same red semantics that you have with do

All I'm saying is... don't do that. :)

If you're going to do it anyway, you might as well write the compiler I wanted to write 10 years ago... if so, start a chat room or mailing list somewhere and I'll join and talk things through. :)
bubnenkoff
12:05Why the follow code does not work?
It's seems that integer is too big:
>> to-integer "2410525241"
*** Script Error: cannot MAKE/TO integer! from: "2410525241"
Oldes
12:16Yes... Red has only 32bit integer so far.. use float instead:
>> to-float "2410525241"
== 2410525241.0
12:17
>> to-integer to-float "2410525241"
*** Script Error: integer overflow/underflow
*** Where: to
*** Stack: to-integer

bubnenkoff
09:45I tried to create two files. app.red and foo.red in app.red I am doing do load %foo.red. After compiling with red.exe -c app.red I got app.exe with external dependence to foo.red. Is there any way to inline (put in) all context from foo to app.red to get only one file?
toomasv
10:56#include %foo.red
bubnenkoff
11:42Does compiling app give any significant performance improve?
9214
11:43Depends on the app.
bubnenkoff
11:56Could you give an examples of cases?
12:00I wrote app. It setting some words with func like:
f: func[] [some-value: "123"]

to make some-value available outside. So it's work with REPL, but does not allow me to compile app because compiler find variables before they are declared.
I did them global declared like:
some-value: none


Am I right? Or it's like a hack?
9214
12:10[Compiled vs. interpreted behavior](https://github.com/red/red/wiki/%5BDOC%5D-Guru-Meditations#compiled-versus-interpreted-behaviors).
bubnenkoff
12:23> I wrote app. It setting some words with func like:
>
> f: func[] [some-value: "123"]
>

> to make some-value available outside. So it's work with REPL, but does not allow me to compile app because compiler find variables before they are declared.
> I did them global declared like:
>
> some-value: none
>

>
> Am I right? Or it's like a hack?

So it's issue: "As of 0.6.0, the Red compiler can't process dialects. The interpreter doesn't have this issue, and the compiler will, correctly, complain." ?
13:12And what is dialect? I still do not have full understanding
9214
14:28@bubnenkoff the issue that you link to is misleading; Red compiler does not process dialects simply because it shouldn't: they (input blocks, that is) are fed to a dedicated dialect processor (e.g. view or parse) and should not be tampered with.

The problem with "undeclared words" is not related to dialects either, but is rather generic: compiler distinguishes between "code" and "data" by following a set of static heuristics; interpreter, by contrast, figures this distinction out as it proceeds with evaluation. So, if "declaration" occurs in "data", compiler will complain, simply because it did not find it in "code" and thinks that the usage of a word is invalid. Interpreter does not make any such assumptions. The link that I gave gives a simple example of this.
14:31> And what is dialect?

"Dialect" is a loosely defined umbrella term for data formats, ad-hoc evaluators, an embedded domain-specific languages created in Red. For example, function spec is a dialect as a format, math is a dialect as a small evaluator, parse is dialect as a DSL.
greggirwin
18:46@bubnenkoff you can compile in encap mode (-e) to get interpreted behavior and a single standalone EXE. Unless you're doing heavy math, like in the mandelbrot demo, you likely won't see much change in performance. It would be good to have an article that highlights when compilation makes a difference, because people think everything will go faster when a) it won't, and b) it only matters in special cases. The key, of course, is knowing what parts of your code are slow, which is where profiling tools will help. Then you think next about the algorithms used, and what you might do in R/S, because a better algo will give you massive gains, while general Red compilation won't.

bubnenkoff
09:01@rebolek does your http-tools support setting custom timeouts?
rebolek
15:32@bubnenkoff no. It's not possible to set timeout on Red level yet.
9214
21:54@bubnenkoff

> Could you give an examples of cases?

In your case, as I understand it from the type of questions and code snippets that you post, compilation won't make much of a difference, because you're working on parsing for XML and/or JSON data, and making HTTP requests; that means that your program is mostly I/O and memory-bound, that it either waits for data to arrive or processes this data in RAM. Compilation down to machine code helps if there's a lot of number crunching happening, i.e. when a program spends most of its time using CPU.

bubnenkoff
12:54> @bubnenkoff you can compile in encap mode (-e) to get interpreted behavior and a single standalone EXE. Unless you're doing heavy math, like in the mandelbrot demo, you likely won't see much change in performance. It would be good to have an article that highlights when compilation makes a difference, because people think everything will go faster when a) it won't, and b) it only matters in special cases. The key, of course, is knowing what parts of your code are slow, which is where profiling tools will help. Then you think next about the algorithms used, and what you might do in R/S, because a better algo will give you massive gains, while general Red compilation won't.

It's seems that Red do not recognize -e syntax, because it's not compile app with: red.exe -e F:\code\app.red
9214
13:08@bubnenkoff -r -e or -c -e, depending on which compilation mode you work with.
bubnenkoff
13:26app.red:
Red []
#include %foo.red
view [panel foo]

foo.red:
Red []
foo: [button]


after compiling with: red.exe -r -e D:\test\app.red
I am getting error: Script Error: view has no value
9214
13:30@bubnenkoff naturally, because you didn't include View module by putting Needs: View in the header.

XANOZOID
17:41I can confirm that compile with red -t windows -r file.red when having Red [ Needs: View ] in the header, works nicely!
17:43I tried looking for some reference on this, but is there a way to position a window instead of it always being centered? And is there a way to grab reference of a window and apply things to it? Like closing that specific window (since you can omit the handles) without using "quit" (which ends the entire Red process). I found some-word: view [...] does not capture the window (probably gets unset).
bubnenkoff
17:53
f: func [] [
  some-data-that-need-be-accessible-everywhere: []
  append some-data-that-need-be-accessible-everywhere "foo"
]

vs
some-data-that-need-be-accessible-everywhere: [] ; near top of code
...
...
...
f: func [] [  
  append some-data-that-need-be-accessible-everywhere "foo"
]

Is there any best practice?
9214
17:53@XANOZOID it doesn't gets unset, it simply waits for view to exit the GUI event loop (and then errors out because it returns unset). Use layout to get a hold of the tree of faces, which you then can reference and manipulate.

> is there a way to position a window instead of it always being centered?

view [do [self/offset: 0x0]]
XANOZOID
17:53@9214 thanks!
rebolek
17:54@bubnenkoff having "global" word defined at "global" level makes more sense.
XANOZOID
17:55[![image.png](https://files.gitter.im/5780ef02c2f0db084a2231b0/iJsQ/thumb/image.png)](https://files.gitter.im/5780ef02c2f0db084a2231b0/iJsQ/image.png)
bubnenkoff
17:55So when it's better to use func in real app? I mean that it;s very hard to control and prevent words overlay. Words declared at top at last placed near each other
XANOZOID
17:55@9214 because it doesn't "unset", I think I noticed that even after the window closes it had no value . . .
17:55Looks like view/no-wait gets around that :). Wonder if that's a bug
9214
17:55@XANOZOID what's a bug, specifically? view returning unset?
XANOZOID
17:56Whoops I guess I wasn't thinking very clearly since I completely understand what you said lol
17:57No, all good!
18:02@bubnenkoff func can be used in plenty of places! Func is relative to whatever context its words are referring to. So you can use func inside of a context/object for when you understand your context. I'm not sure you can get the same behavior using function which I believe only use words local to the function
bubnenkoff
18:04But it's better to limit it's usage of some context (objects) to prevent name conflicts? Right?
XANOZOID
18:04Actually I believe you could also use "Function" too - you just need to use self/xyz
18:05huh I'm wrong it looks like. Okay guess I don't understand :)
18:06I was not expecting function [/local x] [x] to have different behavior than function [][x] within a context
18:07Mmmm "making all set-words found in body, local" that is an important note.
18:08@bubnenkoff Why would you limit usage of context objects? You use them when you need them and that's really all there is to it . . .
18:10What name conflicts are you thinking would occur?
bubnenkoff
18:13for example I can create two functions with same set word and that get a lot of debugging problems. Like:
foo: func[] [x: 1]
bar: func[] [x: 2]
18:13in big app it very give words with same names
XANOZOID
18:14Is that all there is to what you're saying?
18:14If those are defined within the same context that's not such an issue
18:14That's just doing something you'd expect or should learn to expect with experience
9214
18:16> Func is relative to whatever context its words are referring to.

Any given word within function's body can refer to its own context, so this definition doesn't hold any water, unfortunately :wink:
rebolek
18:17@bubnenkoff I have a functor where you can mark local words in func body like:
foo: lfunc [data][
    /local x: 1
    parse data [copy /local value to end]
]
9214
18:18The only difference between func and function is that the latter tries to be smart and collects all set-word!s and words of iterators for you in a /local list.
XANOZOID
18:18@9214 Not sure how it resolves in the end, but when you define it, the words go up the context hierarchy from what I gather. Then after that I'm going to assume someone is injecting words some other way
18:18I think it's not a matter of "best practice" but a matter of knowing what you want your functions to do to start with. Both have their usages. Function isn't "better" to use if that's exactly what you want to do. Using function could have the opposite intentions if you're not careful. You just got to get comfortable with both in the end.
9214
18:19> the words go up the context hierarchy from what I gather

There's no such thing as context hierarchy. They are all separated from each other.
XANOZOID
18:19context [ . . . . context[ func [] [ words ] ] ] ] Is this not what I described?
9214
18:19No, that would be lexical scoping, which Red doesn't have.
XANOZOID
18:20The words inside of func are going to be related to that structure even when I pass them around
18:20I understand that. How much more "complex" can it be, I don't imagine much more
9214
18:21Not to that structure but to its context, and it alone. There's no hierarchy between contexts (aside from us dubbing them "global" or "local" sometimes).
18:21Imagine a kid holding a baloon. Kid is a word, baloon is its context. That's all!
bubnenkoff
18:22> for example I can create two functions with same set word and that get a lot of debugging problems. Like:
>
> foo: func[] [x: 1]
> bar: func[] [x: 2]
>


not good example. Better:
foo: func[] [x: 1]
bar: func[] [x: true]

or something that cause name conflict
9214
18:22And you can give that kid another baloon, but only one. Because if there are two baloons, then the kid will fly up in the air :wink:
XANOZOID
18:22I'm not seeing any concreteness in that analogy . . .
18:23I don't really see how it's different than what I was saying - is what I guess I'm saying
rebolek
18:23There is some kind of hierarchy in the sense that a context can be child of other context. But also child of different context. And parent to both of them. But they wouldn't know.
18:23Crazy world.
9214
18:24@rebolek uhm, no, there's no relations whatsoever between any given context and any other one. I guess you mean prototypes, not contexts?
XANOZOID
18:24And this can happen using static text without a form of binding or molding?
9214
18:25> I don't really see how it's different than what I was saying - is what I guess I'm saying

As I understand, you are saying that Red has lexical scoping.
XANOZOID
18:25I'm saying that the words in the structure I described, without any other unknowns, are going to be exactly what you expect them to be until someone else screws with it
rebolek
18:26@9214 I mean this:
a: context [x: y: none]
b: context [c: a]
d: context [e: a]
a/x: b
a/y: d

Here a is "child" of b and d and "parent" to both of them.
9214
18:27@rebolek ah, alright, but that's something that you model yourself, not intrisic to objects or contexts.
rebolek
18:28right
XANOZOID
18:29I don't think I'm missing anything just yet . . .
18:29Hopefully not
rebolek
18:29that's what I meant with "in the sense"
XANOZOID
18:30I'm still comprehending this as the words inside of the context a are whatever was known at the time of writing until otherwise redefined . . .
18:31like the words don't "look up" anything at any point in time, and only know what they know as written
18:35Wait - so @9214 did you mean that you understood what I wrote
> context [ . . . . context[ func [] [ words ] ] ] ]

As me saying the words are "scoped" at all times? I am of the impression that when you write them like this they are "initially" scoped to what is known when written or "realized", but after that there's no more "scoping" applied
rebolek
18:36that depends on what is words in your example
9214
18:37... and "initially", and "realized".
rebolek
9214
18:39@XANOZOID is that what you mean?
>> catch [context [foo: 1 context [bar: 2 qux: does [throw reduce [foo bar]] qux]]]
== [1 2]
XANOZOID
18:39To my understanding - words are not there to define a lexical relationship but used to define a a series of symbols. As static text, not formed during run time, we can assume that the words of the structure are constructed based on a few rules. Then, afterwards, the "hierarchy" is a façade of sorts
bubnenkoff
18:40So in result. If I need some global it's better to move it's to top of code than set inside func?
9214
18:47@bubnenkoff in terms of code organization it is better to group global parameters together, yes, or even factor them out in a separate config file of sorts.
greggirwin
21:11@XANOZOID another way to position: view/options [button "OK"] [offset: 10x10]
21:26@9214, it could be a nice, small article or blog entry (unless you already did one I forgot about), which explains the definitional aspect during evaluation. e.g. when objects/contexts are created. It's one of those things that appears to work like other langs so much (the façade is so realistic), that it's hard not to believe it works the same.
9214
21:31@greggirwin agreed. I have tons of drafts, but little to no time to weave them into a coherent blog post. Although what I have in mind is a more broad explanation of the core principles. Soon :tm: perhaps.
XANOZOID
22:05@greggirwin Thanks! That'll be nice to reference
22:06I'm not sure what I'm misunderstanding. I've read plenty of the examples and analogies about the "word, context" etc rules. I feel like it should really just take two sentences to explain the basic idea.
22:09I'll start writing down what it is I understand today, and then share it - and hopefully someone can clarify some misunderstandings . . . But honestly, the less "abstract it is" and the less you need to know about the philosophy of "redbol" languages I think the better it is to understand the structure of contexts and what to expect a word will be.
22:18I feel like perhaps I'm not covering all the "cases" in my explanations - but I feel like the evaluation of words are more or less to what I have described. I refer to this (https://github.com/red/red/wiki/%5BDOC%5D-Why-you-have-to-copy-series-values) as my general understanding
9214
22:20@XANOZOID but this has nothing to do with the evaluation of words. No need to try to cover all the "cases" — usually the more extensive the explanation, the farther it is from the truth :smiley_cat:
22:22I usually give that as an example:
>> cutlery: [spoon spoon spoon spoon]
== [spoon spoon spoon spoon]
>> set cutlery 'spoon
== spoon
>> print cutlery
spoon spoon spoon spoon

>> phrase: split "There is no spoon" space
== ["There" "is" "no" "spoon"]
>> forall cutlery [bind cutlery context [spoon: take phrase]]
== [spoon]

>> cutlery
== [spoon spoon spoon spoon]
>> print cutlery
There is no spoon
XANOZOID
22:29I think this follows what I understand already - I'm thinking this explanation just complicates the basics
22:29and we're not working with a context anymore
22:29How does this work for a context?
9214
22:30> I'm thinking this explanation just complicates the basics

I'm all ears for a simpler one! :wink:
XANOZOID
22:30It wouldn't, you'd have to refine that example to the function bodies inside of it, and the context-words that are "set" to their following series/word. . .
22:31Right?
9214
22:32TBH, I don't quite follow what you mean by all that. Let's take a step back, _way_ back.

---

Word is a boxed structure, i.e. internally it is pretty much the same shape as all the other values. OK?
XANOZOID
22:33I understand this, yes
9214
22:34Great! Conceptually, word consists of two parts: spelling and meaning. Spelling is a bunch of symbols that you see on the screen when you refer to a word. Meaning is a value that you get when you evaluate a word.
XANOZOID
22:34Yes, this is still as I understand
9214
22:35Almost like in the natural language, words in Red can have the same spelling and the same meaning, **or** they can have the same spelling and different meaning (homonyms), even if they are evaluated together as a group.
XANOZOID
22:36Sure, that's fine - but as I was saying earlier that behavior is _only_ possible when the block containing the words of the same "spelling" are constructed dynamically
22:36Otherwise they're all whatever it originally was . . . or is this incorrect?
9214
22:37@XANOZOID whatever it originally was, was constructed dynamically :wink:
22:39Words can't get their values without evaluation, there's no static meaning pre-assigned to them during typing.
XANOZOID
22:39But as you write a series structure, [spoon spoon spoon spoon], those aren't evaluated. However, putting that _specific_ block inside of context block or func [...] block - and there's nothing else wrapping it, spoon spoon spoon spoon will evaluate to whatever a single "spoon" is . . . no?
22:40It's impossible for "one" context/object to have multiple definitions for "spoon" as a word, but every spoon written inside of it may be different.
9214
22:42> But as you write a series structure, [spoon spoon spoon spoon], those aren't evaluated.

Correct, that's just data.

> However, putting that specific block inside of context block or func [...] block - and there's nothing else wrapping it, spoon spoon spoon spoon will evaluate to whatever a single "spoon" is . . . no?

Yes. But I am binding block (or rather each word in it) to 4 different contexts, one for each spoon.
XANOZOID
22:43Yes I think I understand where you're coming from . . . that's understandable. I suppose it really is a bit difficult to fully explain words without having everything
9214
22:43So the 1st spoon is bound to one context, the 2nd to another, the 3rd to yet-another, etc. Yet they all look the same.
22:44Both context and func actually do quite similar mumbo-jumbo.
22:45The case with single "spoon" that you describe is what occurs on the very first iteration of forall.

>> forall cutlery [print head bind cutlery context [spoon: take phrase]]
There There There There
There is is is
There is no no
There is no spoon
XANOZOID
22:46Thanks Vlad, if you are okay with that shortening of your name, I think I can take the nuances you're trying to really hammer down from here and write a little draft up. I'll post back here later this week (hopefully sooner than later) and ask for yours/everyone's peer review!
22:54Interesting - never really thought about the behavior of bind over a series with an offset head. Thanks for that image!
9214
23:07Best of luck. I can't get any smaller than that:

word → object / function → context
 |                            |
 • symbol                     • symbols
 • index                      • values


Which, in practice, begets more questions than it answers.
XANOZOID
23:08No I really appreciate it! I can understand how you want to address the issue now . . . and realize I "mostly" understand it . . so I was really just trying to grind this out so I can help write something out for everyone learning the best way I can :).
greggirwin
23:11Concrete is good. Maybe fleshing out something like this?
; We can omit the catch in an example, as `catch/throw` isn't
; needed to understand binding.
catch [
	context [		; Red creates a context, an anonymous one
		foo: 1		; and binds set-words in the spec to it.
				; Since context can't grow, it has to find
				; all the set-words first.
		context [	; But what happens here? We have another
				; anonymous context, so the "outer" context
				; doesn't have a reference to it. 
			bar: 2	; And words in its spec are bound to it.
				; But how does the body of `qux` know the
				; context of `foo`? It doesn't. `Foo` knows. ...
			qux: does [throw reduce [foo bar]]
			qux
		]
	]
]
23:12Start with the simplest case and add to it.
XANOZOID
23:18This helps! The comments reveal the flow of the situation really nicely. Will keep this in mind . . . thanks Gregg!
9214
23:20In the above:
* Topmost context grabs the provided block and traverses it in search of set-word!s, but only at the top level. It founds only foo: and extends its list of symbols with it, filling associated value with unset. The context is created, and the block is bound to it (and so is the content of the nested block), then evaluated.
* Upon evaluation foo is set to 1, and the nested context kicks in, repeating the operation described above. This sepearate (N.B.) newly created context has bar and qux as its symbols, again pre-filled with unset. Block is evaluated...
* ... bar is set to 2, and qux is set to the result of evaluation of does, which creates a function. Within function's body, throw and reduce are bound to a global context, foo is bound by the operation of top-level context to one context, and bar is bound by the nested context to another context. does itself creates an empty context because that's what it does (no pun intended).
* Finally qux calls that function, which throws the reduced block up the call stack, and gives you [1 2].

greggirwin
02:41> The context is created, and the block is bound to it (and so is the content of the nested block), then evaluated.

@9214, this is an important element to focus on as you write notes and articles. The fact that nested set-words are not collected, but nested words are bound is key.
giesse
08:21@XANOZOID if you think it might help to look at slightly higher level code than Red/System, I can explain what's going on [here](https://github.com/giesse/Project-SnowBall/blob/master/topaz/types/context.topaz#L42) ([Javascript version](https://gist.github.com/giesse/3ebac89c91ec8cbb06420f62d6b9dff2#file-topaz-js-L1308)) and so on. It doesn't get more concrete than that :)
greggirwin
17:22:+1:

bubnenkoff
08:13@toomasv I decided to revisit your example. I want to make it's clear. Am I right understand that order of execution is next:
-------------------------------------------+
				  |                                          |
              +-------+                                      v
 lots [data2: skip tail  append data2 copy/deep [lots: []]  -2]
Oldes
08:16
(copy/deep [lots: []])
                         (append data2 (copy/deep [lots: []]))
                   (tail (append data2 (copy/deep [lots: []])))
             (skip (tail (append data2 (copy/deep [lots: []]))) -2)
lots [data2: (skip (tail (append data2 (copy/deep [lots: []]))) -2)]
bubnenkoff
08:19oh thanks!
toomasv
08:19Nice :) Also:
+---------------------------------------------+
             |    +------------------------------------+   |
             |    |    +-------------------------------+   |
             |    |    |            +------------------+   |
lots [data2: skip tail append data2 copy/deep [lots: []]  -2]

Or may be rather:
+-----+-------------------+------------------------+
        v     |   +---------------+--------------------+   |
lots [data2: skip tail append data2 copy/deep [lots: []]  -2]
bubnenkoff
08:25big thanks!
toomasv
bubnenkoff
08:31Why code work wrong without tail?
toomasv
09:16When you append lots [] to data2, this needs to be first lots you see in data2 otherwise things will be appended not to the latest lots but to first one. Because if you don't skip back from tail then you'll see other lots before the last one. This matters only if you append several lots of course.

bubnenkoff
12:38I have got data struct:
data: [
	lots: [
		lot: [
			name: "foo"
		]
	]
]


I need to access to it's elements by path: [lots lot name]
>> to-path [lots lot name]
== lots/lot/name


but how to get full path with root data? I need:
data/lots/lot/name


in summary i need merge word data and block [lots lot name] to single path
9214
12:45to path! [data lots lot name]? Or append to path! 'data [lots lot name]. Path is a series, so the same set of familiar operations applies to it.
bubnenkoff
12:46thanks!
15:30I want to set path to empty block: []
How to do it?
and make a/b/c: []
to-set-path [a b c] 
== a/b/c:


I am thinking about set to-set-path [a b c] [] but it's do not work
9214
15:35put a/b 'c [], do reduce [to set-path! [a b c] []], set 'a/b/c [], set to set-path! [a b c] [] (which actually works in the latest version).
bubnenkoff
15:52latest = Automated builds, master branch ?
15:53
>> set to set-path! [a b c] []
*** Script Error: a has no value
*** Where: set
*** Stack:

15:56actually I want to do sonting like:
1. to create set path with value []
2. append it's to data
data: []
append data set to set-path! [a b c] []
9214
15:56@bubnenkoff why do you think this error happened?
bubnenkoff
15:56it's trying to evaluate result?
9214
15:57So you want to put [a/b/c: []] into an empty block?
15:58> it's trying to evaluate result?

It's trying to access an element which you did not create beforehand, which is a.
>> a: [b [c none]]
== [b [c none]]
>> set to set-path! [a b c] []
== []
>> a
== [b [c []]]

bubnenkoff
15:59> So you want to put [a/b/c: []] into an empty block?

I have got block with data ([a b c]). I need so make them set path with value and then to add in another empty block
16:18Can I safely start few of exe compiled with -c -e and be sure that there were no errors with shared resources like some global vars?
16:53> > it's trying to evaluate result?
>
> It's trying to access an element which you did not create beforehand, which is a.
>
text
> >> a: [b [c none]]
> == [b [c none]]
> >> set to set-path! [a b c] []
> == []
> >> a
> == [b [c []]]
>

>

Or. I understood that a in path do not exists. But I did not understand how to create such path of un-existen elements
9214
16:56@bubnenkoff you are already creating it with to set-path! [a b c]. a can be created afterwards.
>> unset 'a
>> path: to path! [a b c]
== a/b/c

>> a: [b [c d]]
== [b [c d]]
>> set path 'q
== q
>> a
== [b [c q]]

>> a: [b [c x]]
== [b [c x]]
>> set path 'y
== y
>> a
== [b [c y]]
17:01a/b/c by itself doesn't care if either of its elements exists or not, just like [a b c] doesn't (and internally path! and block! are one and the same). It matters only when you try to evaluate the path, e.g. by calling set on it.
bubnenkoff
17:03Thanks for an example! So it's impossible to set value to it?
9214
17:04Clearly it is possible, I just did that in the example above. Unless you mean something entirely different by "setting a value".
bubnenkoff
17:06I want to get from

data: []
append data set to set-path! [a b c] []


data: [
	a/b/c: []
]
9214
17:09Well, I already [asked](https://gitter.im/red/help?at=5f88715fea6bfb0a9a389830) if that's what you actually want to do an hour ago :smiley_cat:
>> data: []
== []
>> append data reduce [to set-path! [a b c] []]
== [a/b/c: []]
>> new-line/skip data on 2
== [
    a/b/c: []
]

bubnenkoff
17:11Oh as usually big thanks!
XANOZOID
17:15From a semantical point of view - does it make sense that we should be able to "get" a "set-word" type? As well as "set" a "get-word" type?
9214
17:20https://github.com/red/red/issues/4448
XANOZOID
17:22I'm assuming that's just a legacy reasoning haha
17:23It says "should support" but not "why" - unless the contract from the start was "any-word" and it wasn't respecting _that_
17:27I noticed that you can't use #system or routine code inside of the repl. Will/should this be supported? Should I make a wish on this? Otherwise I'm thinking I have to adapt the REPL (rebuild it with bindings) for when I want to use my own Red/System code?
9214
17:28All values withing any-word! share the same structure and the same interface, ditto for any-path!. It makes sense, design-wise, to allow generic operations that work on one type of value to work on all the other ones. As for "why" — people find it more convenient; in case of set and get, the difference in datatype is most usually just a syntactic nuissance not worth of extra conversion. And, in general, semantic of a datatype is what you want to make out of it: in Red issue! is for preprocessor, in VID its for hex-encoded colors, in Parse they are just values used for direct matching.
XANOZOID
17:28Thanks Vladimir :)
17:29That makes sense - sounds like the "Redbol" way.
9214
17:29> Will/should this be supported?

When Red will be self-hosted and able to JIT compile such routines, so, after 1.0.

> Should I make a wish on this?

Patience, Grasshopper.

> Otherwise I'm thinking I have to adapt the REPL (rebuild it with bindings) for when I want to use my own Red/System code?

Yes, that's how it is usually done. You can define a separate file with bindings and include it into the console.
XANOZOID
17:30Wait . . . "include it into the console" - Wait . . . So it _is_ supported then?
17:31> Patience, Grasshopper.

🙇‍♀️🙏😆
9214
17:32@XANOZOID I mean "include" by hacking the [sources](https://github.com/red/red/blob/a9b26c7e966f4943bcdb584f33facdca49800124/environment/console/GUI/gui-console.red#L36) and compiling custom console from them afterwards.
XANOZOID
17:32Oh hmm. I think you mean there's a workflow for this. Got it! Okay yeah - I'm sure I'd have found it
17:32Gotcha gotcha
17:32I'm thinking about hacking a few things into my own repl lol. Like creating an event loop, kinda like view does except directly in the repl instead of my api, inside of it to simulate timeouts and stuff
17:33And I need a loop for when I want to start making an interactive game engine haha
17:34That'll be fun
9214
18:15@XANOZOID so you want a REPL within a REPL, sort of?
XANOZOID
18:25REPL in REPL? Hmm. . . If I was to be more concise - I mean to say I plan on somehow hijacking or breaking into the loop of the GUI based REPL so I can sort of fake cooperative multitasking. This would be so I can load up my engine through a command inside of the repl, and then it would open up a window that has its own event-loop . . . but while that's open I should be able to sort of operate between the two of them and send messages/data to the game instance. It should definitely be possible to some degree
9214
18:27Ah, I see what you mean. Perhaps @qtxie can comment on that, if he's not too busy. I wonder if the upcoming console plugin system would somehow address that.
XANOZOID
18:30Oh sweet! That would be awesome 😀. I'm fine with working my own while I'm playing around with making a game engine, but if something like that's coming up that'd be super helpful
Yamoon2018
18:43I need to find a way to connect Red with ODBC or any way to connect to GraphDB like ArangoDB or Neo4j
greggirwin
19:37@bubnenkoff on compiled EXEs and sharing, there is none at the Red level. That is, the processes can't see inside each other, anymore than other EXEs. *However*, if you load code or data dynamically, you can use it for IPC and such.
19:38@Yamoon2018 no bindings for those yet, but there are examples of others in the red/code repo, if you want to write your own.

pekr
06:17Our json does not work as a codec yet? Need to use load-json, right? https://github.com/red/red/blob/master/environment/codecs/JSON.red
endo64
06:45It works as a codec, load uses it if the file extension is .json.
06:45
>> write %file.json {{"a":1,"b":"ok"}}
>> load %file.json
== #(
    a: 1
    b: "ok"
)
>> load-json {{"a":1,"b":"ok"}}
== #(
    a: 1
    b: "ok"
)

pekr
08:19Ah, tried to use read/as, which according to help system, should allow reading via a codec?
rebolek
08:19you probably mean load/as
08:19and load/as works fine, I use it all the time
pekr
08:20So read/asis just for an encoding?
rebolek
08:23I've never seen read/as to be honest and I doubt there is support for other encodings than UTF-8, I would be really surprised. But I need to look at source to be sure.
08:31As I thought:

>> read/as %delme.w1250 'Windows-1250                       
*** Internal Error: reserved for future use (or not yet implemented)
bubnenkoff
11:32is there any way to access to second ("bbb") element by path?
data: [
	foo: [name: "aaa"]
	foo: [name: "bbb"]
]
data/foo/name ;  == "aaa"
pekr
11:34why do you have the same assignment there?
bubnenkoff
11:38Because I need such data structure.
rebolek
11:38but what is the point of having two same set-words?
pekr
11:40You can eventually iterate by the position: data/2/name or foreach [name value] data [print value/name]
11:40pity we don't have forskip
bubnenkoff
11:41As you remember I am generation complex structure. With big help from Toomas I get it work, but now I am learning it's again to understand it's better. In result I need to generate struct and then fill. I am trying to improve it's generation
rebolek
11:48@pekr
forskip: func ['word skip-num body][until [do bind body :word set :word skip get :word skip-num tail? get :word] set :word head get :word]
pekr
12:02Why it is not part of a default distro? Because we thought that we could get powerful for iterator but in the end got neither? :-)
rebolek
12:03Maybe someone can try merge request and maybe it will get accepted.
bubnenkoff
12:15> @pekr
>
> forskip: func ['word skip-num body][until [do bind body :word set :word skip get :word skip-num tail? get :word] set :word head get :word]
>


Could you explain how it can be helpful for my task?
rebolek
12:16you could do forskip data 2 [something]. Anyway, having same set-word in your data structure does't make any sense, there is better way to do this.
9214
12:36
text
data: [foo: [name: "a"] foo: [name: "b"]]
data: [foo: [name: "a" name: "b"]]
data: [foo: [name: ["a" "b"]]]
fergus4
13:43I want to step through a block of strings and have them append to a text area one at a time but it seems the area is not updated until the loop is finished and all strings are displayed at once. Also, is there a fix to using "wait" ...still seems to crash app.
toomasv
13:59I repeat myself :)
data: [
    foo: [name: "aaa"]
    foo: [name: "bbb"]
]
data: skip tail data -2
data/foo/name
;== "bbb"

That is if you want to select name from last foo.
14:05Witout path:
select select/last data 'foo 'name
;== "bbb"
bubnenkoff
14:15hah! Really cool! that's work!
rebolek
14:21
data: [
    foo: [name: "aaa"]
    foo: [name: "bbb"]
    foo: [name: "ccc"]
    foo: [name: "ddd"]
    foo: [name: "eee"]
    foo: [name: "fff"]
]


And what now? :)

As I wrote, this is really bad data structure.
planetsizecpu
15:06
data: [ [foo: [name: "aaa"]] [foo: [name: "bbb"]] ]
== [[foo: [name: "aaa"]] [foo: [name: "bbb"]]]

 ? data/1
DATA/1 is a block! value.  length: 2  [foo: [name: "aaa"]]

? data/2
DATA/2 is a block! value.  length: 2  [foo: [name: "bbb"]]

? data/1/2
DATA/1/2 is a block! value.  length: 2  [name: "aaa"]

? data/2/2
DATA/2/2 is a block! value.  length: 2  [name: "bbb"]



15:07I'm not sure if I understand what you want, but maybe this ^
15:09And so on:
? data/2/2/1
DATA/2/2/1 is a set-word! value: name:

? data/2/2/2
DATA/2/2/2 is a string! value: "bbb"

XANOZOID
15:09What about the "data" structure is wrong? It's valid Red code to me. If you intend on treating it like a tree, then you need to first construct a tree.
15:12IE: If you're defining a structure and require semantics beyond what Red will provide you out of the box, you just need to wrap it your own way. You could eventually create a tree that works like a path sort of like data/foo/1 ; bbb data/foo/2 ;aaa or data/foo ; [ [aaa] [bbb] ] ...
15:15However once you're working with those semantics you won't be able to share it with both your own semantics and the default without some ambiguity that'd need its own spec to solve.
rebolek
15:20@XANOZOID What is wrong? Using same set-word! for different blocks. You're right it's valid code (or data, to be precise), but just being valid doesn't mean it's right :)
Your point on tree is good. Actually with removing foo: you wouldn't loose any information (just the foo set-word that can be stored separately) and will gain simple accessible structure.
XANOZOID
15:43@rebolek Right! But as we know, that's mostly a misunderstanding of how Red will interpret a bare block. However, it could be deceiving to the ongoing learner that [ word: 1 word: 2 word: 3] should be no different than . . .
data: append append append []  bind [word] object [word: 1] bind [word] object [word: 2] bind [word] object [word: 3]
foreach word reduce data [ print word ] ; --> 1 2 3

Which would "appear" to have different forms of "/word", but we know it does not - and really shouldn't given the expected usage. . .
15:47
and even more tricky is that you also may observe this behavior
data/word == data/1 ; true
data/word == data/2 ; true
data/word == data/3 ; true
(reduce data/word) == (reduce data/1 )  ; false
(reduce data/word) == (reduce data/2)   ; true
(reduce data/word) == (reduce data/3)   ; false


Which is interesting since reduce data results in [1 2 3] but data/word resolved to the second word?>
9214
16:02@XANOZOID data/word uses word as a key to select what comes after it in data. Since the first value that matches this key is the first word, it select the second word, in all of the 3 cases.
XANOZOID
16:02Ah, I thought that would only happen if you had a set-word in there
16:03I was actually surprised you could use block/x as a form of query
16:03Well. I guess I should be careful with my words :). I mean with the behavior I thought only a set-word would do haha. Edit -- I should have noticed that! I was so caught off about there being no set-words . . .
9214
16:05@bubnenkoff what we are trying to say is that the type of structure you use is unfit for the type of data queries you perform. It's a balancning act, so you need to modify either of the two, or ditch both and look and the bigger picture.
greggirwin
17:37There's nothing wrong with having duplicate keys, it's just that path syntax or basic select doesn't know anything about them. You simply need to write processors that understand your data model.
17:44@pekr forskip is handy at times, to be sure, and for is still a possibility which could subsume it as well. Forall is no more valuable IMO, but what I loved most about them in R2 was that forall was a special case of forskip and so was a one-liner that used it internally. I can't say if forall is a native now because of a specific use case in the code base where performance was needed, but I *think* the same thing could be done at the R/S level. Forall could then even be a one-liner mezz which calls the native forskip. There may be details that make that harder than I expect though.

bubnenkoff
15:36If path is just the series why next code do not work with path?
all-but-last: function[b] [
	b: reverse b
	b: next b
	b: reverse b
]

path: [aa/bb/cc]
all-but-last [aa bb cc] ; work
all-but-last path ; do not work I expected to get aa/bb
9214
18:03@bubnenkoff because your path is not even a path, but a block with a path..? Reversing one-element block is a no-op.
greggirwin
19:36Concretely:
>> path: 'aa/bb/cc
== aa/bb/cc
>> all-but-last path
== aa/bb

bubnenkoff
08:33Thanks! I am experimenting with set syntax and can't understand where is error:
data: [
	foo: [name: "aaa"]
]

path: to-path [data foo]

; data/foo: tail data/foo ; this syntax works
set reduce path tail reduce path

error:
Script Error: invalid argument: "aaa"

09:26I found error. It should be:
set path tail reduce path
Rebol2Red
10:14inp: [5 3 8 1 2 1 12]
I want to remove the 4th value of inp to get [5 3 8 2 1 12]
How do i achieve this?
10:55Oops. I have to answer my own question. I could remove my question but for others who want to know how.
remove find inp inp/4
11:09Well maybe there is more to it. What if i want to remove the 6th value?
remove find inp inp/6

Find will take the first value it find so the 4th value will be removed. (Which in this case does not matter). What do you think?
xqlab
12:20remove at inp 6
Rebol2Red
12:58Thanks
inp: [5 3 8 1 2 1 12]
probe remove at inp 6 ; == [12]

So we need to do:
inp: [5 3 8 1 2 1 12]
probe head remove at inp 6 ; == [5 3 8 1 2 12]
greggirwin
17:29@Rebol2Red do ? remove in the console, and it's doc string describes its behavior.? While you're there, look at change and insert. Understanding series action/func behaviors helps enormously.
17:30Playing with small examples in the console is also very helpful.
Yamoon2018
17:56I need a document or any source of information for network protocols
greggirwin
19:35Red has basic I/O right now, which means you can read/write HTTP resources. Full I/O will come in 0.7 and then work on more protocols can begin in earnest.
Yamoon2018
19:37Basic I/O means I can open the ports to communicate with any SQL server
rebolek
19:39No, only HTTP(S) is currently supported, for SQL you would need raw TCP. You can try new IO in one of the development branches, but it's not finished yet.
Rebol2Red
20:20@greggirwin Is your post meant to be sarcastic or patronizing? Do'nt you think i do all those things after years of using Red? I am NOT a beginner.
GiuseppeChillemi
20:52@Rebol2Red it's a standard suggestion when some topics seems not clear to the counterpart. I have received it many times.
greggirwin
20:54@Rebol2Red neither sarcastic or patronizing. Sorry if it seemed that way. I don't always remember who uses Red regularly, and since it was a basic question, perhaps my suggestion will help others.
Rebol2Red
21:26@greggirwin No hard feelings. And yes i know i ask sometimes things which i have forgotten or seems easy. Probably cause of my age which is over 60 or changing from many other programming languages to Red.
Yamoon2018
21:27@rebolek , which development branch

Yamoon2018
16:16As far as I know that Red is cross platform language which means, the same code can run either under Windows, Linux, or Mac , but this code is running very well under windows while it shows error under Linux(Ubuntu), under Ubuntu 20.0 I'm using Red-064 and visual studio code
color-list: exclude extract load help-string tuple! 2 [glass set-color]

Compilation Error: undefined word help-string

So did I miss something
9214
16:32@Yamoon2018 it's not related to the cross-platform aspect, help-string is simply a console-only definition which compiler does not understand. [Here](https://gitter.im/red/help?at=5f1abb69cd7bed0e3789d6bb) is a workaround, you can also see other's solutions if you scroll the linked discussion. And besides — you are using an outdated build.
Yamoon2018
16:48@9214 , I got the building file from Red's official web site for Linux, any suggestions to solve the as I need to be sure i'm using the most recent build.
16:52What about this error ,

save file: request-file/filter ["png" "*.png" "jpeg" "*.jpg" "gif" "*.gif"] draw (canvas/size) (canvas/draw)

Compilation Error: undefined word draw
greggirwin
17:01Make sure you have needs: View in your script's header, though on Windows here I get a different error for that. *** Compilation Error: Windows target requires View module (Needs: View in the header)

If you run about/debug in the console it will tell you what version you're running.
9214
17:18> any suggestions to solve the as I need to be sure i'm using the most recent build

@Yamoon2018 use the [latest automated build](https://static.red-lang.org/dl/auto/linux/red-latest), not the stable one, and make sure that you installed the [required GTK dependencies](https://github.com/red/red/wiki/%5BNOTE%5D-Linux-GTK-dependencies#debian). The release model that Red uses and the difference between stable and nightly are described [here](https://github.com/red/red/wiki/%5BNOTE%5D-Release-model).
rebred
18:33is the thousands comma separator option built in the
money
datatype or do I have to build it with a string?
greggirwin
19:30You can use the standard group separator in the literal form, but you need to format them for output yourself (at this time).
>> USD$1'000'000
== USD$1000000.00

You can play with some pieces from https://github.com/greggirwin/red-formatting and provide feedback as well.
9214
21:30@rebred [form will put separators for you](https://github.com/red/docs/blob/master/en/datatypes/money.adoc#formatting).
>> form $1337
== "$1'337.00"
litew
21:36Is there any way to customize keyboard shortcut's in REPL? <Ctrl> + <A>, <Ctrl> + <E>, <Ctrl> + <H> shortcuts work great, but <Ctrl> + <W> (delete backward bunch of symbols until space) doesn't :(
greggirwin
21:52Thanks for the reminder on that @9214.
9214
22:10@litew you'll have to hack console sources for that I'm afraid, at least for now.
litew
23:03@9214 thank you for the hint, seems like there is no "handler" available yet for KEY_CTRL_W special key https://github.com/red/red/blob/master/environment/console/CLI/input.red#L60
9214
23:08@litew you need to add an extra switch branch inside [console-edit](https://github.com/red/red/blob/df54dcdf65cdf9dd37590225ac51aaedcd065f9a/environment/console/CLI/input.red#L379). Sounds like a good first issue to me; GUI console should also be updated though.
litew
23:32@9214 so [this](https://github.com/red/red/blob/master/environment/console/GUI/old/terminal.reds#L1181) is key switch for GUI console, right? Inside edit func

endo64
04:56@litew You've pointed to old GUI console, should it be https://github.com/red/red/blob/master/environment/console/GUI/core.red#L880 ?
Yamoon2018
07:32What is the difference between image! and binary! ??
rebolek
07:36@Yamoon2018 image! is datatype for images, binary! can hold any binary data. image! has some metadata also, like image size, you can access individual pixels easily, etc.
Yamoon2018
08:04Which is correct

photo-album: object[
    photo-id: integer!
    photo-name: string!
    photo-binary: binary!
]
OR
photo-album: object[
    photo-id: integer!
    photo-name: string!
    photo-binary:image!
]
rebolek
08:11that depends on what is the source of your photo-binary!. If it's image format Red can recognize, then image!. If it's raw data that you can't convert to an image!, then binary!
Yamoon2018
14:32Is there any documents to show the difference between Windows and Linux special for save, save-as & request-file built-in functions
greggirwin
17:05The functions should work the same from Red. If not, please chat about it in red/bugs here and report an issue if needed.
litew
18:29> @litew You've pointed to old GUI console, should it be https://github.com/red/red/blob/master/environment/console/GUI/core.red#L880 ?

Honestly I don't know where is the right place for managing kb shortcuts for GUI console atm, thank you for pointing to that area.

GiuseppeChillemi
21:03How do I get all Red instructions? words-of system/words returns me a lot of other elements. Also a way to get the words of VID dialect would be welcome.
9214
21:22@GiuseppeChillemi [this](https://gist.github.com/9214/a8d3396d1de89fd3ce95a022cc1ee330) will create a dump of Redbin symbol table for you, that is all the words/refinements/issues used by the Red runtime, as well as various internal names and keywords. Not terribly useful though, as you need to categorize them by hand.
endo64
21:22What do you mean by instructions?
21:23Is it this what you want?
ins: collect [foreach word words-of system/words [if find [function! op! action! native!] type?/word get/any word [keep word]]]
GiuseppeChillemi
21:40Thank you, while waiting for your help I have walked down the road and I have made some work:

x: words-of system/words
forall x [
	if value? first x [
		if find [function! native! action! op! routine!] ty: to-word type? get first x 
		 
		[prin [first x " : " spec-of get first x] probe ty]
	]
]

21:50While writing this code I have discovered there is no found? in Red. Why?
21:57I mean: which logic has changed in FIND and IF to remove FOUND? in Red
greggirwin
22:331) What
2) https://github.com/red/docs/blob/master/en/vid.adoc
22:36Found? is nice for use with find (and easy to write if you want it), but it's also redundant in use, because you can say if find ..., where the only value found? adds is giving you a logic result which is helpful sometimes.

pekr
06:11Gregg - it always starts like that, stating that there is no problem for users to add one liners. But it also always ends the same way - user feeling there is certain functionality missing. Another example might be forskip, which was not effectively replaced by planned fornor anything else.
Oldes
07:32@GiuseppeChillemi https://www.curecode.org/rebol3/ticket.rsp?id=2053
litew
08:55Is it possible to compile red-console on Linux with GTK support disabled (view/draw)? I'm trying to run REPL on my linux server which has no X display:

$ ./red --cli
(console-2020-10-23-64733:2326): Gtk-WARNING **: 04:51:20.558: cannot open display: 

$ cat /etc/centos-release
CentOS Linux release 7.8.2003 (Core)
09:20Nevermind :) Found --no-view option.
GiuseppeChillemi
13:04@Oldes Thanks Oldes, Curecode is still a great source of informations. I remember it being ported to GitHub but I don't find it.
endo64
14:33@GiuseppeChillemi https://github.com/dockimbel/curecode
GiuseppeChillemi
15:31@endo64 I have expressed myself incorrectly, I meant: curecode Rebol2/3 issues

greggirwin
00:16@Oldes thanks for finding that.

@pekr, sounds like you're saying I'm consistent. ;^)

If we don't have a list of things that have not been included in Red yet, but come up from time to time, let's make a wiki page (again, @pekr can point out that I'm a broken record here). There we can say why they haven't been added to Red yet, if that decision is final, and make arguments for and against.

We can argue that something isn't necessary, or we can argue that it isn't harmful. I only miss forskip rarely, but some key old code of mine uses it, so I *do* miss it, and I've noted that forall is a special case of forskip so we get it almost for free and I personally don't see it as harmful. But forall is a native now, so it's more and deeper work to make that change. When they were mezzanines, it was easy. So comes the design question of whether forall needs the speed. Maybe @9214 or @hiiamboris have seen its use where the performance makes a difference.

I put a REP for for out there, but the outcry hasn't been so great that it ever got pushed forward. It's good for people coming to Red, but I also think for other cases. Why I haven't pushed it myself has come to naming again and again. What do we call our loop constructs and how many do we need?

We also have a *lot* of design ideas out there, like format, CLI, etc. and there's just a lot to do. Bugs to fix, PRs to merge, 64-bit plans to make, blockchain work to prioritize, work that keeps us afloat, and more.

I don't ever disregard these questions, but if *you* need these things, *you* can write them today, here and now. Why do you care if they are standard in Red, unless you're thinking about the language design as a whole and long term use and compatibility for everyone who uses it? In that case, work with others to put set of standard extensions in the red/code or red/community repo.
XANOZOID
07:04Kind of banking off of "you can write them today", but in an unrelated way, how can I simulate the way foreach x [..] [..] is able to treat x as a word-literal instead of a value? I've created a function that accepts the same data types and the behavior of native foreach takes the word as-is, but a regular old func [word [word!.. ... results in type errors where foreach doesn't.
07:05foreach seems to be a special case compared to everything else I've observed
07:08I kind of saw the source code for the foreach function, it almost looks like it's doing some sort of trick with the stack
giesse
09:20
>> my-foreach: func ['word [word!] series code] [?? word ?? series ?? code]
== func ['word [word!] series code][?? word ?? series ?? code]
>> my-foreach x [1 2 3] [blah blah]
word: x
series: [1 2 3]
code: [blah blah]
XANOZOID
09:55aha! I haven't seen the semantics of a word-literal being used as a function parameter
09:55That seems to have done it :)
9214
12:19They are [documented](https://github.com/red/red/wiki/%5BDOC%5D-Guru-Meditations#literal-arguments-and-get-arguments).
XANOZOID
15:47I really don't understand what "guru meditations" means. It really doesn't sound like a spot I would find documentation for this - I'm sorry to say. Being "documented" is nice 😄, however the user experience to look there isn't quite so . . . I didn't even think this was something I could easily query and didn't take a shot.
15:48So I guess I could describe some parts of Red information as knowledge hidden behind an unknown amount of clicks, even with the wiki, so far. . .
pekr
15:55Guru meditation is famous Amiga computer error message. And author of Rebol, Carl Sassenrath, is also an author of original Amiga OS :-)

15:56http://www.geekometry.com/2013/11/amiga-guru-meditation-error-screen-wallpaper/
XANOZOID
15:58Hahaha thanks for the background!
15:58I'll finish up my thoughts here on user experience with this next part . .
15:58When I think about user experience learning a language, the best examples I have are Go and Dart. Take Go, you find yourself the "documentation" page https://golang.org/doc/. It's broken down into logical sections - but the two most important things you can find in the docs are "A Tour of Go"(https://tour.golang.org/welcome/1) and "Language Specification" (https://golang.org/ref/spec). And then there's Dart. They've got a nice technical all-encompassing spec (https://dart.dev/guides/language/specifications/DartLangSpec-v2.2.pdf) -- and a "evolving spec", but the cherry-on-top for me is there "Tour" (https://dart.dev/guides/language/language-tour) and "Samples". Where tour is a huge list of all of the features, and samples is the very high overview https://dart.dev/guides. But, as we will know, however nice the documentation, people will still always ask a question that's probably explained there anyways - because it's a "querying" problem.
16:05And as far as the actual UI/UX of both - Dart is obviously more visually "appealing", and would be difficult to maintain and mimic, but Go is actually setup really logically and still easy to follow - and certainly within a day or two's reach of work to replicate to some degree. So I don't think the examples are too out of the question to get into.
16:12I could try to do something like this if it's wanted
16:14An example of how a hosted reference can be updated on Github and displayed under a nice interface, in my opinion, would be Haxe. For example: https://haxe.org/manual/types.html -> https://github.com/HaxeFoundation/HaxeManual/blob/master/content/02-types.md#L1-L36.
greggirwin
17:03I agree that the wiki isn't true documentation (and hard to search as well). We have a long way to go with docs, and just haven't been able to allocate consistent resources to them. @gltewalt did a lot when he was around, @9214 has taken it very seriously to doc new things like money!, and also parse, which is critical. @tovim and others help with translations, which is also deeply appreciated.

If someone would like to extend the function! reference docs to include some more details that would be great.
17:05We also have a broad and deep [spec doc](https://github.com/meijeru/red.specs-public/blob/master/specs.adoc), created and maintained by @meijeru.
17:08The wiki currently links to https://www.red-lang.org/p/documentation.html for its doc section, and I see that doesn't mention Rudolf's spec, which is a massive oversight. It would be nice if the wiki could point to a page with more doc links and explanations, which can include the .org page.
17:10Moving to red/docs.
GiuseppeChillemi
19:08How could I execute a REBOL script under Red? I have tried CALL rebol.exe myscript.r on a Rebol but it has not worked
endo64
20:09@GiuseppeChillemi call/show "rebol.exe file.r"

GiuseppeChillemi
17:23@endo64 It seems Red is releasing the file I write after I quit and the consolle returns to the caller script. So, the caller one finds the file locked. I will investigate more on this topic.
endo64
20:08Since open is not supported on file!s in Red, yet, your file shouldn't be locked by Red. And write locks for a very short time, shouldn't be an issue, are you sure your Rebol script doesn't keep running in the background? Try also /wait with call.

JakubKoralewski
12:14Hello everyone. I have a question regarding structs. I found the declare struct! syntax in the specification, but I can't get it to work
>> s: declare struct! [i [integer!] b [byte!]]
*** Script Error: declare has no value
*** Where: s
*** Stack: 
>> s!: alias struct! [i [integer!] b [byte!]]
*** Script Error: alias has no value
*** Where: s!
*** Stack:

Is this Red/System only?
9214
12:17@JakubKoralewski yes, you are confusing Red/System with Red. struct! in Red is not implemented yet, and will slightly differ in its semantics from a low-level counterpart.
JakubKoralewski
12:30Thank you

bubnenkoff
07:38Is it possible to create solve next task with objects. I need to know from child who is it's parent. In my case I need to move have copy of number on name level.
o: object [
	number: 1
	object [
		name: "Apple"
	]
]


so result should be like:
o: object [
	number: 1
	object [
		number: 1
		name: "Apple"
	]
]


in pseudo-code:
o: object [
	number: 1
	object [
		number: ../number ; link to parent
		name: "Apple"
	]
]

is it possible?
toomasv
08:01@bubnenkoff I can't see any sense in creating anonymous object in context of another object, as it is lost as soon as created. But let's say you want to create child object in parent object and reference parent's field with same name as child's field. For this you can use self, e.g.:
>> o: object [parent: self number: 1 c: object [number: parent/number name: "Apple"]]
== make object! [
    parent: make object! [...]
    number: 1
    c: make object! [
        number: 1
        name: "Apple"
    ]...

Or you want to create separate object from inside another object:
>> o: object [parent: self number: 1 set 'c object [number: parent/number name: "Apple"]]
== make object! [
    parent: make object! [...]
    number: 1
]
>> c
== make object! [
    number: 1
    name: "Apple"
]

08:16And if you want your child object always contain current value of parent's field, use reactor:
>> o: reactor [parent: self number: 1 set 'c object [number: is [parent/number] name: "Apple"]]
== make object! [
    parent: make object! [...]
    number: 1
]
>> o/number: 2
== 2
>> c
== make object! [
    number: 2
    name: "Apple"
]

Although separate creation seems cleaner to me:
>> o: reactor [number: 1] c: object [number: is [o/number] name: "Apple"]
== make object! [
    number: 1
    name: "Apple"
]
>> o/number: 2
== 2
>> c
== make object! [
    number: 2
    name: "Apple"
]
bubnenkoff
08:54big thanks for examples!
09:23> @bubnenkoff I can't see any sense in creating anonymous object in context of another object, as it is lost as soon as created. But let's say you want to create child object in parent object and reference parent's field with same name as child's field. For this you can use self, e.g.:
>
> >> o: object [parent: self number: 1 c: object [number: parent/number name: "Apple"]]
> == make object! [
>     parent: make object! [...]
>     number: 1
>     c: make object! [
>         number: 1
>         name: "Apple"
>     ]...
>

> Or you want to create separate object from inside another object:
>
> >> o: object [parent: self number: 1 set 'c object [number: parent/number name: "Apple"]]
> == make object! [
>     parent: make object! [...]
>     number: 1
> ]
> >> c
> == make object! [
>     number: 1
>     name: "Apple"
> ]
>

>

There is an error on to-json on first example

>> to-json o
*** Internal Error: stack overflow
JakubKoralewski
09:48Is there a way to make an object which has a property which namee is the same as the variable:
x: 2
object [x: x]

The above returns an error.
x: 2
object [x]
09:51The second one also doesn't work, I was trying to get the shorthand property initialization like in JavaScript from es2015+
10:172 - Also is there a built-in method that can check if a char/string is a letter? I know you can do charset [#"A" - #"Z" #"a"-#"z"], but I want to cover all characters including with diacritics etc.
toomasv
11:24@JakubKoralewski Maybe use compose?
>> x: 2 object compose [x: (x)]
== make object! [
    x: 2
]


> is there a built-in method that can check if a char/string is a letter?

You'll need to build charsets for letters you want to include yourself, no builtin methods AFAIK. Charset for all letters can be huge, consult e.g. [XML spec](https://www.w3.org/TR/xml/#CharClasses) for character classes.
11:29@bubnenkoff Any strong reason not to create second object separately? Then you don't need self-referencing.
bubnenkoff
11:35heh...)) It's continue my old problem with data and lots) The idea is next. I need to insert result to DB. But for every child I need to know parent name because I need to be able JOIN data in DB.
So from:
object [
    number: 1
    object [
        name: "Apple"
    ]
]

I need:
object [ 
    number: 1 ; !
    object [
        number: 1 ; ditto
        name: "Apple"
    ]
]


it's synthetic example, but it's need to show my problem. So I need any elegant way to do it.
11:36So I am trying to understand if it's possible to solve task on data level. I mean to describe data and generate proper result. Or it's only way to write some iterator
11:38I can't do it as separate object because I need solid data structure. All other tasks with your great help I did on it
9214
13:33@JakubKoralewski WRT "characters that are letters": it sounds more sensible to create a much smaller, complemented charset (e.g. digits, punctuation, brackets, etc) and check if char! is _not_ a part of it. OTOH, it largely depends on the specific problem that you are trying to solve. Password validation?
XANOZOID
14:19@bubnenkoff That definitely shouldn't be a stack overflow. While the example uses the parent's field, it doesn't recurse or do anything stack-filling if I'm reading it correctly.
9214
14:21@XANOZOID it should, because the structure JSON codec tries to serialize is cyclic.
XANOZOID
14:23It's not cyclic - the property that the child object is pointing to does not contain a reference to itself, but the parent of the property it's pointing to does. If you show the node graph there, there's no cycle
14:24Ah my bad. [ parent: self ]
14:24Completely went over my head
14:30That's such a peculiar case. Is the behavior of red objects ever going to be changed here*? They're evaluated on creation - otherwise that would work
14:31It might be impossible or breaking behavior based on how object blocks work as is though. Since you can do stuff like object [ data: 1 print data ] and expect it to print 1
14:51@bubnenkoff anyways this should work
a: object [ parent: return object [ set 'parent self num: 1  apple: object [ num: parent/num name: "manzana" ] ]]
14:51[![image.png](https://files.gitter.im/5780ef02c2f0db084a2231b0/ySmf/thumb/image.png)](https://files.gitter.im/5780ef02c2f0db084a2231b0/ySmf/image.png)
9214
15:14> That's such a peculiar case

It's not peculiar, it's [generic](https://github.com/red/red/issues/4691#issuecomment-717934161), and is at the heart of Red as a data format.

incept: func [block][append/only insert/only block block block]

>> block: incept [we need to go deeper]
== [[...] we need to go deeper [...]]
>> block/1
== [[...] we need to go deeper [...]]
>> block/1/7
== [[...] we need to go deeper [...]]
>> block/1/7/1/7/7/7
== [[...] we need to go deeper [...]]
>> block =? block/1/7/1/7/7/7/1/1/1
== true


> Is the behavior of red objects ever going to be changed here*?

Objects simply hold values associated with symbols. How these values get there is up to the user: the common case is usage of object constructor. If you don't want evaluation, use construct.
XANOZOID
15:31> Objects simply hold values associated with symbols

Yeah - but only on creation. IE: num: parent/num does not work here like it would in a "generic" block.
15:32That's why I say it's peculiar
15:35It's like, not actually that it holds the value associated a with a symbol as much as it just holds the value a symbol evaluates to during the time it's written. Its semantics are definitely not like blocks at all. I'd say the semantics of object are peculiar, although necessary for what they actually are, compared to the far more general idea of a sequence. Further - until objects are extensible past creation, I'd say they're much less general than they _could_ be.
15:42Ah I misunderstood what you said. Yeah the symbols of the new "object" now have a value associated with them. That's pretty standard. What I said doesn't really apply to what your response was, but it does make the context behind what I said more clear.
greggirwin
17:56You can create graphs without issue. They are just values (nodes) that refer to other values. When you *evaluate* them, that's when decisions have to be made. Either the evaluator knows cycles may exist, and accounts for handling them, or it doesn't and bad things happen if cycles exist because it goes in circles (or down wihrlpools). That means you can't have an evaluator that isn't cycle aware serialize structures with cycles. It can't know what to do when it encounters them.
XANOZOID
20:30Yes graphs and cycles aren't the issue - but the order of evaluation of Red does not have a special case for object declaration - which for the purpose of doing this:
example: object [ a: "hello" print example/a ]

Is simply not a supported order of operations. At least not without our own adaptions. And it's a little tricky to conserve existing functionality given the code I provided earlier - where you can actually "return" from a object-block.
However - their should be a way to get around this without shipping our own layer over object - or without the several bits of needed logic I showed earlier to sort of "get around it".
`
greggirwin
21:45I don't see how that example could work. You're referencing the object before it's been created.
XANOZOID
22:27As it is, this example and the evaluation rules, it definitely can't work. However, I just have a hypothetical approach to it. I can post some idea in a few
GiuseppeChillemi
22:39Is there a way to connect an object with functions to a Red value and use them via path syntax? I would like to do things like mypic: load %image.jpg connect the management object and run functions on it via path likemypic/size (to get size), mypic/resize 3000x2000, mypic/sharpen, mypic/blur 22. But if you want just to get or set the value you can use the standard single word Get/Set notation.
greggirwin
22:50@GiuseppeChillemi Nope.
XANOZOID
22:50@GiuseppeChillemi To my understanding you wouldn't be able to change the underlying structure of the value for "mypic" -- but you could always modify "mypic" itself to be usable the way you describe. . . It would operate over the loaded image and all, it just wouldn't extend the image's actual functionality
22:51By modify I mean just make an object that has the contract you're describing and make it apply to the image data. Probably not a good idea in the end.
greggirwin
22:52If you look at the datatype code in Red, you'll see that each type may have an eval-path function, which is how this works today. You can, of course, write your own system to do this with just a little extra syntax needed at the user level.
XANOZOID
22:56This is pretty much what I thought could be possible, but probably optimized with red/system:

as-obj: make op! func ['a b] [ set a object append copy [ set a self ] b ]
parent: as-obj [ num: 1 child: as-obj [ num: parent/num name: "apple" ] ]

results in:
make object! [
    num: 1
    child: make object! [
        num: 1
        name: "apple"
    ]
]

22:56Basically make this possible using a bit of trickery with operations
greggirwin
23:02We can bend Red to our will in unimaginable ways. :^)
23:03At least until they are imagined.
XANOZOID
23:10It works! :) But is this not something we'd want? It's probably a little too hacky to really be put into public . . . and for a very specific use-case. However, I do find it useful - and because it's combinable with "set-word" child actually becomes a member of the parent object. It's pretty interesting . . . And yes - I love Red :)
23:11I'm still planning on making a LLVM IR target, or will start to, when December starts :)
GiuseppeChillemi
23:27> If you look at the datatype code in Red, you'll see that each type may have an eval-path function, which is how this works today. You can, of course, write your own system to do this with just a little extra syntax needed at the user level.

It is a datatype level, so a general one.

I am thinking having it at context level for each value
;---------------------------------------------
SYMBOL | Value | Connected Object
;---------------------------------------------

To avoid conflicts with normal path notation we can use a mypic//sharpen notation (or any other usable one) to access the connected object.
greggirwin
23:41@XANOZOID I can only speak from my own experience and the history I know of Redbol users. From that perspective, I've never needed it and I don't remember it coming up as a feature request. @giesse 's examples are the first I can recall seeing. That doesn't mean I haven't hacked my way around it, or that others have; I just don't remember it being an issue.

In general I favor simplicity, and if Red lets you solve problems, it's not a show-stopper. The question is how much we gain, and what we give up in return. Your as-obj op is clever, but could lead to confusion with how as works since they share a base name. It's also a very general same with specific semantics. Then consider if we want to use ops with lit args and set-words on the left as standard. I like that there aren't many ops, they are generally clear by their distinct symbols, and are therefore more obvious in their effect on evaluation order.

On naming, if you were to write a func that does what you want, what would you call it, and what would you use for its doc string?
GiuseppeChillemi
23:57@XANOZOID the goal of the idea is to have a management object for structures which can accommodate complex data like blocks, images and everything else. In this way, every data can have its own vocabulary of words, function to query and/or manipulate itself and act like new datatype.
XANOZOID
23:59@greggirwin I will think about this! I ultimately don't find it too necessary . . . it still looks a little funny to me and I'm not sure if I'd ever need this too :). If anything, I'd probably want a better more general alternative.

XANOZOID
00:00@GiuseppeChillemi Interesting. The way you described it made me think it's like some sort of decorator pattern you're trying to conceptualize
GiuseppeChillemi
00:12In Red we have the context of a word but we do not have a context for a container value. In this context could reside all the management functions and calculated properties of the value. Red already has a sort of inaccessible meta language with action words which are common to all datatypes. With a connected object you can have such kind of custom handler object at user level with its own vocabulary.
00:14A special word like myval could be reserved to access the connected value from the connected object functions.
05:47Thinking on what I have written after 4 hours of refreshing sleep. My example table is a context entry with a connected object to it. To have it at value level, it should be rapresented out of contex, otherwise it is at context word level.
JakubKoralewski
11:14is there a way to create a drag and drop feature with Red currently?
11:17[nvm](https://github.com/red/red/pull/2838) seems like not possible yet
toomasv
11:29@JakubKoralewski Please be more specific - drag what, drop where?
JakubKoralewski
11:30drag a file into some widget and get the path/file from some actor event in the widget
as I said though seems not possible red/red#2838
GiuseppeChillemi
13:05Is there a way to set transparency to one or more elements of the gui and have it always on top?
13:14@XANOZOID it was really late and maybe I have not properly expressed myself. I want to attach functions and calculated properties to a container element without using an object. The best would be of we can override the Red builtin set/get too so that it would work like a custom datatype but at word/value level.
XANOZOID
14:56@GiuseppeChillemi Hmm. If you figure out a good way to do that dynamically let me know haha . . . I've yet to figure out how to work around objects not being extendable . . .
GalenIvanov
14:59Hi! I started learning Red/System and I have troubles returning a struct by value from a function. I'm definately making some stupid mistake, that's why I need help.
14:59
Red/System[]

Color!: alias struct! [
    r [byte!]
	g [byte!]
	b [byte!]
	a [byte!]
]

make-color: func [
    r [integer!]
	g [integer!]
	b [integer!]
	a [integer!]
	return: [Color! value]
	/local color
][
    color: declare Color!
    color/r: as byte! r
	color/g: as byte! g
	color/b: as byte! b
	color/a: as byte! a
	color
]

green: declare Color!
green: make-color 0 255 0 255
probe as integer! green/r
probe as integer! green/g
probe as integer! green/b
probe as integer! green/a

magenta: declare Color!
magenta: make-color 255 0 255 255
probe as integer! magenta/r
probe as integer! magenta/g
probe as integer! magenta/b
probe as integer! magenta/a
14:59The result of this code is:
15:00
0
0
0
0
255
0
0
0
15:01An not 0 255 0 255 / 255 0 255 255 255. What I'm doing wrong?
XANOZOID
15:04I can't quite say - I'm looking at how I've done mine in the past and I was doing things kind of wonky because I was working around things that weren't working how I expected
15:04However this is what I got
15:04
red

RayColor!: alias struct! [
    r [byte!]
    g [byte!]
    b [byte!]
    a [byte!]
]


set-color: func [
    color [RayColor!]
    r g b a [integer!]
][
    color/r: as-byte r
    color/g: as-byte g
    color/b: as-byte b
    color/a: as-byte a
]

gray: declare RayColor! set-color gray 200 200 200 255
15:04This seemed to work for me
GalenIvanov
15:05@XANOZOID Thank you, I'll try it
15:09Yes, it works just fine, thanks again!
15:12So you are changing the colors in place, whereas I was trying to assign the color a newly created struct.
XANOZOID
15:14Try your code without the value in your return statement
15:16[![image.png](https://files.gitter.im/5780ef02c2f0db084a2231b0/C5A8/thumb/image.png)](https://files.gitter.im/5780ef02c2f0db084a2231b0/C5A8/image.png)
15:16I got this with our code if I removed "value" from the return
GalenIvanov
15:16Hmm, I think I tried it like this, but apparently I wasn't.
XANOZOID
15:17I'm just as surprised as you are on my end since I thought I did a while back too 😅
9214
15:18> I have troubles returning a struct by value from a function.

You are allocating struct on the stack, which then disappears as soon as make-color finished off and returned to the caller. What you are probing then is a random junk off the stack.
Red [Note: "compile with -r -d flags"]

#system [
	color!: alias struct! [
		r [byte!]
		g [byte!]
		b [byte!]
		a [byte!]
	]

	make-color: func [
		r [integer!]
		g [integer!]
		b [integer!]
		a [integer!]
		return: [color! value]
		/local color
	][
		color: declare Color!
		color/r: as byte! r
		color/g: as byte! g
		color/b: as byte! b
		color/a: as byte! a
		dump4 color
		color
	]

	green: declare color!
	green: make-color 0 255 0 255
	probe as integer! green/r
	probe as integer! green/g
	probe as integer! green/b
	probe as integer! green/a
]

Hex dump from: 004CE4ECh

004CE4EC: FF00FF00 00401003  0000004C 001D7CC0  .?.???@.L...?|?.
004CE4FC: 00401003 0000004C  001D7CC0 00401003  ??@.L...?|?.??@.
004CE50C: 0000004D 001D7CC0  00401003 0000004D  M...?|?.??@.M...
004CE51C: 001D7CC0 00401003  0000004E 001D7CC0  ?|?.??@.N...?|?.
004CE52C: 00401003 0000004E  001D7CC0 00401003  ??@.N...?|?.??@.
004CE53C: 00000050 001D7CC0  00401003 00000050  P...?|?.??@.P...
004CE54C: 001D7CC0 00401003  00000052 001D7CC0  ?|?.??@.R...?|?.
004CE55C: 00401003 00000052  001D7CC0 00401003  ??@.R...?|?.??@.
0
0
0
0

See the FF00FF00 part? That's your struct.
XANOZOID
15:20:) I understand how that works in C, wasn't sure what the semantics of a "value" return in Red/System are haha. I need to find that C -> Red/System cheat sheet floating around
GalenIvanov
15:23@9214 Thank you for your explanation!
XANOZOID
15:33@9214 Did you do something Red specific to get that Hex dump 😄?
GiuseppeChillemi
17:09> @GiuseppeChillemi Hmm. If you figure out a good way to do that dynamically let me know haha . . . I've yet to figure out how to work around objects not being extendable . . .

Object will be extendable in the future Vladimir has expressed this sometime and I believe in his words.
17:18> @GiuseppeChillemi Hmm. If you figure out a good way to do that dynamically let me know haha . . . I've yet to figure out how to work around objects not being extendable . . .

I am far from being able to modify the core of Red but I am sure I'll experiment with this in the future because I have a lot of passion for inventing and exploring the many different opportinuties Red gives us. Currently, I see it easily possible at Datatype level or at context level, but tied to the word and not to the value (and you must "clear" the connection when the value changes). Otherwise, (and I risk saying a lot of stupid things here) the object can be connected at cell level, in the additional space you can allocate.
XANOZOID
17:52@GiuseppeChillemi Yes, I'm certainly aware it'll come eventually :). Until then - it's a challenge assuming you're not going to wait!
GiuseppeChillemi
21:09@XANOZOID you can always use it as prototype, clone and extend it and rebind the interested code blocks.
XANOZOID
22:44@GiuseppeChillemi not necessarily practical since objects are not words and the words that hold them aren't easily capturable. At least I can't imagine as such.

GiuseppeChillemi
04:33@XANOZOID could you extend your thought?
Rebol2Red
12:11
printout: function [
    items
][
    len: length? items
    if not (len = 0) [
        repeat i len [
            case [
                len = 1         [print items/1 return ""]
                i < (len - 1)   [prin rejoin [items/(i) ", "]]
                if i = len      [prin rejoin [items/(i - 1) " and " items/(i)]]
            ]
        ]
        print []    
    ]
]

printout ["1" "2" "3" "4" "5" "6"]  ; 1, 2, 3, 4, 5 and 6
printout ["1" "2"]                  ; 1 and 2
printout ["1"]                      ; 1
printout []                         ; no printout

I don't like my function. There must be a better way.
rebolek
12:24I don't know if it's a better way, but here's an attempt:
printout: func [series][
        print rejoin collect [
                forall series [
                        keep first series
                        keep case [
                                tail? next series [""]
                                tail? skip series 2 [" and "]
                                'else [", "]
                        ]
                ]
        ]
]
Rebol2Red
12:39@rebolek Nice, thanks. btw: I get a newline at printout []
Maybe some more input?
rebolek
12:48hm, empty block would need an exception at the beginning: if empty? series [exit] or something like that
Rebol2Red
13:01@rebolek Exactly like that.
Maybe someone has other ideas? Maybe with insert, append or ...? Pointing in the right direction will be enough. Thanks in advance.
13:13@rebolek Is using true instead of 'else not more conventional?
I wonder what the meaning of using 'else is anyway? A fancy name for replacing true? If so nice find!
rebolek
13:19I used true in the past but some people prefer 'else as it is probably more readable. You can put anything true-y there:
>> case [make error! "error is fine" [print "ok"]]
ok
>> case [make logic! 'false [print "ok"]]
ok
>> case ['switch-to-this-branch-and-shoggoth-will-eat-your-soul [print "ok"]]
ok
Rebol2Red
13:27@rebolek And indeed it is more readable. Learning something every day. Many thanks for taking the time to explain. I really appreciate it.
toomasv
13:35@Rebol2Red I recall having done [something similar](https://gist.github.com/toomasv/fd651f24e18d7bc85d05204cc5f828d2).
Rebol2Red
15:24@toomasv Nice! Thanks.
XANOZOID
16:00@GiuseppeChillemi It's not unlike you already know! I was simply saying yes, you must re-contextualize everything you care about . . . which means plenty of book-keeping haha . . . But I'm pretty sure it can't be automated - it being understanding what words need to be fixed again
9214
16:13
text
enlist: function [list [block!]][	
	forall list [
		this: make integer! head? list
		that: make integer! tail? next list
		flag: 1 + or~ this that << 1
		
		prin [pick ["," "^/" " and" "just"] flag :list/1]
	]
]
Rebol2Red
19:38@9214 Nice, but the output is not the desired one
enlist ["1" "2" "3" "4" "5" "6"] 
enlist ["1" "2"]   
enlist ["1"]                     
enlist []

output:
1, 2, 3, 4, 5 and 6
1 and 2just 1
9214
19:41"^/just".
Rebol2Red
19:43@9214 There is also a newline in the output just before 1, 2, 3, 4, 5 and 6. Why?
Oldes
22:25This one is faster and less cryptic:
enlist2: function [series][
	out: clear ""
	unless empty? series [
		forall series [
			append out first series
			append out case [
				tail? next series   [  ""   ]
				tail? skip series 2 [" and "]
				'else               [ ", "  ]
			]
		]
	]
	copy out
]
22:45or this one for direct output and with just and none:
enlist3: function [series][
	if empty? series [print none exit]
	if tail? next series [prin "just "]
	forall series [
		prin first series
		prin case [
			tail? next series   [""     ]
			tail? skip series 2 [" and "]
			'else               [", "   ]
		]
	]
	prin lf
]
22:58But I believe, that it is better not to use direct output, so I would and with this one:
enlist4: function [series][
	if empty? series [return copy "none"]
	out: clear ""
	if tail? next series [append out "just "]
	forall series [
		append append out first series
		switch/default  length? series [
			1 [""     ]
			2 [" and "]
		][     ", "   ]
	]
	copy out
]
23:00which can be still reduced to:
enlist5: function [series][
	if empty? series [return copy "none"]
	out: clear ""
	if tail? next series [append out "just "]
	copy forall series [
		append append out series/1
		switch/default length? series [
			1 [""     ]
			2 [" and "]
		][", "]
	]
]
23:04@rebolek when I see source of collect, I would not use it in functions where performance is appreciated.
greggirwin
23:12This is a great problem with lots of edge cases. Good for different approaches. Yours are great @Oldes. I can't see performance being an issue for this use case though. Certainly something we can profile, and write up, to help guide people to the clearest solutions that meet their performance needs in different circumstances.
XANOZOID
23:40This should also be a nice solution
enlist: function [x] [
    n: ["None" ["Just" x/1] [x/1 "And" x/2] [ loop l - 1 [ append x reduce [take x ","] ] "and" take x ] ] 
    print n/(min 4 1 + l: length? x)
]
Oldes
23:48It does not have correct result.. it outputs: 1 , 2 , and 3
9214
23:48And modifies the original x in-place.
XANOZOID
23:49You can fix those easily :)
23:49length? x: copy x
23:49and just use string appending instead of block appending for the last part
greggirwin
23:57But look how clear @Oldes' versions are. Aside from the append append bit.

XANOZOID
01:45Okay - then lets try for reducedness *and* readability . . . While also being correct and not self-modifying.
enlist: function [x] [
    cases:[ "None" ["Just" x/1] [(
        prin take x: copy x
        loop len - 2 [prin["," take x]]
        prin [" and" x/1]
    )]]
    print cases/(min 3 1 + len: length? x)
] 
; tests
enlist x: [] loop 5 [ enlist append x length? x ]


I think that's pretty readable! Less code, no more than a conditional as a loop. . . It's essentially a less "intentionally" obvious switch, to be fair.
greggirwin
05:17Readable is (always) in the eye of the beholder. :^) I had to reformat it to understand it.

What's nice about it is treating the cases as data and dispatching against that. But it also has a cost because they are inextricably tied to the logic that comes after, where len is set and the calc to their index for dispatching is non-obvious. Comments would help. ;^)
giesse
10:19another variation:
enlist: function [block] [
    switch/default length? block [
        0 [form none]
        1 [rejoin ["just " first block]]
        2 [rejoin ["" first block " and " last block]]
    ] [
        output: copy ""
        append output first block
        last-value: take/last block
        foreach value next block [
            repend output [", " :value]
        ]
        repend output [" and " :last-value]
    ]
]
greggirwin
16:43Nice. I like this one a lot.
Oldes
17:51But it modifies the input block. And also repend is quite expensive function.
greggirwin
17:58Here, this version doesn't modify the input block:
enlist: function [block] [
    block: copy block
    switch/default length? block [
        0 [form none]
        1 [rejoin ["just " first block]]
        2 [rejoin ["" first block " and " last block]]
    ] [
        output: copy ""
        append output first block
        last-value: take/last block
        foreach value next block [
            repend output [", " :value]
        ]
        repend output [" and " :last-value]
    ]
]

b: [1 2 3]
enlist b
17:59And are you *really* concerned about performance for this particular function?
Oldes
18:36I'm not concerned at all.. as I never needed it yet, but it is a funny game to search for so many solutions.
18:47
enlist: function [block] [
    switch/default length? block [
        0 [form none]
        1 [rejoin ["just " first block]]
    ] [
        output: clear ""
        forall block [
            append output block/1
            if 2 = length? block [
            	return copy append append output " and " block/2
            ]
            append output ", "
        ]
    ]
]
18:57It's a shame there is not delta-profile function in Red like in Rebol3 to play this game;-)
greggirwin
giesse
19:40ok, then: (just small change over Gregg's)
enlist: function [block] [
    switch/default length? block [
        0 [form none]
        1 [rejoin ["just " first block]]
        ;2 [rejoin ["" first block " and " last block]]
    ] [
        output: copy ""
        append output first block
        last-value: last block
        foreach value copy/part next block back tail block [
            repend output [", " :value]
        ]
        repend output [" and " :last-value]
    ]
]
greggirwin
19:40[profile](https://gist.github.com/greggirwin/908d44dc069ed84cf69f053e1308390d)
giesse
19:40(the 2 case is not really necessary indeed)
19:41one could avoid the copy by looping with while for eg., or forall and breaking out before the tail
XANOZOID
20:43This is very fun!
20:43I have another shot :). No modifying the data at all anymore!
enlist: function [x] [
    print pick [ 
        "None" 
        ["Just" x/1]
        [(repeat i l - 2[prin x/:i prin ", "] x/(l - 1)) "and" x/:l]
    ] (min 3 l: length? x)
]
20:48While writing that - I feel like "loop" makes more sense with repeat's semantics, and vice-versa . . . Since I've seen it that way in some "basic" dialects :) but honestly really just an observation nothing more than that
20:49It's bad (actually good haha) when a language is more fun than other work :P

luce80
15:26Nice game. It's my turn. Derived from @Oldes:
printout: func [items][
	forall items [
		switch/default length? items [
			0 [exit]
			1 [print first items]
			2 [print [first items "and" last items] exit]
		] [prin first items prin ", "]
	]
]
printout ["1" "2" "3"]
printout ["1" "2"]
printout ["1"]
printout []
XANOZOID
16:23Ahh, I like that one a lot!
greggirwin
18:13We call this game "The Red Optimizer". :^) These are getting so concise!

@XANOZOID, watch out for l as a variable name, as it can look a lot like 1 or I, depending on the font.
18:16I was going to play as well, but have other coding fun on my list when I can make time.
addos
18:19hi, when using print function, how do you control what characters it uses for newline?
XANOZOID
18:25@addos do you mean how do you print a newline? Like print "line 1.^/line2" ? Or how to print ^/? (which would be print "^^/"). . .
Otherwise, I'm not aware of any way to change the standard escaping codes, in print, other than creating your own function that sets your string up to match what print expects
18:29@greggirwin Hahaha it's fun for sure 😄 - learned a few tricks and that last one posted got me thinking for sure! Ahh yes, good catch on l :)
addos
18:29yeah, I want to print \r\n instead of \n
XANOZOID
18:31@addos maybe print "^(13)" ?
18:3213 is the carriage return code, and the ^(#) syntax seems to print out based on character code in there
greggirwin
18:32CRLF is built in as standard, or you can include just the CR, but print is a native, so not easy to patch. Easy to wrap though.
18:32#"^M" is CR.
XANOZOID
18:33If we were on discord I'd be giving lots of thumbs ups - definitely useful for me to remember these
greggirwin
18:33@XANOZOID char codes use hex notation, just FYI. Do you'd want #"^(D)"
XANOZOID
18:34Ahh, also very good to know. Thanks, Gregg!!
greggirwin
18:34? char! will show you all the built-in char values.
18:47OK, I had two thoughts on the example we're all playing with. One is more involved, but this one was quick to do:
enlist: function [block] [
    switch/default length? block [
        0 [form none]
        1 [rejoin ["just " first block]]
    ][
        block: reverse copy block
        output: rejoin [block/1 " dna " block/2]
        foreach value skip block 2 [repend output [" ," :value]]
        reverse output
    ]
]
print enlist []
print enlist [1]
print enlist [1 2]
print enlist [1 2 3]
print enlist [1 2 3 4 5 6]

This isn't going to win any code obfuscation contests, and it's not a "real" solution for this, but more than once I have done the reverse trick to make certain processing easier. The fact that this has a couple subtle gotchas makes it fun.
18:49You could also walk the block backwards and use insert. That would be another approach.
XANOZOID
18:59Nice use of reverse there - makes for some pretty concise logic! And yes I can kind of see where you can take that . . . definitely could do some tricks there
GiuseppeChillemi
19:12My parse version:

enlist: func [list /local position element] [
	parse list [
		 any [position: any-type! (
				element: first position
				case [
			 		head? position [prin [element]]
			 		last? position [print [" and" element]]
			 		true [prin ["," element]]
				]
		 	)
		 ] 
	]
]

XANOZOID
19:19Interesting! Never thought about using parse . . . should definitely be explored further for its declarative features :)
GiuseppeChillemi
19:37I am currently experimenting with using parse in place of foreach/forall for row-oriented structures. The advantage is you can easily parse and identify elements in complex field/row structures and execute code, either at element (field) level and/or row level. It's a nice journey.
greggirwin
19:39@GiuseppeChillemi nice!
GiuseppeChillemi
19:40Thank you, It's nice what Carl before and now you are making possible with Red!
XANOZOID
19:47it kind of reminds me of pattern matching in other languages :). Except more flexible!
greggirwin
20:00Block parsing is so much more powerful, because you can match on specific values or datatypes.
GiuseppeChillemi
21:56Another version, more coincise, based on foralland with no /local

enlist: func [list] [
	forall list [
 		prin rejoin [
 			first list
 			case [	 				
	 				(length? list) > 2 [", "] 
	 				last? next list [" and "] 
	 				last? list [lf] 	
	 		]
	 	]
	] 
]

;----------- TESTS ------------------------------------------
enlist ["1" "2" "3" "4" "5" "6"]  ; 1, 2, 3, 4, 5 and 6
enlist ["1" "2"]                  ; 1 and 2
enlist ["1"]                      ; 1
enlist []                         ; no printout
greggirwin
22:13Also very nice. Much like a couple of @Oldes' I think. And the different approaches show the value of different functions. e.g. forall vs foreach vs repeat.
GiuseppeChillemi
22:13(note: for some strange reason, while copying and pasting to gitter, something has translated LF to OFfor 2 times! )
22:14@greggirwin We all have created different solutions. Red is so flexible that let everyone build its own style.
greggirwin
22:15For general observers, note that this version has rejoin inside the loop, so it's a heavier on allocations.
GiuseppeChillemi
22:29It's needed because another space would have been printed by prin
greggirwin
22:33Yes, which could also be done by printing in two separate steps. e.g.
enlist: func [list] [
    forall list [
        prin first list
        prin [
             case [                     
                     (length? list) > 2 [", "] 
                     last? next list [" and "] 
                     last? list [lf]     
             ]
        ]
    ] 
]
22:34Though now we might be back to @Rebol2Red's original. :^)
GiuseppeChillemi
22:39It was my first version but I have not liked the double prin.
greggirwin
22:40I like how it makes clear that the first list item (on each pass) is always printed, and then optionally some separator.
GiuseppeChillemi
22:44Yes, I think too but my goal was to make it concise... which is often synonymous of *obfuscated*.
22:44😁

toomasv
05:33One more with forall:
enlist: func [list][
	switch/default length? list [
		0 ["None"] 
		1 [append "Just " list]
	][
		list: next list 
		forall list [
			list: insert list pick [" and " ", "] last? list
		] 
		rejoin head list
	]
]
06:04Almost same
enlist: func [list][
	case [
		empty? list ["None"] 
		single? list [append "Just " list]
		'else [
			list: next list 
			rejoin head forall list [
				list: insert list pick [" and " ", "] last? list
]]]]
XANOZOID
06:20This reminds me of what I really wanted to do earlier :). . . I couldn't quite get it right since I kept causing some sort of infinite loop haha
toomasv
06:54But this is deficient in some cases, e.g.:
>> enlist [%a %b %c]
== %"a, b and c"
>> enlist [<a> <b> <c>]
== <a, <b> and <c>>
>> enlist [#a #b #c]
== "a, b and c"
>> enlist [a b c]
*** Script Error: a has no value

Here is a more robust one:
enlist: func [list][
	switch/default length? list [
		0 ["None"] 
		1 [rejoin ["Just `" mold first list "`"]]
	][
		out: head clear at "`" 2
		append out mold first list
		list: next list
		forall list [
			append out pick ["` and `" "`, `"] last? list
			append out mold first list
		]
		append out "`"
	]
]

>> enlist [%a %b %c]
== "`%a`, `%b` and `%c`"
>> enlist [<a> <b> <c>]
== "`<a>`, `<b>` and `<c>`"
>> enlist [#a #b #c]
== "`#a`, `#b` and `#c`"
>> enlist [a b c]
== "`a`, `b` and `c`"

GalenIvanov
08:02Nice to see all these solutions! This revived in me an idea I had back this summer (inspired by Dyalog APL Problem Solving Competition) - to have a problems solving competition in Red. Maybe it's too early for such an event, but I think it can spread the Red popularity further.
bubnenkoff
15:10How are you doing refactoring of Red code? it's very easy to make very hard to find error with Red
XANOZOID
15:25@GalenIvanov I remember a long time ago a website I was on for code competitions* had "Holiday" events . . . I joined a "New Years" event and was on it for 4 hours trying to get/stay in the top 10 haha
15:25It's always very fun :)
15:31@bubnenkoff Practice makes perfect . . . there's no better guide than trying it out for yourself! But there's really no guide, just takes experience and getting comfortable with your language of choice I guess. Common procedure is to start from a point that works and see what you can string together and swap out to keep it working while making your code more precise. That's all I can say I suppose
bubnenkoff
18:30is there any way to detect unused\hangling words in project or error with setting words value from function without /external modificator?
TimeSlip
19:39I have a question about how the Red compiler works. I am getting a compilation error during the compiling to native code process "invalid definition for function." Would the compiler be "Smart enough" to know that there was something wrong with my struct! definition? Say, for example that my struct! has within it references to other struct!'s that I haven't yet defined? BTW, I am attempting to bind another library but this one is much more complicated. Hope my question makes sense. @9214 I need your expertise!
9214
20:07@TimeSlip are we talking about Red or Red/System compiler? Can you give me a minimal example that produces that error?
20:13> my struct! has within it references to other struct!'s that I haven't yet defined

If you mention them without giving any definition then the compiler has nothing to work with and rightfully complains. If you mean cross-references, then they should be allowed:

foo!: alias struct! [bar [bar!]]
bar!: alias struct! [foo [foo!]]
TimeSlip
20:18@9214 Red compiler. Inside the #system [] I have MYSQL_RES!: alias struct! [ row_count [integer!] fields [integer!]... and inside the #import block and the dll block I get no errors. It happens when I try to declare the routine and use the MYSQL_RES!
20:18red_mysql_store_result: routine [ MYSQL [integer!] return: [MYSQL_RES!] /local res [MYSQL_RES!] ][ res: mysql_store_result MYSQL res ]
9214
20:21@TimeSlip well, routines are supposed to return Red values, not arbitrary structs that you have defined yourself. To put it another way: there's no mysql_res! datatype. Keep in mind that routine has spec of Red (like any other function definition) but body of Red/System.
TimeSlip
20:28OK, @9214 I was looking at [Rebolek's binding](https://github.com/rebolek/user.reds/blob/master/substring.reds) as an example. I will further investigate what I am doing wrong. Thank you so much for the help.
20:29Back to work...
9214
20:30@TimeSlip but that's not a library binding, just a handful of Red/System definitions.
20:31In your case you need to convert res content to some existing Red value, say, a block of integers, one per field (if they are all integer!s), or a raw binary! dump.
20:38For example:
Red []

#system [
	foo!: alias struct! [
		a [integer!]
		b [integer!]
		c [integer!]
	]
]

bar: routine [return: [binary!] /local foo][
	foo: declare foo!
	foo/a: DEADBEEFh
	foo/b: FACEFEEDh
	foo/c: CAFEBABEh
	
	binary/load as byte-ptr! foo size? foo
]

probe reverse bar ; little-endian order

$ example
#{CAFEBABEFACEFEEDDEADBEEF}

TimeSlip
22:12@9214 Thank you. Ah, I think I see what you mean now. And in looking closer at the documentation for the API function, I see that it returns a pointer to the MYSQL_RES struct. I guess I need to figure out how to handle the struct then from the point of receiving the pointer to it. Again thanks for pointing out how this stuff actually works.
greggirwin
22:16@Oldes have you done this in any of your bindings, to give @TimeSlip a head start?
TimeSlip
22:19@greggirwin Thanks. Right now it's a wall that I'm trying to climb over that incorporates a lot of little and big things I don't really understand.
Oldes
22:27All I did is in the [red/code](https://github.com/red/code/blob/master/Library) repository. I was not working too much on Red side.. mostly on Red/System side.
greggirwin
22:28It builds character. ;^)
22:28Thanks @Oldes. Do you remember anything that returns pointers to structs?
Oldes
22:29You mean handles?
greggirwin
22:29Sounds like an actual pointer from what @TimeSlip said. Not an opaque OS resource ID.
Oldes
22:33I think that all my experiments were in a form of a dialect, where the set-word! was used to receive the handle of specified type, which was linked with internal resources.
greggirwin
22:33OK, thanks.
TimeSlip
22:33Could be handles and thanks. Let me fool around some more.
Oldes
22:35Something like: https://github.com/red/code/blob/master/Library/Bass/bass.red#L23-L43
22:37You can [see](https://github.com/red/code/blob/master/Library/Bass/bass.red#L796-L822) that for example in Bass I have just 3 routines... where all are using single internal do function.
22:42I don't think I was ever using a routine which would return direct Red values.. mostly because that was never well documented. I just learned how to use the set-word from inside the dialect to store results.
endo64
23:10Here is my enlist function, optimized for values without spaces :)
enlist: func [list /local pos] [either pos: find/last form list { } [head replace pos { } { and }] [form list] ]

>> enlist ["1" "2" "3"]
== "1 2 and 3"
>> enlist ["1" "2"]
== "1 and 2"
>> enlist ["1"]
== "1"
>> enlist []
== ""
>> enlist ["1" "2" "3 or 4"]
== "1 2 3 or and 4" ;)
TimeSlip
23:10@Oldes Thank you. I'll be back with a better way of asking my question.
9214
23:21@TimeSlip why do you need to expose that pointer at the Red layer? It's an implementation detail.
23:24Think how View handles it: Red/System binds names to functions in the library, but VID provides a dialected interface on top of that, without boggling down the user with low-level details of a specific backend. As I said earlier, it makes no sense to create a fine-grained binding with one routine per each function.
TimeSlip
23:36@9214 I'm not at all sure I simply want to get the function in the library to work. I think my method of presenting my problem is not good so I'm probably confusing everyone.
9214
23:38Alright, if you want to check if the binding works, why bother with routines at all? Work at a pure Red/System level, that's simpler and much faster.
TimeSlip
23:52@9214 A great question and I'm afraid I don't know enough to know the difference. But here is my situation (Apologies for the length and form)
23:52I am trying to have Red access the libmySQL.dll.
So far I am able to using routines, initiate a MySQL session, open a db, Send a SQL statement (As a test I am sending {show tables}. I ask and get a row count of 10 which is correct.
But now I want to actually see the results.
There is a function:
mysql_store_result() MYSQL_RES *mysql_store_result(MYSQL *mysql)

The MYSQL_RES struct is:
typedef struct MYSQL_RES { my_ulonglong row_count; MYSQL_FIELD *fields; struct MYSQL_DATA *data; MYSQL_ROWS *data_cursor; unsigned long *lengths; /* column lengths of current row */ MYSQL *handle; /* for unbuffered reads */ const struct MYSQL_METHODS *methods; MYSQL_ROW row; /* If unbuffered read */ MYSQL_ROW current_row; /* buffer to current row */ struct MEM_ROOT *field_alloc; unsigned int field_count, current_field; bool eof; /* Used by mysql_fetch_row */ /* mysql_stmt_close() had to cancel this result */ bool unbuffered_fetch_cancelled; enum enum_resultset_metadata metadata; void *extension; } MYSQL_RES;

**And this is where I am stuck. How do I set up a routine where I can get this to work?**
23:54Up until now, I've only had to deal with pointers, integers and strings.

9214
00:03I'm not familiar with MySQL, but my gut tells me that you need to iterate over MYSQL_ROWS and peek at its content.
00:07Quick googling gave me [this](https://www.informit.com/articles/article.aspx?p=30494&seqNum=6), which I think you should try and port to Red/System: get the result set (your mysql_res! struct), call mysql_fetch_row on it within a loop until it returns a null, and within the body of that loop iterate over row's fields and pretty-print them.
TimeSlip
00:08@9214 I tell you, the best I can get out of the mysql_store_result is to have it return a pointer, which it does, but which is still a mystery to me as to what else I can do. :-(
9214
00:09mysql_store_result returns you a struct, or rather a pointer to it, which is the same. From when on you can do whatever you want with it.
TimeSlip
00:10@9214 We're on exactly the same page now! What I don't know how to do is set up the struct! so that it doesn't throw the **Compilation Error: invalid definition for function exec/red_mysql_store_result** error.
9214
00:10Suppose you simply throw that pointer up to Red as an integer!, then what? There's nothing meaningful you can do with that value, except calling other MySQL function on it that expect mysql_res! as an argument.
00:11@TimeSlip the definition is invalid because your return: spec is malformed. Try:
red_mysql_store_result: routine [ 
	MYSQL [integer!]
	/local 
		res [MYSQL_RES!]
][
	res: mysql_store_result MYSQL
	res
]
00:12Or keep it as return: [integer!] if you want. Although I'm not sure if res pointer will be automagically converted to it.
TimeSlip
00:13@9214 OK, I think I've tried that but I will try again.
00:16@9214 No, I had not tried that combination before but it does relate to what you said before about Red not knowing about the MYSQL_RES! datatype.
00:20It doesn't give me the error now, thank you though it broke the row count. I'll take a look at why.
00:25It's because I am now using the mysql_res result. That's kind of interesting in itself because the mysql_num_rows function would work previously.
00:31Also, it doesn't like having return: [integer!] because the #import declares it as returning MYSQL_RES! and complains it's not the right return type. Can I make the assumption that I am now getting closer and if I could only figure out what to do with the pointer, I'm golden?
9214
00:32@TimeSlip I already told you what to do with the pointer. Try as integer! res, or as integer! :res if that doesn't work.
TimeSlip
00:47Interesting, when I add as integer! res, it says that I am attempting to change the type of variable: res from : [struct! [ ...] to: [integer!] so I think I'm getting what I want but again, I don't know what to do with a pointer to a struct assuming that is what is being returned. And why does the mysql_num_rows not work when it did before. Perhaps I was getting the correct result using the return: [integer!] in the place? @9214 Thanks for your help. Let me fool around with it a bit more and perhaps someone can chime in with some help with the struct! issue.
01:26OK folks, I am getting close. With Vladamir's help I essentially ignored the struct! idea and am using integer!. It works. I am getting one function that expects a struct! result as a parameter to come back with what I expected (the number of tables in the db). Using that same struct! result value, I can call the function that returns the values of the rows. This appears to work in that I get different integer values which I am assuming are pointers to the arrays that are holding the strings I want to see (I get the same # of returned values as there are tables). The 64K question is how in the world do I access those strings given that I have these pointer results?
9214
01:44@TimeSlip [Indeed, how?](https://gitter.im/red/help?at=5fa09e6306fa0513dd8bc039)
01:46Substitute pretty-printing for conversion from c-string! to string! (assuming you have string data in the fields and not binary) and accruing them in a block.
XANOZOID
14:48Well I guess now is a good time for me to ask . . . is it even possible for Red to use a function from Red/System without Routine?
rebolek
15:35Red and R/S functions are running on completely different levels and it's routine!'s task to connect them.
pekr
15:43@XANOZOID is that really a problem for you? Routine is basically a wrapper to call into an R/S code ....
rebolek
15:44exactly
XANOZOID
15:46@pekr I didn't mean to frame it as a problem - I just wanted to make sure I understood it correctly :)
pekr
15:47OK then. The same, as calling a wrapped function from R/S into a shared library .... not sure what the overhead is, never measured, but should be fast enough ....
XANOZOID
15:48@rebolek @pekr Great, thank you! I was asking because I'm working on writing a binding and was trying to think about what the exact structure should be - which I've found is two files - one R/S and one Red with routines!
15:49I'm going to take a look later today at some of the libraries in the Code repo, just noticed there might be some examples there
rebolek
15:50@XANOZOID you can actually write everything in one file if you want. See #system and #call.
15:50That way you can call Red code from Red/System and vice versa.
XANOZOID
15:56Thanks, Rebolek - that should definitely be helpful
greggirwin
16:53Red gives you options everywhere. Sometimes it helps to write things separately, other times it's nice to have them close together, like inlining assembly in the old days.
bubnenkoff
18:36is there any way to rewrite next code to switch?
if find "asdf" "a" [result: 'aaa]
if find "asdf" "b" [result: 'bbb ]
if find "asdf" "c" [result: 'ccc ]
; if not all [ .... ] [] ; some logic if not all are true

Or in another words is there any way to use switch with find inside every case?
greggirwin
18:51Switch matches values. What you want is case.
dsunanda
18:57Something like this (assumes only one of your conditions can be true at once - though that's easy to fix :)
result: case [
   find "asdf" "a" ['aaa]
   find "asdf" "b" ['aaa]
   find "asdf" "c" ['aaa]
   ]
print result
9214
18:57@bubnenkoff
foo: function [string][
	index: find string charset "abc"
	either index [
		result: select [#"a" 'aaa #"b" 'bbb #"c" 'ccc] index/1 
	][
		; some logic if none were found
	]
]
18:58You can swap select [...] for switch index/1 [#"a" ['aaa] ...] if you want. I'd also inlined charset "abc" result instead of creating it on each function call.
greggirwin
19:08Nice one @9214.

bubnenkoff
13:03>Switch matches values. What you want is case.

Am I right understand that switch is preferably when there is maybe one or more true conditions, while case when only one?
9214
13:17switch evaluates the first true branch, so as case, but case/all evaluates all of them (if any).

GiuseppeChillemi
02:01Hi, I have asked some time ago with no answer but "Nenad did it, I have seen". I need to output to a secondary console to use as debug. How do I open another one and output there?
9214
03:25Use file-based IPC perhaps.
Rebol2Red
11:39In rebol you can do:
to-decimal "123.45"
;== 123.45
to-decimal 123
;== 123
to-decimal [-123 45]
;== -1.23E+47
to-decimal [123 -45]
;== 1.23E-43
to-decimal -123.8
;== -123.8
to-decimal 12.3
;==12.3

There's no to-decimal in Red. what's the reason?

btw:
There is a function called number? in Red
but there is no to-number or to number. Why?
toomasv
11:47decimal! type is not yet implemented in Red.
number? checks typeset, but there are no to- functions, only to-. Same for to .
Rebol2Red
12:15@toomasv Is decimal! somewhere on the roadmap? I have only the info on https://www.red-lang.org/p/roadmap.html which has not much details.
toomasv
12:36Sorry, I don't know details of roadmap, but there has been talk about it around :point_up: [November 3, 2020 3:17 PM](https://gitter.im/red/bugs?at=5e9a09f1a9ca186206448c68)
9214
12:36@Rebol2Red Rebol's decimal! is Red's float!.
Rebol2Red
16:03@9214 hmmm.
How about print to-float "123" ;== 123.0
not nice because it is obviously an integer

@toomasv in my program this gives all the right output
to-decimal: function [v][
	v: to-float v	    
    w: to-integer v
	either (remainder v w) = 0 [to-integer v][v]
]

; examples of using to-decimal

print to-decimal "123.45"	;== 123.45
print to-decimal "123" 		;== 123 
print to-decimal 123		;== 123 
print to-decimal 123.45		;== 123.45

I am open to improvements!
9214
16:07@Rebol2Red yes, it's an integer (or rather its textual representation), which you are converting to a floating-point number.

> in my program this gives all the right output

Neither Red nor Rebol do such kind of conversion with to; it will either give you a value of a datatype that you asked for or error-out if conversion is impossible.
Rebol2Red
16:22@9214
probe to-decimal "123" ; == 123
probe type? to-decimal "123" ;== integer
I rest my case.
9214
16:22
text
>> to-decimal 1.0
== 1
Rebol2Red
16:28@9214 You got me there but maybe i can find a way to go around this.
9214
16:31"If it's a string that looks like a number then load it, if it's a number then keep it, else bail".
to-decimal: func [value][
    case [
        number? value [value]
        find number! scan value [transcode/one value]
        'nope [make error! "can't do this"]
    ]
]
Rebol2Red
16:41@9214 Nice. I knew this was possible because if Rebol can do it Red can do it also.

This is a function i made up a while ago
numeric?: 	func [
    "String to number" string
][
     number? attempt [load string]]

Maybe this is related and i will appreciate your opinion about it. Thanks.
9214
16:46That's what the find number! scan value part does.
Rebol2Red
16:58@9214
print (to-decimal "2.3") + (to-decimal "3.7") ;== 6.0

I'd rather like to see as output 6 and datatype as an integer
Is it even possible to add to the function?
TimeSlip
19:09Hello. Toomas has been generously helping me with some 3D draw ideas. I've run across an issue though with his Rubik's cube code that has to do with the "^" (caret) symbol. Do any of you have any thoughts about this symbol? I've looked through the supporting code and the apps that use it but can't find it defined anywhere. Is it a new edition? Here is a sample on how it is used in the algebra.red file:
syms: #(prod: * wedge: ^ dot: | ldot: _| rdot: |_ vee: &)

19:10And in the d301.red file:
perp: func [
	"Project component of v1 perpendicular to v2"
	v1 [vector! object!] "Vector or object projected"
	v2 [vector!] "Blade from which it is rejected"
][v1 ^ v2 * v2]

toomasv
20:13In my [code](https://github.com/toomasv/GA) caret is used as word for operator (long name wedge). Its body is defined in [algebra.red](https://github.com/toomasv/GA/blob/master/algebra.red#L431). Defined as op on line [474](https://github.com/toomasv/GA/blob/master/algebra.red#L474). I have no problem with it, but @TimeSlip gets errors. We are both on W10. @TimeSlip, would you please paste here some errors you are getting. Any ideas?

GiuseppeChillemi
00:04I am trying to create a PROBE which is able to print words and log them. I have called this function PLOG: as *program log*
This is a preliminary version.
You have to use it with refinements which specify how the input value is processed and printed

PLOG/L value works passing as is, with no reduction.
PLOG/LL name value as before but preceding the print with the provided name
PLOG/L/G value and PLOG/LL/G name value get the value VALUE if the argument is a word.
PLOG/R value and PLOG/RR name value, works as regular PROBE but you can provide a name which is printed.

PLOG: func [
	"Debug words, print their values "
	/l 				"Print next the value and return it as is, with no reductions"
	'l-value	 "The word name or any other text"

	/ll 			"Print the provided string and the next value and return it as is, with no reductions"
	ll-name 	 "The word name or any other text"
	'll-value "The value"

	/g 				"If the argument is a WORD Performs a GET WORD. Also print the word name without having to provide it"


	/r 				{Print a value but let Red/Rebol reduce it before passing a argument 
						Use this if you want to print functions result}
	r-value		"The value"
	 
	/rr 			{Print a value but let Red/Rebol reduce it before passing a argument 
						Use this if you want to print functions result
						Prints the word name you provide
						}
	rr-name 	[String! word!] "The word name or any other text"
	rr-value  "The value"

	/sep			"Print a separator" 
	sep-text		[String! word!] "The separator text"

	/format ;To be implemented
	style			

	out-data
	pre-string
	name
	value
	to-get
] [
	if not value? 'plog-data [set 'plog-data copy []] ;For future use
	pre-string: "LOG>>>"
	
	case [
		l [value: :l-value if all [g word? l-value] [to-get: true]]
		ll [name: ll-name value: :ll-value if all [g word? ll-value] [to-get: true]]
		
		r [value: :r-value]
		rr [name: rr-name value: :rr-value]	
	]
	case [
		sep [print [pre-string "----------------" sep-text]]

		true [
			print [
				pre-string
				case [
						name [rejoin [name " "]]
						to-get [rejoin [value " "]]
						true [rejoin ["xNO-NAMEx" " "]]
				] 

				":-: " 
				mold out-data: either to-get [get value] [value]
			]
		]
	]
	out-data
]





00:05Here is an output and my problem:

;-------------- EXAMPLES ---------------------------------
x: 22
plog/l x															;LOG>>> xNO-NAMEx  :-:  x  
x: 22
plog/ll 'x x  								;LOG>>> x  :-:  x
plog/ll "Value of argument X is:" x  ;LOG>>> Value of argument X is:  :-:  x


x: 33
plog/l/g x														;LOG>>> x  :-:  33 
x: 33
plog/ll/g 'x x  					;LOG>>> x  :-:  33
plog/ll/g "Value of argument X is:" x ;LOG>>> Value of argument X is:  :-:  33

x: 44
plog/r x 															;LOG>>> xNO-NAMEx  :-:  44 
x: 44
plog/rr 'x x							;LOG>>> x  :-:  44 
plog/rr  "Value of argument X is:" x	;LOG>>> Value of argument X is:  :-:  44

00:07Here is my problem:
00:10I want to use PLOG/L/G version with a function, get it, run it with the following arguments like PLOG/L/G func arg arg. To do this I have to get its arguments and reduce them inside my function. I need this to print the function name with the /g option , so I can remove the /r and /rr refinements. I see no option than putting the function and its arg inside a block and getting its first word and running the block with do . The whole syntax would be.
PLOG/L/G [myfunc arg arg]
Do you have other solutions than using this?
00:18(Result should be LOG>>> myfunc :-: func-result)
greggirwin
02:11On decimal!, we plan to have an accurate decimal type, as money is but with more precision available.

@Rebol2Red Red won't auto-coerce to a lesser type with math ops. That's up to a user to do if they want it. Red does support floats for some loop constructs, where it truncates floats.
02:45@GiuseppeChillemi I don't have time to look at the details in your func, but why not pass a block to your logging func?
- [my-func ...] ; reduced
- [:my-func] ; get
- ['my-func ...] ; print name only
- ["extra text" my-func]

That avoids all the lit-word! args and a number of refinements.
bubnenkoff
07:36If I want to save-restore values and selected item of drop-list should I save only /selected value or it's better so save all object of drop-list and than load it's at start?
9214
07:41@bubnenkoff depends if content of drop-list is static or not. If it is, then saving selected index is enough.
GiuseppeChillemi
08:41@greggirwin let's see, I am experimenting.
TimeSlip
16:01Here is one example of the caret error:
do %algebra.red
*** Syntax Error: invalid issue! at "s: #(prod: * wedge: ^^ dot: | ldot: _| rd"
*** Where: do
*** Stack: do-file expand-directives load

16:03That is on line 345.
toomasv
17:03@TimeSlip Can you do such things?:
>> s: #(prod: * wedge: ^ dot: | ldot: _|)
== #(
    prod: *
    wedge: ^
    dot: |
    ldot: _|
)
>> s/wedge
== ^
>> s/prod
== *
>> s/dot
== |
rebolek
17:04Using an escape character as an operator is not a fortunate decision IMO.
greggirwin
17:39@rebolek, I agree. However, it's a *great* test to find problems like this., and it is a valid word, so should be available to dialects if that's the case.
17:39I'm just afraid I'd confuse myself and have to ask for help with my own code. :^)
toomasv
18:16I didn't meet any problem while using it, but I am curious, why the code that works perfectly well in my case does fail in other case, although on same platform. ^ is escape in strings/chars, but valid word. If we have to avoid some characters for esoteric reasons, it makes Red more fragile and unpredictable IMO.
rebolek
18:52@toomasv I don't agree. We already have to avoid some characters in words, for example: ( ) [ ] , $ and few others, like, curiously, \. Does it make Red fragile and unpredictable? IMO no, I believe it's otherwise, it makes Red less fragile and more predictable. Is ^ such an important character to support it in words? I don't believe so. I may be wrong, e.g. 2 ^ 3 is of course simpler to write than 2 ** 3, but I can live with such limitation.
toomasv
19:09@rebolek These characters are not valid for words. They are not to be avoided, they are not allowed. But ^ is valid character for word and it is not clear why it causes problem in this case.
TimeSlip
21:33@toomasv No, I get this error:
s: #(prod: * wedge: ^ dot: | ldot: _|)
*** Syntax Error: invalid issue! at "s: #(prod: * wedge: ^^ dot: | ldot: _|)"
*** Where: do
*** Stack: load

21:35I wonder if it's the version I am using: Build 0.6.4 4-May-2020
greggirwin
21:58@TimeSlip yes, please use the nightly build.
21:59I also prefer ^ to **, for exponentiation.
TimeSlip
22:41@greggirwin @toomasv OK, that was the problem. Now using the 11/4 build and it works. Thank you for the help.
GiuseppeChillemi
22:54I have learned something new. I thought * and other symbols could not be used alone.

GiuseppeChillemi
21:35I use words as keys in blocks but you have to put other words inside another block to use them as value. I am thinking about switching to set words as keys. Which difficulties could I encounter?

greggirwin
18:49Not sure what you mean by using a sub-block. Can you post an example? Set-words as keys are fine, I don't know how they'll solve your problem, e.g. with path access they behave the same.
GiuseppeChillemi
19:20@greggirwin

block: [hello word]


key + word-value)Is ok until..

block: [
   hello word 
   word some
];


the key has the same name of a value

To avoid this you should encapsulate the value as:

block: [
   hello [word]
   word [some]
]

And access it via block/key/1

Otherwise you have to change the key type to another one

block: [
   hello: word
   word: some
]

And access it via block/key
rebolek
19:28Why not using map!? It's designed exactly for this use case.
greggirwin
19:34@GiuseppeChillemi use select/skip blk 2 for that, or a map! as @rebolek suggests. Enforcing key-value semantics on blocks is a bit more work, and many of us have written wrappers to do it. Maps solve it natively, but have other limitations as well.
19:35e.g. you can *only* access by keys.
GiuseppeChillemi
19:59I am working on code which is both Rebol and Red, this is the reason I still do not use maps. When LV and ports will be available I will move to Red only code
19:59Also, could you point me some of those wrappers?
greggirwin
20:23
set-key: func [ ; put-key change-key?
        {Updates a named value in a series of key-value pairs, appending the
        key and value if it doesn't already exist; returns the series head.}
        series [series!]
        key
        value
        /local pos
    ][
        either pos: find/only/skip series key 2 [
            head change/only next pos value
        ][
            repend series [:key :value]
        ]
    ]

    get-key: func [ ; select-key ?
        {Gets a named value in a series of key-value pairs, or NONE if the
        key doesn't already exist.}
        series [series!]
        key
    ][
        ; Auto-create a "slot" for the key
        if not find/only/skip series key 2 [repend series [:key none]]
        ; Have to get the first item, because /skip causes SELECT to
        ; return a block.
        first select/only/skip series key 2
    ]

    has-key?: func [ ; found-key?
        {Returns true if key exists in the series of key-value pairs; false otherwise}
        series [series!]
        key
    ][
        found? find/only/skip series key 2
    ]

    remove-key: func [
        {Removes a named value in a series of key-value pairs, or NONE if the
        key doesn't already exist.}
        series [series!]
        key
        /local res
    ][
        ; What should this func return? REMOVE result, series head, the value
        ; at the key, or item removed--key+value?
        res: get-key series key
        remove/part find/only/skip series key 2 2
        :res
    ]

    incr-key: func [
        {Increments a named value in a series of key-value pairs, appending the
        key and value if it doesn't already exist; returns the series head.}
        series [series!]
        key
    ][
        set-key series key add 1 any [get-key series key 0]
    ]
20:23Old R2 code.
GiuseppeChillemi
21:28Thanks, I have created a similar function set last year but it was not so complete. I have understood what you mean for "wrapper". Sometime I have thougth we could have another word datatype in Red/Rebol which works exactly right the main one to serve this purpose here and in parsed blocks. The only difference, just a character to use as prefix of the second one.
greggirwin
21:43We've all done that too. set-ex, find+, etc.
GiuseppeChillemi
23:46I was thinking about an Alias datatype, which is the same of the WORD! dt but with a prefix. It would cone very handy with dialects, so you can use an alternate words without risking to use the same words used in main code. It's for isolation.

bkalef88_gitlab
06:21can someone take a look at this code? I'm simply trying to dynamically generate a gui, which is working to the point where it attempts to pass the values to this incr-receive function.
06:23
build-buttons: func [idx [integer!] b-lab [string!] b-val [integer!]][
	the-set-word: rejoin ["a" idx "-r" b-lab]
	the-btn-word: rejoin ["btn-r" b-lab]
	?? the-set-word
	?? the-btn-word
	append stats-layout compose[
		(to set-word! the-set-word)				; the reference to the button
		(to word! the-btn-word) [incr-receive idx b-val]		; assign to the set-word, the appropriate button style	
	]
]

06:23errors being received are;
*** Script Error: context for idx is not available
*** Where: act
*** Stack: do-file view do-events do-actor do-safe
06:25a sample execution of the incr-receive function;
incr-receive 10 3

and I guess the incr-receive function header would be needed;
incr-receive: func[inc-idx inc-scr][
06:31I feel I am doing something wrong in the compose of the build-buttons func, but I've tried everything I can think of over likely 3 hours and can't coerce it to process without error.
9214
06:47@bkalef88_gitlab idx word in [incr-receive idx b-val] is bound to a context of build-buttons function, ditto b-val; when you compose and append your result, this block becomes a part of the layout that you form, and so is idx word, which is _still_ bound to a context of the function. But once function has finished evaluation and returned to the caller, its context disappears. Hence the error message: idx no longer has any value associated with it.

What you're likely need to do is:
append stats-layout compose/deep [
        (to set-word! the-set-word)                ; the reference to the button
        (to word! the-btn-word) [incr-receive (idx) (b-val)]        ; assign to the set-word, the appropriate button style    
    ]

Which would substitute idx and b-val for the values that you pass to build-buttons.
06:51To rephrase it in more simpler terms: the relation between idx word and a value that you pass as a parameter to build-buttons exists only during build-buttons evaluation — once the function returns to the caller, this relation gets broken. At the same time, idx word nested within the block that you compose _persists_ long after this relation is broken, and still "points" to a place where its value is supposed to be found. But when you press a button, incr-receive is called, it evaluates idx as one of its arguments... and cannot find anything.
bkalef88_gitlab
15:08Thank @9214 for the detailed and clear response. I had tried every permutation of evaluation of the two parameters within this composed section.... and thought about compose/deep... and maybe even tried it as my new error is one I saw before. I will hammer away at it for a while before asking for any further help. Tx again.
greggirwin
18:04@GiuseppeChillemi but that hurts a dialect's readability. One of Red's main goals is to use words like humans do. It also changes word! syntax. It also doesn't solve the problem completely, as your alias could still only reference another word in a single context (likely global, but wouldn't have to be). What do you do if 2 modules use the same word and you want to alias it?
GiuseppeChillemi
18:05Maybe in the future the function context will be available after function exit.

9214
05:59That's what closure! is for.
GiuseppeChillemi
11:41Thanks, I have always read about closure! but never connected it to this purpose.

bkalef88_gitlab
01:05any guidance on how RED fills a draw area. I'm trying to get this pie-chart.red file to work, which I believe is a copy from Rebol. Seems there is not a flood command, am I missing something?

Red[Needs: View]

data: [
    18 red
    22 blue
    15 green
    20 yellow
    10 purple
]

sum: 0
foreach [val color] data [sum: sum + val]

plot: copy [
	canvas: base 200x200 silver
    ;box snow 200x200 
	draw[
		pen black
		circle 100x100 90
		line 100x100 100x10
	]
]

total: 0
foreach [val color] data [
    angle: 360 * val / sum
    total: total + angle
    xy: 100x100 + as-pair 90 * sine total -90 * cosine total
    repend plot/draw ['line 100x100 xy]
    append plot/draw reduce [
        'fill-pen color
        'flood 100x100 +
            100x100 + (as-pair 
                90 * sine total - (angle / 2)
                -90 * cosine total - (angle / 2)
            ) / 2
    ]
]
view  plot
9214
03:05@bkalef88_gitlab Draw has an extensive [reference documentation](https://github.com/red/docs/blob/master/en/draw.adoc). If you consult it, you'll find out that there's no flood command — try to play around with [fill-pen](https://github.com/red/docs/blob/master/en/draw.adoc#fill-pen) instead.
? (draw 100x100 [fill-pen red circle 50x50 20])

IIRC @toomasv had some interesting [piechart](https://gist.github.com/toomasv/87c5df40fdb76b08f2e1e495155dbf9b) experiments.
toomasv
05:13pie is interesting exercise. You'll need rainbow.png (below) to use the above pie.red. There is also [pie-style](https://gist.github.com/toomasv/8de193279fe556b6bb4f7b67c7e18c22) and [sectors](https://gist.github.com/toomasv/a122fa00305d3f2290a3b952d0c84c2d).
05:14[![rainbow.png](https://files.gitter.im/5780ef02c2f0db084a2231b0/qUKn/thumb/rainbow.png)](https://files.gitter.im/5780ef02c2f0db084a2231b0/qUKn/rainbow.png)
05:25I think @rebolek has worked on pie-chart a lot.
bkalef88_gitlab
06:59@9214 yes, I had been referencing that document and just wanted to make sure I had not missed something. Fill-pen works fine, and I got fill-pen bitmap to work as I was hoping. I will need to look at @toomasv suggestions. I did however manage to piece together a bit of what I was looking to do. The goal was to recreate a Spider/Web/Polar graph, and using draws arc and a semi transparent image as my fill-pen bitmap I pretty much got what I was looking for... except text at each chart axis, which will prove to be difficult for me. I may need to draw the chart and axis and use it as the background as I did here with the image.
![sample image of polar chart](https://i.postimg.cc/T1SYTbyX/sample-output.png)
07:08I am new to GitLab so having issues understanding how to link to my projects etc, but figured out I could add a snippet to let anyone look at the manually crafted draw block that built the above image. Time to work out the code to build it dynamically from a simple data block. Anyone wanting to suggest how to add angled text in the exterior, middle of each vertex I am open for any assistance.
* https://gitlab.com/volleyball-apps/serve-receive/-/snippets/2039609
toomasv
09:34Simple example:
start: -90
lay: foreach [color angle text][
	61.160.255 110 "First"
	99.212.212 70  "Second"
	80.202.115 40  "Third"
	250.212.57 40  "Fourth"
	242.97.123 50  "Fifth"
	150.90.228 50  "Sixth"
][
    append [] compose/deep [
		at 0x0 box 400x400 draw [
			fill-pen (color) pen white line-width 2 
			arc 200x200 100x100 (start0: also start start: start + angle) (angle) closed
			pen black rotate (start0 + start / 2) 200x200 [text 325x190 (text)]
		] on-over [
			face/draw/9: either event/away? [100x100][120x120]
		]
	]
] 
view/tight append lay [
	box 400x400 draw [
		fill-pen white pen white circle 200x200 40
	]
]
bkalef88_gitlab
14:02Thanks so much for the response and direction @toomasv. I will certainly be spending some time studying your example. It looks very interesting at first glance.
toomasv
14:11@bkalef88_gitlab You are welcome!
bkalef88_gitlab
14:49I just had a chance to run your code... WOW!!!
15:04Now I am very interested in how to extend this to become a style as you have done with your pie style. Do you have any advice on this for someone who has never created a 'style' before? https://gist.github.com/toomasv/8de193279fe556b6bb4f7b67c7e18c22
toomasv
16:27@bkalef88_gitlab I updated the pie-style. Try first example.
bkalef88_gitlab
22:13@toomasv , that is a nice example. Some reading material for tonight.

bubnenkoff
08:45Remember me please -- can't find here in history, how to pass args to app? like: app.red -foo
ne1uno
09:13https://gitlab.com/hiiamboris/red-cli/ or for simple a option or two print system/options/args
09:20 system/script/args has them too
9214
10:04@bubnenkoff here's the [history](https://gitter.im/red/help?at=5f24084b14c413356f49682a).
JakubKoralewski
11:49is there a __name__ == "main" analogue from Python in Red? I have a window.red, and I want to debug a specific window, without having to start the whole application and click through each time to open that window, so I wanted to check in the window.red file if it's being called directly or being included from the main file?
ne1uno
11:53you can fake it with if find system/options/script "script-name.red" [...]
JakubKoralewski
12:04system/options/script gives the name of the currently running script?
12:06That's cool thanks!
ne1uno
12:10yea, use find to ignore path, many things could work for if or either there
Oldes
13:23It's maybe safer to use split-path:
>> second split-path %/some/very/long/path/to/script.red
== %script.red
koba-yu
13:41Hi, my Windows 10 has got blue screen and maybe after that, I can not start Red GUI Console. Command Line Console is OK. I deleted C:\ProgramData\Red folder and re-download latest Red binary but GUI Console still not working. Do you know there are any other caches about Red I should delete...?
9214
14:59@koba-yu try to purge C:\\AppData\Roaming\Red.
Oldes
20:12I just noticed, that there is defined any-word! but also all-word!. I understand difference, but is there any real usage of the second one?
koba-yu
23:57@9214 Thank you for your advice!
I have come to my office now and got what were going. My Red GUI Console appears very low place on the monitor. I used Red by remote desktop yesterday so it went out of the screen...
I will check the folder you mentioned if something goes wrong again!

bkalef88_gitlab
00:08If windows...
* alt-tab to the application in question or select in the taskbar
* alt-space will select the window control menu
* press the M key
* use the arrow key to move the window by a pixel
* then move your mouse
* the window outline will be attached to the mouse pointer
* press the mouse button to place the window in a viewable area.
koba-yu
03:01@bkalef88_gitlab Thank you! I will use this next time.

fergus4
13:16I'm using @rebolek http-tools to send faxes and SMS messages though an twilio API. It works but I'm not sure how to insert a number into the command. Given to_number: "+12129994444" and the command:
ret: send-request/data/auth https://fax.twilio.com/v1/Faxes 'POST [
    From: "+1234567891" 
    To: to_number 
    MediaUrl: https://www.twilio.com/docs/documents/25/justthefaxmaam.pdf 
    ]'basic [
        "MyID" "MyPassCode"
    ]

How do I wrap the command to include the variable 'to_number'
rebolek
13:22@fergus4 for example:
ret: send-request/data/auth https://fax.twilio.com/v1/Faxes 'POST compose [
    From: "+123456789"
    To: (to_number)
    ...
]
13:22And thanks for using it :-)
fergus4
13:28compose!!!!! I'm a dope. Thanks Bo. And thanks for these tools to fill in the gaps until Red 1.0
rebolek
13:30You're welcome :) You can of course use reduce or your preferred method, nothing special there.
fergus4
13:31I tried reduce but could not get it to work.
rebolek
13:37As there isn't reduce/no-set in Rebol, it's much harder with reduce, you would need to set-word! 'something for every set-word!. compose is much cleaner currently.

tinulac-leinad
00:55Hi,
in this portion of code :
doc: read/lines file
  foreach line doc [
    parsed-line: parse-abc-line line false
    switch/default (copy/part parsed-line 2) [
      
      "A:"  [
            tune-list/(length? tune-list)/A: parsed-line  
          ]
      "B:"  [
            tune-list/(length? tune-list)/B: parsed-line  
          ]
      "C:"  [
            tune-list/(length? tune-list)/C: parsed-line  
;-- and so on

Is there a solution to write once the block without function call ?
toomasv
05:22@tinulac-leinad Sure there is. Without any examples of your file or parse-abc-function I just made up simplistic ones:
tune-list: [#()]
letter: charset [#"A" - #"Z"]
trash: clear []
doc: {1 A: "Red"
2 B: "Blue"
3 C: "Green"
4 D: "Yellow"}

parse doc [some [
    to [" " letter ": "] skip 
    copy line to [newline | end] (
        either find/case "ABC" first line [
            l: copy/part line 2 
            tune-list/(length? tune-list)/:l: line
        ][append trash line]
    )
]]

Results:
>> tune-list
== [#(
    "A:" {A: "Red"}
    "B:" {B: "Blue"}
    "C:" {C: "Green"}
)]
>> trash
== [
    {D: "Yellow"}
]
tinulac-leinad
13:00@toomasv
OK, I want to create a list of tunes in memory, each tune is an objet as below and "comform" to the ABC musical notation.
You can have an ide of what is ABC musical notation here in particular in the melody chapter http://abcplus.sourceforge.net/abcplus_en.pdf
A sample of what is an ABC file, whith 2 tunes :

tune obect :
tune: object [
    ;       field name        header corps   other     util  	Sample and notes
  ;       ============         ====== ==== ========= =======   ==================
  A: ""     ; region              yes                           A:Normandie A:Bretagne
  B: ""     ; source              yes        yes                archive B:O'Neills
  C: ""     ; composer            yes                           C:Trad.
  D: ""     ; discographie        yes                           archive D:Chieftans IV
  E: ""     ; espacement          yes yes                       I don't use
  F: ""     ; Field name                      yes               I don't use
  G: ""     ; instrument          yes         yes               archive G:flute
  H: ""     ; history             yes         yes               archive H:composé en…
  I: ""     ; information         yes         yes       playabc
  K: ""     ; key                 Last   yes                    K:G, K:Dm, K:AMix
  L: ""     ; default value       yes    yes                    L:1/4, L:1/8
  M: ""     ; mesure              yes    yes  yes               M:3/4, M:4/4
  N: ""     ; notes               yes                           N:voir O'Neills 234
  O: ""     ; from                yes         oui       index   O:I, O:France, 
  P: ""     ; parts               yes    oui                    P:ABAC, P:A, P:B
  Q: ""     ; tempo               yes    oui                    Q:200, Q:C2=200
  R: ""     ; rythm               yes         oui       index   R:R, R:valse
  S: ""     ; source              yes                           S:collected in cork 
  T: ""     ; title             second   yes                    W:rat's in the river
  X: ""     ; index number      First    yes                    X:1, X:2
  Z: ""     ; transcription  	    yes                           Z: from a paper

  melodie: [] ;-- the melody part of the ABC tune ... 
              ;-- a simple liste of lines at this time
]

here is one function to parse a line of ABC file
parse-abc-line: function [  line incipit
                            /local 
                              tmp-line 
                            /extern
                              pass
                              last-to-get
                          ][
  { parameters 
    line : line of abc : doc for ABC  in %doc/abcplus_en.pdf or _fr.pdf chapter II for idea of 
                          what whe have to do for a complete parser
    incipit: boolean true if we want only the 2 first bars of the tune
    
    Here whe parse-abc-line is used for one abc line and in a loop whe have to pay attention 
    on 2 extern vars
    pass: is set to true when one complete tune is processed and to false when the "X:" is encountered 
          to know that a new tune is in processing
    last-to-get: is used when whe are processing lines with incipit set to true. it is set to true when the 
                 the first line of melodie is get.  
    }                            
  
  tmp-line: to-string rejoin [line/1 Line/2]
  ;-- headers
  either (parse tmp-line
          [some["A:" | "B:" | "C:" | "D:" | "E:" | "F:" |
          "G:" | "H:" | "I:" |"K:" |"L:"|"M:"|"N:"|"O:"|"P:"|"Q:"|"R:"|"S:"|"T:"|"W:"|
          "w:"|"$ "|"X:"|"Z:"]])[
    if ( all [ incipit parse tmp-line ["X:"] ]) [ 
        
        last-to-get: false
        pass: false
    ]
    rejoin [line "^(line)"]
  ][
  ;-- Melodie
    either incipit [  
      either all [not pass not last-to-get][
        last-to-get: true
        rejoin [ tmp-line/1 "|" tmp-line/2 "|" tmp-line/3]
      ][
        pass: true
      ]
    ][
      if (not incipit) [
        rejoin [line "^(line)"]
      ]    
    ]
  ] 
]

the rest ins a second post...
13:07@toomasv So, the function that create a list in memory and then a sample ABC file content:
My question was about the switch world : how can I have one action for mutliple choice as you can see here ?
load-abc-list-from-file: function [ file /extern tune-list tune ][
  ;-- load tune-list [] from a file
  tune-list: []
  doc: read/lines file
  foreach line doc [
    parsed-line: parse-abc-line line false
    switch/default (copy/part parsed-line 2) [
      
      "A:"  [
            tune-list/(length? tune-list)/A: parsed-line  
          ]
      "B:"  [
            tune-list/(length? tune-list)/B: parsed-line  
          ]
      "C:"  [
            tune-list/(length? tune-list)/C: parsed-line  
          ]
      "D:" [
            tune-list/(length? tune-list)/D: parsed-line  
          ]
      "E:" [
            tune-list/(length? tune-list)/E: parsed-line  
          ]
      "F:" [
            tune-list/(length? tune-list)/F: parsed-line  
          ]
      "G:" [
            tune-list/(length? tune-list)/G: parsed-line  
          ]
      "H:" [
            tune-list/(length? tune-list)/H: parsed-line  
          ]
      "I:" [
            tune-list/(length? tune-list)/I: parsed-line  
          ]
      "K:" [
            tune-list/(length? tune-list)/K: parsed-line  
          ]
      "L:" [
            tune-list/(length? tune-list)/L: parsed-line  
          ]
      "M:" [
            tune-list/(length? tune-list)/M: parsed-line  
          ]
      "N:" [
            tune-list/(length? tune-list)/N: parsed-line  
          ]
      "O:" [
            tune-list/(length? tune-list)/O: parsed-line  
          ]
      "P:" [
            tune-list/(length? tune-list)/P: parsed-line  
          ]
      "Q:" [
            tune-list/(length? tune-list)/Q: parsed-line  
          ]
      "R:" [
            tune-list/(length? tune-list)/R: parsed-line  
          ]
      "S:"  [
            tune-list/(length? tune-list)/S: parsed-line  
          ] 
      "T:"  [
            tune-list/(length? tune-list)/T: parsed-line  
          ]
      "W:"  [
            tune-list/(length? tune-list)/W: parsed-line  
          ]
      "X:"  [
            
            append tune-list copy tune
            tune-list/(length? tune-list)/X: parsed-line  
          ]

      "Z:"  [
            tune-list/(length? tune-list)/Z: parsed-line  
          ]
    ] [
        append tune-list/(length? tune-list)/melodie parsed-line 
    ]
  ]
  tune-list
]

An ABC file sample :
X: 1
T: 1-1 Lucy Farr's
R: barndance
M: 4/4
L: 1/8
K: Gmaj
|:DE/2F/2|G2 G2 G2 G2|GABG E2 D2|B2 B2 B2 B2|BcdB A3 A|
BcdB G2 G2|GABG E2D2|DEGA BddB|A2 G2 G2 :||
|:A2|BcdB G2 G2|GABG E2 D2|DEGA BddB|B2 A2 A3 A|
BcdB G2 G2|GABG E2 D2|DEGA BddB|A2 G2 G2 :||

X: 2
T: 1-2 Gypsy Princess
R: barndance
M: 4/4
L: 1/8
K: Gmaj
(B2 B)B B2B2|ABAG E2 D2|(G2G)B d2 Bd|e2 dB A2 GA|
(B2 B)B B2B2|ABAG E2 D2|(G2G)A BddB|A2 G2 G2 z2:|
(d2 d)d d2 d2 |B2 BA G2 Bd|(e2e)e e2 e2|B2 BA G2 zB|
(d2 d)d d2 d2 |B2 BA G2 Bd|(g2 g)e dBGA|B2 A2 G2 z2:|

X:3
T:2-1 Ar Thoir An Donn
R:Reel
M:C|
L:1/8
K:Emix
AFFE ~F2 EF | AF~F2 Acec | BG~G2 EFGB | c/2d/2e fe ecBG |
AFFE ~F2EF | AF~F2 Acec | BG~G2 EFGB |1ceBG AFFE |
|2 ceBG AF~F2 || c/2d/2e fga2 ga | fe~e2 cBAc | BG~G2 EFGB |
c/2d/2e fe ecBd | c/2d/2e fg a2 ga | fe~e2 cBAc | BG~G2 EFGB |
|1ceBG AF~F2 :|2 ceBG AFFE |]

Regards,
Daniel
13:20@toomasv Last thing. I have test my function and it work fine as you can see:
>> load-abc-list-from-file %./data/sources/SV-DG-DN.abc
== [{|:DE/2F/2|G2 G2 G2 G2|GABG E2 D2|B2 B2 B2 B2|BcdB A3 A|^/} "BcdB G2 G2|GABG E2D2|DEGA BddB|A2 G2 G2 :||^/" "|:A2|BcdB G...
>> tune-list/1/L
== "L: 1/8^/"
>> tune-list/1/K
== "K: Gmaj^/"
>> tune-list/1/T
== "T: 1-1 Lucy Farr's^/"
>>

I want just to know more about select to have more clean code.
I have also some questions about object because the doc is short about it. No private data , initializer function and private or public functions etc ... ?
toomasv
15:12@tinulac-leinad How about this:
load-abc-list-from-file: function [ file /extern tune-list tune ][
  tune-list: []
  doc: read/lines file
  attrs: charset [#"A" - #"T" #"X" #"Z"]
  foreach line doc [
    parsed-line: parse-abc-line line false
	if find/match parsed-line "X:" [
		current: length? append tune-list copy/deep tune
	]
	either parse/part parsed-line [attrs #":"] 2 [
		attr: to-word first parsed-line
		tune-list/:current/:attr: parsed-line  
    ][
		append tune-list/:current/melodie parsed-line 
    ]
  ]
  tune-list
]
tinulac-leinad
15:54@toomasv even more concise and clear than I hope ;) I have to read more about parse and red in general ;)
Thank for the lighting
toomasv
15:55@tinulac-leinad You are welcome!

Oldes
09:29Is there a shortcut for code like:
if not find block value [append block value]

(I have a strange feeling that there was) and if not... what name would be good for such a mezzanine?
rebolek
09:30AFAIK there isn't, I miss it too. You probably confused it with alter which does something similar.
09:31or maybe having set! type would solve it properly :-)
Oldes
09:32The source of my feeling was probably from extend, but that is only for key/value pairs.
09:33How would set! type work?
rebolek
09:33"set" is a collection of unsorted, unique values.
09:34so if you append an already existing value to a set, nothing happens
toomasv
12:18This could be named nipend :)
pekr
14:29I fist thought about append-if-new, but then came up with just perfectly valid new imo .... append, if not already there. But newgenerally could be used to instantiate new objects, etc., so maybe not so great naming suggestion ....

new block value
rebolek
15:47hmmm. that's so simple it's unbelievable it's not used for anything yet :)
ne1uno
15:49newpend
pekr
15:52@rebolek The more I think about it, the more I like it. No more those pesky if found? find target value []old Rebol memes :-) Should I post a wish ticket? :-)
rebolek
15:54I miss found?. Or true?, whater the name, I don't care. But it's so useful I have to add it manually to almost any big enough codebase.
pekr
15:55Is not simple if find target valuegood enough?
rebolek
15:55for this use case, yes. But for others, no.
15:58for example if you want to avoid value: either something [x][y] and want to use value: pick [x y] true? something. You may use value: pick [x y] not not something, but that looks crazy.
pekr
16:05Maybe appendand insertcould have just new refinement. But I think it is going to be rejected, as any new addition to those two will slow them down a little append/new. This one would be used much more frequently, than append/dupimo ....
rebolek
16:09Instead of a new refinenement I prefer new datatype, set!. New refinement would slow down actions, new datatype would be optimized for this kind of usage.
pekr
16:11What would such datatype do? Wouldn't user be confused by set* function(s)?
16:12I mean - how would you use it to add a new block value, if not present?
rebolek
16:13That's like possible confussion between map! type and hypothetical map function, but I don't think it would be such a problem.
pekr
16:13It already works like that on maps, no?
rebolek
16:13It's basically like maps with keys part only, yes.
pekr
16:14What is setsupposed to do on block values? Set an element at index position?
rebolek
16:15I'm not sure I understand your question.
16:16Maybe to avoid the confusion between set and set!, we can call it množina! ;-)
pekr
16:19Well, I just really wondered, what is set supposed to do on a block. I had strings there, so it did not work (was not useful. Now with set [a b c] 1I have realised, it sets each word to a given value. That is something I would expect from mapor each function maybe ....
Oldes
16:19Maybe it would be enough to extend extend allowing block! as a first argument and any-type! as second.
rebolek
16:20@Oldes that is not a bad solution, but having optimized set! type is still my preferred one.
Oldes
16:22Adding a new datatype is too much work.. I will stay with unless find block value [append block value].
pekr
16:23Yeah, extendword is self explanatory. But my feeling is, that we have started to remove polymorphism from Redbol by having all those set, put, get,poke, pick etc. :-)
rebolek
16:24you can call it ufa (unless find ... append ...).
Oldes
16:24Yes... I can:) Or just eb (extend block ...)
pekr
16:25Hmm, putdoes "new" implicitly .... it replaces the key/value if found, or adds it
16:27Guys, stop those abbreviations, or HF will chime in with a code golf examples :-)
rebolek
16:27But put still requires a key.
pekr
16:28Maybe put should be dissaloved for blocks? It makes sense with maps and is not all that natural for blocks imo ...
rebolek
16:28If you are using block! as a key/value store, which is perfectly valid use case, then putis very useful.
pekr
16:36Hmm, pity extend is tied to objects, maps only. But not sure it could be easily extended to work on a block value, but maybe it could. It would be imo a nice solution extend block value, not requiring mine proposed new block value
rebolek
16:38It actually works on map! only, object! is still TODO.
16:38Maybe it's worth writing a REP for it.
16:39(block! I mean.)
pekr
16:39What would the spec be supposed to accept? Nowadays it is limited to the following types spec [block! hash! map!]
16:40You would have to allow it accept just any value?
rebolek
16:41Probably. It would need to behave differently for block! and for map! / object! but that's not unseen in Red, for example foreach also has special case for map!.
pekr
16:46Well, why append/insert can't be extended then? Isn't it just another case somewhere in their code?
Oldes
16:50Hm... maybe append/only block value could work with such a check.. if value would not be block... because the /only is now ignored if value is not block!
rebolek
16:51it is. but all this questions about what function should be extened (making it slower) just supports my statement that instead of extending a function, new datatype should be introduced.
Oldes
16:52I don't think adding a new datatype is a good way to go in this case... You must count that with each new datatype you must add code solving how it should work in many places and so the slow down would be even bigger.
pekr
16:53@rebolek This is such a simple case, that I really don't know, what such a new datatype would offer in addition? Could you provide me with the code example?
Oldes
16:53But adding such a exceptions is also not a good... because it simply adds exceptions.
rebolek
16:54I know it's more work, but it's a type that has it's benefits and would be an useful addition. If it wasn't, other systems wouldn't do the work to support it.
pekr
16:54/only is used for values "as-is", but could be used ....
rebolek
16:55And then, what if you want to add a block in block? Now you have different behavior and a case where you need to get back to unless find...append...
pekr
16:56I don't understand this obsession with somehow slowering the code. I can understand Carl claiming openhad too many refinements already, but append and insert are branching their code anyway, no? Would there be any speed penalty by just adding /new refinement?
rebolek
16:57actually there aren't branches based on type, each type implements it's own actions.
Oldes
16:58Maybe I can just use union
>> union [a b] [b]
== [a b]
>> union [a b] [c]
== [a b c]
pekr
16:58Hmm, I can see. The help format is visually identical to functions, but it states "APPEND is an action! value"
rebolek
16:59@Oldes you can, you just need to allocate new block that will be disposed immediately
Oldes
17:00Maybe this could be supported:
union [%dir1/ %dir2/] %dir3/

(which is my use case)
rebolek
17:01Yes, that sounds reasonable at first look (I don't know the actual implementation of union so maybe it's not reasonable at all)
17:02But IMO it's the cleanest proposal yet (with the exception of set! type)
Oldes
17:09But there is no man-power to implement your set!.. I will use the union with my value inside a block.
rebolek
17:10Actually Nenad stated that he was thinking about implementing set! so I'm not the only one who wants it :) But I understand there are more important things to do.
17:11Also I have a set! implementation done using reactors, let me find it...
17:13Here it is: https://github.com/rebolek/red-tools/blob/master/set.red
17:13
>> do %set.red
== func [/local value][
    value: make sorted-set! [] 
    value/data
]
>> s: make-set
== []
>> append s 1
== [1]
>> append s 2
== [1 2]
>> append s 1
== [2 1]
Oldes
17:14The union is much slower...:
>> dt [loop 10000 [b: [a b c d] v: 'e union b reduce [v]]]
== 0:00:00.0219467
>> dt [loop 10000 [b: [a b c d] v: 'e unless find b v [append b v]]]
== 0:00:00.0089654
17:15hm... I guess it's because it makes lookup hashes... so it's a no go in such a use-case.
pekr
17:25I still don't undestand, how a set!type would help to add a non-existent element to a block?
rebolek
18:57@pekr see my experimental implenetation

greggirwin
02:38New, append/new, etc. don't work from a naming perspective. The basic words have to clearly imply the logic involved. Extend is the closest, but then we run up against the issue that blocks are *not* key-value pairs. We do want to use them that way, a lot sometimes, hence things like set/key/has-key wrappers. If we say that extend *treats* blocks that way (and we can), then it needs to work like it does for maps and objects, with key-value pairs, and so doesn't match what @Oldes needs in this case. It really is set logic as @rebolek says, but that's a much larger task, as we have all the other series types to consider. e.g. we have charset to wrap bitsets, which covers string types, but is set! simply a block with added logic, or do we have any-set! which could also be a hash! or other block type (and also a bitset)?

Union and other set ops are not complex today in how they're dispatched, because the types have to be compatible. Even if you bring type coercion in, you still have the overhead of creating a compatible type internally. Or complicating the set op code in each type.

Good profiling info @Oldes. How many times does it need to run in your real use case, and under what performance criteria?

The simple check logic, even at the mezz level, avoids allocations if no change is needed, so that's a win.
02:42Looks like I drafted append-new myself at one point. I also did this:
inset: func [	;!! too close to INSERT
	"Append value to series if not present; otherwise return location where value was found."
	series [series!]
	value
][
	any [find series value  append series value]
]
02:44What a real set! gives you, of course, is the confidence that nobody (like you on another day) can go behind your back and treat the block as a non-set and mess things up. Same issue as with alter and the design question of removing all occurrences or just one.
02:46Clearly just an idea there with inset as both find and append should use /only.
02:48Include is a nice name, and carries semantics with it, that we expect it to be idempotent. But probably too confusing to mix with the preprocessor, which is also (generally) location dependent.
rebolek
05:50Another name I was thinking of is expand but that's currently used by expand-directives which I don't think is a good choice.
pekr
06:01@greggirwin I don't agree, that newis eventually a bad name. It stems down from things like append-if-new, where Carl suggested to not make a long names. For me, /onlyis one of the worst naming decisions in Redbol and users absolutly can't have any clue, unless they become familiar with what it represents. And yes, it would work for the above discussed scheme, but is naturally taken to prevent inlining of blocks.

What I also am not much comfortable with, is the split we did for Red, re some functions splittings between the map, object, block semantics. I always wished do have just insertand appendand overloading those things is not user's business, but a designer's one :-) So - I am not sure I want to have yet another function to remember, expand, keeping in mind what datatype it works for and for what it does not.
rebolek
06:04in such case, insert is enough as it was in earlier Rebol versions ;-) I don't think that having more functions is a bad think and you don't have to remember them, just remember those which you use
pekr
06:06Rebolek - I think that most users would be just ok with appending to object, not extending it via other function. For me it almost feels like the function was created just to push user to realise, he is dealing with a different kind of stuff. Which is of course true, but ....
rebolek
06:31Which may be a good thing. But I understand, extend feels kind of superfluous, we have insert and append and also put which takes key and value as args. The only difference between extend and put is that extend can put more keys at once, but I believe put can be extended to support this also.
pekr
06:47Otoh extendis nice and self explanatory word ...
rebolek
07:34Agreed.
loziniak
09:32> if not find block value [append block value]

I have a function just like that in my code, and I called it supplement.
09:33Also, there is set! on the roadmap: https://trello.com/c/O2upNkDQ/47-datatypes
Oldes
15:20supplementsounds good to me.
rebolek
16:14@loziniak good catch! I remember discussing it with Nenad and didn't know it's on the roadmap. But it's so useful that it shouldn't be a surprise :)
Oldes
17:13The biggest problem with these functions is like with find and select... one never knows which equality type should be supported :/
17:57I ended with:
supplement: func [
	"Append value if not yet found."
	series [block!] {(modified)}
	value
	/case "Case-sensitive comparison"
	/local result
][
	result: series ; to return series at same position if value is found
	any[
		either case [
			find/case series :value
		][  find      series :value ]
		append series :value
	]
	result
]
pekr
18:46Well, I even don't properly recognise supplement english word, so as for me, I would probably never found out, what the function is for :-)
greggirwin
21:08@pekr, new is so semantically loaded from OO that it could easily be confused with meaning make or copy the value. I agree that /only is one of those things you have to learn, but to replace it we need a better suggestion. I don't have one, and I've tried. :^)

Extend was added to R3, and Red took it from there. It's always a balance between too many functions to remember, and too few that are heavily overloaded. I won't vote for supplement as a standard name, but am happy if others like it for their own use. We also have join/combine which I played with as wrappers to reduce the number of funcs to remember, if the behavior isn't too confusing.
loziniak
21:10I like append/new the most, even better than supplement :-)

hiiamboris
13:18> for example if you want to avoid value: either something [x][y] and want to use value: pick [x y] true? something. You may use value: pick [x y] not not something, but that looks crazy.

@rebolek value: pick [x y] true = something - that's just one more char (space) to type ;)
13:19Although that's for nones, not for series..
13:21to logic! something is still better than not not something ;)
rebolek
13:22right, to logic! works
hiiamboris
13:22or even to yes something :D (but I wouldn't prefer this one)
13:31@Oldes union converts blocks to hashes and then back. But if you use a hash in the first place, it should be faster than find on blocks, esp. when your hash grows.
Oldes
13:32I know that. I was mentioning that... although I don't think that someone would wanted to use such a mezzanine function on large sets.
13:33If one needs to collect unique data.. it was much faster for me just to append them to block and do final unique call to remove duplicates. But the supplement thing is more for user friendly tasks of type: _append directory to this list, if there is not yet_ and do other job.
Rebol2Red
13:55Is there a difference in save and save/all? Maybe in some special cases?
If i compare two files, one saved with save and one saved with save/all there is no difference whatsoever.
r: to-hash ["one" "two"]
save  %htest1 r
save/all  %htest2 r
rebolek
13:55save uses mold, save/all uses mold/all
Rebol2Red
13:56But what's the difference then?
rebolek
13:57For example:
>> mold true
== "true"
>> mold/all true
== "#[true]"
Rebol2Red
14:01Sorry i don't get this
probe load mold true
probe load mold/all true

Results looks the same to me
rebolek
14:02@Rebol2Red that's it, they just *look* the same,but aren't:
>> type? load mold true
== word!
>> type? load mold/all true
== logic!
Rebol2Red
14:05I see, so we need mold/all to get the right type? But it mostly do'nt matter. Maybe like parse/all in rebol which is parse in Red? Correct me when i'm wrong.
rebolek
14:09Mostly it doesn't matter but there are situations where simple mold (or save) is not enough and you need to use the /all variant. I wouldn't compare it to parse, where /all refinement does different thing and while parse/all is better as default, there are situations where I miss the Rebol-like parse with its whitespace auto-skipping.
Rebol2Red
14:12Can i assume that using /all is right for all cases? So always using /all?
rebolek
14:14/all output is less readable, so if you want something that should be human accessible, better not use it
14:14And if you don't care about readability, use redbin.
Rebol2Red
14:17I get it now. Good explanation, thanks!
rebolek
14:30You're welcome!
GiuseppeChillemi
17:45How do I get the words of a function context from its inside:

>> f: func [/local a] [probe words-of context? 'a]
== func [/local a][probe words-of context? 'a]
>> f
*** Internal Error: reserved for future use (or not yet implemented)
*** Where: reflect
*** Stack: f probe words-of


On system/words words-of works but not on functions.
hiiamboris
17:53You'll have to parse the spec I'm afraid.
Rebol2Red
19:14How to change a patron depending on a booktitle?
lent: [
    "Pride and Prejudice" ["Alice"]
    "Wuthering Heights" [""]
    "Great Expectations" ["John"]
]

Change patron "Alice" of book "Pride and Prejudice" to "Susan"
probe select lent "Pride and Prejudice" ;== ["Alice"]
change "Alice" to "Susan" ; pseudocode
probe lent

Change patron "John" of book "Great Expectations" to "Alan"
probe select lent "Great Expectations" ;== ["John"]
change "John" to "Alan" ; pseudocode
probe lent
GiuseppeChillemi
19:17@hiiamboris
I have made this on Rebol.

cclone: func [
	"Make a new context with the same values of another one"
	ctx [object! word!] "The starting context: context or context of a bound word"
	/local
	wrds			;Block used to build the new object prototype
	out-data	;The returned element 
	] [
		;Mettere il GET
		if word? ctx [ctx: bound? ctx]
		wrds: words-of ctx
		forall wrds [
			if word? first wrds [
				change wrds to-set-word first wrds 
			]
		]
		append wrds none
		wrds: head wrds
		
		out-data: make object!  wrds
		
		set out-data values-of ctx
		out-data
]


words-of is missing on Red but I will try to part it with spec-of and parse.
greggirwin
19:18@Rebol2Red
lent: [
    "Pride and Prejudice" ["Alice"]
    "Wuthering Heights" [""]
    "Great Expectations" ["John"]
]
lent/("Pride and Prejudice"): "Susan"
Rebol2Red
19:26@greggirwin
probe lent
== [
    "Pride and Prejudice" "Susan"  <-- not ["Susan"]
    "Wuthering Heights" [""] 
    "Great Expectations" ["John"]
]

Is it not necessary to have ex. "Susan" into a block to use select?

I can do lent/("Pride and Prejudice"): ["Susan"]
Is this correct?
greggirwin
19:32Ah, I missed that you wanted to keep it as a block of people lent to. You can either change the whole block, or just the element.
lent: [
    "Pride and Prejudice" ["Alice"]
    "Wuthering Heights" [""]
    "Great Expectations" ["John"]
]
lent/("Pride and Prejudice")/1: "Susan"
19:33If you need to match it, then you can do this:
lent: [
    "Pride and Prejudice" ["Alice"]
    "Wuthering Heights" [""]
    "Great Expectations" ["John"]
]
change find lent/("Pride and Prejudice") "Alice" "Susan"
Rebol2Red
20:05@greggirwin How to remove a book with patrons from lent?
greggirwin
20:14What have you tried so far?
Rebol2Red
20:15remove lent select lent "Pride and Prejudice"
[["Alice" "Kathy"] 
    "Wuthering Heights" [""] 
    "Great Expectations" ["John"]
]
greggirwin
20:16Use find to find the *position* in lent to remove it.
20:17Select returns the value following the key.
Rebol2Red
20:25This is not working
remove lent find lent/("Pride and Prejudice")
probe lent

== [["Alice" "Kathy"]
"Wuthering Heights" [""]
"Great Expectations" ["John"]
]
greggirwin
20:27Because remove lent removes the first element in lent. Try step by step. e.g.
select lent <key>
find lent <key>
remove ...
<one more step for key-value handling>
20:28Do this in a console, so you can see what's happening. And remember to reset lent if you've modified it while playing.
Rebol2Red
20:56I think this is it
lent: [
    "Pride and Prejudice" ["Alice" "Kathy"]
    "Wuthering Heights" [""]
    "Great Expectations" ["John"]
]
remove/key lent "Pride and Prejudice"
remove/key lent "Great Expectations"
; == [
    "Wuthering Heights" [""] 
]
greggirwin
20:59Very nice. Remove/key is a new addition, which makes it even easier than remove/part find 2.
21:00I can already hear people thinking about change/key. :^)
21:03There's one catch with it, when used with blocks. If you have values that are also keys, you may not remove what you want. That is, there is no implied /skip 2 for remove/key on a block.
GiuseppeChillemi
23:06@hiiamboris @greggirwin However, my cclone function will have a limit once ported to Red. Even if I parse the function specs object, when cloning the context, if values have words bound to the cloned one, it won't work. Until the day we will have closures, we could not pass blocks and structures born inside a function to another one. All operations must happen under the function umbrella.
23:08This is veeeeeryyyy limiting!
23:20No, maybe make will correctly bind the word to the new context. Just too late to think on this topic, I have to sleep ;-)

GiuseppeChillemi
00:12I am still on the consolle:
I have found a problem in my Rebol approach: words-of returns a block of words but some of them are of refinement type, even if they have the visual aspect of a word. How do I create a context where some words are refinements and not simple words, and how do I set them to true?
12:13So, in Red too there is no way to create a context whose words are refinement?
greggirwin
21:51Not at this time @GiuseppeChillemi. Cloning objects is not difficult, but function contexts are a different beast. When I run up against limitations or design elements in Red/Rebol, where I find myself fighting the language, I try to step back and think of other approaches.
GiuseppeChillemi
22:15@greggirwin I am currently experimenting. Nothing definitive, I am just playing with the language, contexts and parse, either in Rebol and in Red. On all the experiments I have made the most limiting thing on Red is just the lack of closures as I can't manipulate a function context with another function. I have to do everything on systems/words context; or create a free one which is not bound to the function and which does not contain words of it one to be later used; never pass words of function contexts and or pass them using blocks with couples of symbol/values inside.
22:18I hope closures will be here soon, they are very useful and they can unlock many new coding approaches.
bkalef88_gitlab
23:45:point_up: [November 27, 2020 9:17 AM](https://gitter.im/red/help?at=5fc10a677850f66b6048a2d1)
Described here: https://www.red-lang.org/search/label/redbin

dander
07:46@GiuseppeChillemi Have you seen any of the [various closure methods](https://github.com/red/red/wiki/%5BNOTES%5D-Closures) that have been discussed?
GiuseppeChillemi
13:09No, I have thought the discussion was happening internally. Thank you for the link.
Rebol2Red
21:03Can someone explain the differences. (Maybe /all isn't working yet? So no difference at all)
bl: [a: 0 b: 10 c: 20 d: 30]

save/all %test.red bl
do load %test.red
probe b 				;== 10

save %test.red bl		;<-- NO /ALL
do load %test.red
probe b 				;== 10

save %test.red bl		;<-- NO /ALL
do load/all %test.red	;<-- NO /ALL
probe b 				;== 10

save %test.red bl
do %test.red 			;<-- NO LOAD
probe b 				;== 10

tinulac-leinad
09:35@Rebol2Red HI,
I have test the same things recently and it works
== [a: 0 b: 10 c: 20 d: 30]
>> save/all %test.red bl
>> b: load %test.red
== [a: 0 b: 10 c: 20 d: 30]
>> probe b
[a: 0 b: 10 c: 20 d: 30]
== [a: 0 b: 10 c: 20 d: 30]
>>
greggirwin
22:08For some values, like words and numbers, the serialized form is the same either way.
22:10But /all isn't in place for all other values as well. The reason for that is finalizing decisions on the serialized syntax. That may move forward now, as the redbin work is wrapping up, and /all is another piece of the serialization puzzle.
22:11https://github.com/red/red/wiki/%5BDOC%5D-Table-for-to-string-etc. has a table, which will be updated, along with @meijeru's detailed spec docs, as the serialized syntax for complex types is finalized.

tinulac-leinad
00:36How to ensure some code is executed before a GUI app is closed ? I tried on-close [; code here] at the end of view but it as no effect ?
THanks
ne1uno
00:46there are multiple ways to exit, including terminate from the OS
01:04https://gist.github.com/greggirwin/95a74f7e9cc8ab62f9e5db7183ba38e3
01:17you can catch unview quit and window close, not sure I've seen example that catches them all. no luck for terminate or something like reboot right now without wrapping OS libraries
greggirwin
02:25@tinulac-leinad can you post your actual code, just the relevant bit, so we can see how you're using on-close? It should work fine, but as @ne1uno says, there are many ways a window can be closed.
toomasv
05:32Don’t put on-close in the end of VID block. Window options and actors are in the beginning of VID.
05:33... or in separate options block.
tinulac-leinad
11:33@toomasv @greggirwin @ne1uno
OK, I just have to see how to use it and this is working Ilts a simple call, but with call of one function this can do the job:
view/options/flags [
  title "APP_TITLE"
  ;-- etc...
] [
  menu: [
    "Files" [
      ;--Etc...
      ]
      ---
      "Quit" kwit
    ]
  ]
  actors: make object! [
    on-close: func [face [object!] event [event!]][ write F_TUNES_LIST tunes-list]
    on-menu: func [ face [object!] event [event!]][
     ;-- Etc...
      if event/picked = 'kwit [
        write F_TUNES_LIST tunes-list
        quit]
    ]
  ]
][resize]

Thanks for help, you give me the way
Numeross__twitter
14:59Hey everyone! Thanks for your welcomes and help :D
I'd like to do some vector graphic stuff, and started reading discussions about float based pairs and triples.
I don't completely understand why it's not implemented yet.

About the syntax :
I'm not sure that I like 3.33x33.3 or 3.33x33.3x333. To me, that's not really readable. And even 3x3 is the way I write 3*3 on paper.
In France, coordinates notation is (3.33 ; 33.3 ; 333.). I guess that wouldn't work. Maybe 3.33|33.3|333. ?
15:02To be precise, french notation is (3,33 ; 33,3 ; 333)
9214
15:34> I don't completely understand why it's not implemented yet.

Because there's not enough space to store more than a single 64-bit float in value's payload, and because the proposed syntax is ambiguous.
hiiamboris
16:13Who said we must use 64-bit floats? ;) 32 should do just fine.
Numeross__twitter
18:08What would be the difference between a vector and a triple ? I can't find something that explain how the payload stuff works.

What do you think of the syntax 3.33|33.3|333. ? I personally like 3|3 more than 3x3, but I don't know Red enough to be objective.
The pipe symbol doesn't seem to be used that much around numbers
hiiamboris
19:34Possible but unlikely. Symbol must mean something, not chosen randomly.
19:40<1.2 3.4 5.6> 1.2/3.4/5.6 (1.2, 3.4, 5.6) point [1.2 3.4 5.6] all these are possible too.
Numeross__twitter
19:53ooh yee
19:54The / symbol is def more used in Red than |
19:57In other discussion it was said that (1.2, 3.4, 5.6) could be ambiguous
greggirwin
20:19Pair syntax isn't going to change. The last time this came up, and I can look for notes if needed, a key point was how often you're going to look at raw values like 3.33x33.3x333. That is, how important is the literal form really?

I believe (1.2, 3.4, 5.6) was what Nenad considered at one point, but ambiguity (in 2 ways) makes it a tough call.
Numeross__twitter
20:33I see, and if you really want to be readable you could do to-triple [3.33____33.3____333]
20:34spaces weren't showing up so I've put underscores
greggirwin
20:37Right, or a serialized syntax when that comes.
hiiamboris
21:00We could just implement point with construction syntax, and think of literal syntax later.
21:03Same for pairs - we could mold it in construction syntax when it's not integral.
greggirwin
21:04Yup.

Numeross__twitter
12:42Is it possible to make a drawing the target of a reactor ? Or do I have to update the drawing manually ?
9214
12:59@Numeross__twitter depends on what you mean by "drawing". If it's an image! then no, if it's a Draw block then yes.
Numeross__twitter
13:00Yes I meant draw block
hiiamboris
13:05Reactor is just code. It can modify anything other code can. So it's possible targets are limitless. So why not an image? You'll just have to tell Red to redraw the image on the screen.
9214
13:09My bad, I misread "target" as a "source" of the reaction. @Numeross__twitter View will handle all of that automagically, you just have to append Draw commands to a draw facet.
view [base 500x500 draw [fill-pen red] on-down [append face/draw reduce ['circle event/offset 10]]]
Numeross__twitter
21:01Ohh I was not putting 'is' in my reactor... I spent all day on this x)

Numeross__twitter
10:45Is it possible to iterate over a reactor ?
10:46Oh ! with keys-of
I swear I have been searching for some time before asking .-.
greggirwin
19:04Red is deep, and takes time to learn. Even then, there are so many features that we all forget them sometimes. Fortunately, you'll quickly find that many functions work across types and give you leverage. If something seems hard to do, ask. Either *someone* will know a trick, or confirm that it's hard. :^)

koba-yu
02:07Hi, are there any ways I can directly call [replace-unicode-escapes](https://github.com/red/red/blob/master/environment/codecs/JSON.red#L167) function in Red's JSON codecs? I have unicode escaped string but not a whole JSON. Not sure whether I can reuse the function or I need define my own one.
I tried context?, bind and other functions to access the codecs' inner context for a while but not succeeded...
rgchris
04:19@koba-yu You can access it through the context:
replace-unicode-escapes: get in context? first find body-of :load-json 'json-value 'replace-unicode-escapes

However you may be better off just wrapping your partial string and loading that
koba-yu
04:54@rgchris Thank you for your answer! So interesting.

> However you may be better off just wrapping your partial string and loading that

You mean something like this is better way?

sequence: "\u304a\u306f\u3088\u3046" ; "おはよう" is descaped string
json: rejoin ["{^"value^":^"" sequence "^"}"]
result: load/as json 'json
;== #(
;    value: "おはよう"
;)
rgchris
04:57@koba-yu Could be as straightforward as:
>> load/as rejoin [{"} "\u304a\u306f\u3088\u3046" {"}] 'json
== "おはよう"
koba-yu
05:01@rgchris Ah, JSON not required key... Thank you, it is much easier enough than accessing context!
rgchris
05:01I believe the JSON decoder will load any JSON value, not just arrays and objects
koba-yu
05:04Didn't know. I misunderstood result must be map!...

>> load/as {null} 'json
== none
>> load/as {true} 'json
== true
greggirwin
05:25It raises an interesting question about anonymous contexts. From an information hiding perspective, they make it clear what is exposed. We'll do the same thing with modules. But if people know they are using something internal to a module or context they have to accept the risks that it's not a public API. That can still save a lot of work. What we're missing now is the documented API part, so anonymous contexts err on the side of caution.

I will say that it's nice of the codec to work as it does in this case.
giesse
10:21ideally, there would be a separate text encoding/decoding module that json just uses. like what i do in power-mezz.
greggirwin
16:19Agreed. I think that was the eventual plan, now that you mention it. So, modules. :^)
16:21Coincidentally, Ladislav just posted a documentation update for his [include](https://github.com/saphirion/include).

Numeross__twitter
06:42Hello, I realized I haven't say thanks for the answers I have received, so thanks !
Now my question:
Is there a way to handle mouse events on Draw stuff ?
07:18To be more precise, an easy way to detect if you click on the outline of a circle, but not on the inside
toomasv
07:20@Numeross__twitter Yes, events on draw are processed by face which drew it, unless mouse is over completely transparent area, where alpha-channel is set at 255, e.g.:
view [box 100x100 draw [fill-pen red circle 50x50 30] on-down [probe "Circle"]]

But this is not consistent on all actors. E.g. on-over processes mouse movement only if it is over transparent area, e.g.
view [box 100x100 draw [fill-pen red circle 50x50 30] on-over [if event/away? [probe event/offset]]]
Numeross__twitter
07:50
view [box 100x100 draw [circle 50x50 30] on-down [probe "Circle"]]

On linux, the event still fire up if I click on the inside of the circle. Do you mean that that's not the expected behavior ?
07:59Oh yeah it's not doing it on windows :^)
toomasv
09:13Not processing events on transparent areas is great for implementing layers. Don’t know how to make layers without it.
hiiamboris
09:34I'm gonna report that.
toomasv
10:06:+1:
Numeross__twitter
11:20Thanks !
12:10Is there a basic graph/tree library ?
Rebol2Red
14:54This is driving me crazy (on windows10)

Can someone explain why if i run this:
loop 10 [ask "Give some input:"]

Nothing happens it looks like Red wants to execute it but it doesn't

But if i do:
print [] <--- arrrgh why???
loop 10 [ask "Give some input:"]

It works!?

Has this something to do about buffering the output?
Maybe someone else had this and found a solution?

ps: I have already tested this with a new Red, but it's the same
hiiamboris
14:56https://github.com/red/red/commit/3cf54998a3665e2de6acbaae6cf4fb79bfbf424a
14:57I guess it's a bug/oversight that "ask" doesn't bring the console up.
14:59You should file an issue about this regression.
15:03And another issue about prin + input combo not working properly ;)
15:03Because ask should be just that. prin and input
15:06oh, second bug is actually a long known one https://github.com/red/red/issues/2679
15:53console just quits if nothing was printed
pekr
16:52not sure if related, but just try printing something in a loop, e.g. loop 10 [print "test" wait 0.5]. It will wait till the loop is finished and then prints at once. It drives me crazy, but it is supposed to be fixed with proper IO?
hiiamboris
17:09loop 10 [print "test" do-events/no-wait wait 0.5]
17:11wait is blocking and simple atm
17:14nothing's stopping you from making your own wait mezz that does do-events/no-wait every 5ms or so.
MarkoSchuetz_gitlab
17:43To see the cross-compiler at work I tried the Android target
➜  tmp ~/src/red-latest -t Android hello.red                                             

-=== Red Compiler 0.6.4 ===- 

Compiling /home/marko/tmp/hello.red ...
...compilation time : 761 ms

Target: Android 

Compiling to native code...
*** Warning: OS_TYPE macro in R/S is redefined
*** Compilation Error: invalid path value: image/extract-data 
*** in file: %/home/marko/tmp/datatypes/binary.reds 
*** in function: red/binary/to
*** at line: 1 
*** near: [1030x7 
    proto: image/extract-data as red-image! spec EXTRACT_ARGB
]
➜  tmp more hello.red
Red [ needs: View ]
view [ text "Hello World" ]
17:48Any hint as to what I should do to get it to compile?
greggirwin
19:13@MarkoSchuetz_gitlab there have been about 3,000 commits since Android was last touched, so it's a big merge task. Stay tuned though, you might be pleasantly surprised.
pekr
19:26@hiiamboris wait is there only to slow down a loop, forget it then and just print in a longer loop. The result is going to be buffered anyway and not printed unless the loop ends iirc ...
ne1uno
19:34@pekr you can add needs gui to text console you build yourself. the old gui console doesn't block but seems to wait also. but has a few other exit quirks
hiiamboris
19:35@pekr I just gave you 2 solutions to that ;)
GiuseppeChillemi
20:16@greggirwin Oh my God, are you telling me I don't need to have to learn Android studio flutter and dart?
greggirwin
20:21@GiuseppeChillemi correct.
GiuseppeChillemi
20:35God exists
MarkoSchuetz_gitlab
23:11I still live in emacs and would like to edit/compile red from there. Is there an emacs mode? I have looked, but haven't found one, so I guess there isn't. I saw several REBOL modes. Which one would be best suited as a starting point?
greggirwin
23:16I don't know of an emacs mode. Not being an emacs guy, or the state of any of the Rebol versions, it's a toss up. We are highly Rebol compatible, but some of that comes from R2 and some from R3, which are not directly compatible with each other in some ways.
MarkoSchuetz_gitlab
23:58For now I found an emacs keymap for vs code that keeps me from shooting myself in the foot too often.

pekr
05:09@hiiamboris Sorry, but I don't need nor want your 2 solutions, all I need is the proper console behaviour. Do you really expect some eventual newcomer starting to experiment with Red to experience a flashing scroller and no output? Will we suggest such hacks? I'll wait for the full IO and if console behaviour will not change in that regard, submit it as a buggy behaviour ...
hiiamboris
09:35It is submitted already ;)
greggirwin
20:01> Sorry, but I don't need nor want your 2 solutions

@pekr, you said it drives you crazy and he offered you a way to be less crazy *with what we have now*. We all know it's an issue.
DanKokenge_twitter
21:51This might be a crazy idea. I have a client/server system with about 500 users. I use the typical HTML/JS from a server. Since cloud drives are available, would it be possible to place code on a drive that all the users have access to. Since it looks like a local drive to the user, could they execute native rebol/red code. You eliminate the middle part of running a program to produce html code. They run the exe code direct. Development time would be greatly reduced.
greggirwin
21:56That works, as long as users have Red installed locally. You could also have a browser/control-center app they use, written in Red, which makes it easy to run remote scripts. Of course you have security issues and such to consider, but the idea of the X-Net (executable internet) is that it's as easy to send logic as it is to send data.
Respectech
21:56@DanKokenge_twitter That should work. Of course, normal security considerations should be taken into account. The main reasons one may want to have the code run in a browser is because it has integrated printing, scrolling, resizing, etc. In Red, many of those things would have to be provided by the developer. But agreed, the application should be able to be created much more quickly in Red than in HTML/JS.
loziniak
22:20@DanKokenge_twitter There was something like IOS in Rebol world, seems just like what you describe:
http://www.rebol.com/index-ios.html
greggirwin
22:25IOS was different in that it did a lot more than just run remote files. It had fine-grained access control, and every app (reblet), including IOS itself, could work against one or more filesets. Those filesets synced locally when you connected to the server so you were always running against a local environment, unless you wrote apps to do otherwise. I built an entire distributed health-club management system on top of it, along with @rgchris.
loziniak
22:30could be a completely alternative internet :-)
22:32do you have any other materials on it? the design, APIs, etc? I'm working on a project that gets some inspiration from this idea.
22:35can I download it somewhere, or was it more a closed, commercial product?
greggirwin
22:35It was a commercial product.
loziniak
22:35perhaps we should continue in chit-chat.
greggirwin
22:36Yup, though I'll be head down for a bit here.
loziniak
22:41same here :-)

ralfwenske
08:46Installing red on Linux Mint 20 (as suggested Ubuntu 18.04+ version) I get:
ralf@ralf-Lenovo-Yoga-2-13:~/Desktop$ sudo apt-get install libc6:i386 libcurl4:i386 libgdk-pixbuf2.0-0:i386
Reading package lists... Done
Building dependency tree       
Reading state information... Done
libgdk-pixbuf2.0-0:i386 is already the newest version (2.40.0+dfsg-3).
libc6:i386 is already the newest version (2.31-0ubuntu9.1).
libcurl4:i386 is already the newest version (7.68.0-1ubuntu2.2).
0 to upgrade, 0 to newly install, 0 to remove and 0 not to upgrade.
ralf@ralf-Lenovo-Yoga-2-13:~/Desktop$ ./red-08dec20-1c5880827 
Compiling compression library...
Compiling Red console...
/home/ralf/.red/console-2020-12-8-28365: error while loading shared libraries: libgtk-3.so.0: cannot open shared object file: No such file or directory

What am I missing?
rebolek
08:48You're missing 32bit GTK. I have no experience with the prebuild version, maybe it has the View module and requires GTK. If you build yourself from sources you can avoid that dependency if you do not need View.
ralfwenske
08:57The instructions on www.redlang.org/p/download.html say:
(*) For Linux 64-bit distros, you need to install 32-bit supporting libraries.

If you are using an Ubuntu 18.04+ version, you should use libcurl4 with multiarch:

    dpkg --add-architecture i386
    apt-get update
    apt-get install libc6:i386 libcurl4:i386 libgdk-pixbuf2.0-0:i386

Should it not be as simple as that? (having newcomers in mind who might be deterred by this experience).
Or alternatively the instructions there hinting at possible complications?
rebolek
09:07@ralfwenske You're right that it should be easy. I’ll ask where the problem can be. I know that if you build from sources, GTK is not required, I’m not sure why it is with the prebuild version.
ralfwenske
09:10Thanks @rebolek - as view is mostly working on linux also I would like to use it.
btw. I just installed sudo apt-get install libgtk-3-dev to no avail... - I mean installation was successful yet red still complains about missing libgtk-3.so.0
rebolek
09:15IIRC I installed libgtk3 (not dev) and everything was working fine. I am using Manjaro (Arch based), but I can try on Ubuntu and let you know.
09:16I reported the problem - either the exe or documentation must be fixed.
ralfwenske
09:17Thank you - I will see if I can find the 32-bit version and install it.
09:30Following instruction did the trick:
sudo apt install libgtk-3-0:i386
...
ralf@ralf-Lenovo-Yoga-2-13:~/Desktop$ ./red-08dec20-1c5880827 
--== Red 0.6.4 ==-- 
Type HELP for starting information.

Thank you for your help @rebolek
loziniak
09:47That's a good hint to change instructions on download page.
greggirwin
19:08@x8x is the one who usually updates the download page, but we can make sure all the same info is in a wiki page, and have the download page point there if people need more help. Then it's easier for us all to add notes and details.
tinulac-leinad
22:29@ralfwenske @loziniak @greggirwin The same p,oblem occur if you compile an application for linux, on a linux machine foe my case, and try to install it on another linux machine. ok you have to install the 32 bits support on thi.s machine. And the same problem occur.
I try to install libgtk with the same error at run time...
I just send a message to the person who use my app with the command line to test:

GiuseppeChillemi
13:19Hi, is there a way to instruct VID to open its window in a specific screen?
pekr
13:41You can go up in the structure system/view/screens and place it in the pane ... Hmm, strange. In the past with R2, I thought that when I have extended desktop, the resolution is for both screens, but it does not seem to be the case, as view/options [area 100x30 button "ok" [unview]][offset: 100x100] plases it just in regards to one of my displays. Both Red and R2 seem to see only one of my monitors ....
13:50Hmm, I have two 3K displays and the following code places it on the second one (on left side), just without the scaling which is set on my ntb to 125% view/options [area 100x30 button "ok" [unview]][offset: -2560x0]
13:51Btw - the scaling differs between my notebook (125%) and physical monitor (100%)
GiuseppeChillemi
13:53I am going to work on a 4 Monitor Setup:
2x 22"
1x 8"
1x 15,6

I need to choose where to open 2 windows.
pekr
13:57Good luck. Seens are imo not supported yet, simply I would expect two entries in system/view/screens in my case. In the past I do remember getting total area resolution .... you have to calculate it yourself and imo if you change system screen ordering, the coordinates are going to be different imo ....
GiuseppeChillemi
13:58If it is not supported it will be a show stopper for me! :-(
hiiamboris
15:04Not supported IIRC
pekr
15:23IIRC, multiple monitor support was planned for the future ... OTOH you can create your structure / resolution and some coordinate calculation functions. You might as well map some Win32 API funcs, to get some monitor info, but it is a long time ago since I looked into it ... (last time it was trying @greggirwin's Send-keys dialect some 10+ years ago :-)
15:30btw - there has to be some functionality already, filling in the system/view/screens .... maybe it might be the starting point to find out ....
GiuseppeChillemi
17:19I need to output some notifications on a secondary screen and open it always on the same place. I don't know absolutely what to do.
Oldes
17:34You can start here: https://github.com/red/red/blob/master/modules/view/backends/platform.red#L830
17:36get-screen-size 0 returns size of the main screen... if you have 2 screens you can use get-screen-size 1 to get screen size of the second one
17:37Of course.. there will be more obstacles on your way.
17:39You may want to start trying to implement get-screen-count which will return number of screens available.
17:40Using get-screen-size as a [template](https://github.com/red/red/blob/master/modules/view/backends/platform.red#L541-L548)
17:42You will have to implement it for each platform! Here is [windows' version of get-screen-size](https://github.com/red/red/blob/028f39ca1da781549524e6b26c79dae2201da44e/modules/view/backends/windows/gui.reds#L1153-L1160)
17:47From above code is clear that get-screen-size 1 will not work, as the id is not used. You would have to go deeper the [rabbit hole](https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-enumdisplaymonitors).
GiuseppeChillemi
18:20It's absolutely out of my reach. If someone wants to implement it, here is my **200USD** bounty. The requirement is easy: implement opening a generated iterface VID on a multi-monitor setup, with different resolutions and reading the current position (to save and open again it later). Real money via PayPal, no bitcoin.
18:28Anyone interested, please, inform me if you are going to implement it. First come first served: if someone will write "I will implement it", the bounty will not be available to anyone else.
pekr
18:47Would resulting code be openi mean, for a greater good, so that it could become part of the Red? If so, I will gladly add 50 Eur to the bounty 🙂
GiuseppeChillemi
18:49I for open code too: same license as Red.
hiiamboris
19:33On Linux I presume?
GiuseppeChillemi
19:34Windows but if a good part of the code could be used in Linux too and the developer feels he can easily implement it on Linux, I would rise the bounty to **250USD** + **50USD** Petr to have it in both worlds *(!Updated!)*
19:44(Ok, I have stopped updating the previuos phrase!) :)
hiiamboris
19:49I can write you routines (for compiled code) for Windows to work with multiple monitors. Or a custom Red build with those routines included. But to properly fit this into View and PR it, is more work, and I'll do this only if @greggirwin agrees.
GiuseppeChillemi
19:50I have created https://github.com/red/red/wiki/Bounties It needs someone of the core team to write link and mention it somewhere.
Numeross__twitter
19:53Hey everyone, I'm working on an implementation of Bret Victors's "Drawing Dynamic Visualizations". [This](https://vimeo.com/66085662) is the talk about it, he showcases it during the 2 first minutes.
How I see it: it's an editor with which you can draw basic geometric shapes that are dependent on one another.
If you think 'geometrically', you can make rich and dynamic data visualisations without code and fairly quickly.

My base idea is to use a graph instead of a timeline, and that selecting an element informs you of the relationships of that element.

My main goal is to learn that sort of interaction design, and I also want to explore how far I can go about expressing an app/website layout with that.
Maybe a "DOM graph" would be more dynamic, and better suited to a reactive interface ?

Here's my best attempt for the back-end, but... yeah, I don't know, I'm very new to Red. There is probably way better approches ?
https://gist.github.com/Numeross/544b43075d214f37b80a731b963c628b
Should I go straight to a DSL ? I don't know much about these, is there any resources on DSL design ?

Any help very appreciated !

edit: I don't mind a slow or not optimized back-end, but I aim at high expressiveness. On a side note I'm curious to what a custom type system would bring to Red
GiuseppeChillemi
19:55@hiiamboris I prefer having it in the mainstream Red as I would like the whole community would enjoy and use this improvement.
hiiamboris
19:59Then let's wait for Gregg's word ;)
20:24@Numeross__twitter in your code, changes in one vector won't propagate into another vector.
20:28In fact, current reactivity probably won't do at all for your need (because the ownership system is a tree). You'll have to manually craft on-change* and on-deep-change* most likely.
Numeross__twitter
20:28Oh you're right, changing x or y works tho
20:28I see
20:29Thanks for the lead :D
20:30hint ? I don't know which is the word
hiiamboris
20:33"hint" will do ;)
zwortex
21:31Hi everybody. The help room looks the proper place for this one. I came up with the following problem while trying to troubleshoot a script that went rogue, spinning around in an infinite loop. From the console, I could quit the process using ctrl+c or ctrl+pause. From the gui console, I could not and I had to kill the process from the windows task manager. In both cases, however, I'd rather, for debugging purposes, be able to perform halt and go back to the input prompt. Is there a way to do that ? Regards.
Oldes
21:35Try building and using CLI version of the console with View included.. so your own code will not interfere with the GUI console, which is also done in View.
21:37Building this file: https://github.com/red/red/blob/master/environment/console/CLI/console.red but adding Needs: View into the header.
hiiamboris
21:39How would it help him stop the script without quitting the console though?
zwortex
22:26Hi @Oldes, I did your trick with two benefits : now I can output quickly from the gui as it is killing the process, and I can see the console screen refreshed if anything is being printed out during the loop. However as mentioned by @hiiamboris, the signal is not trapped and I can't return to the input, which would be even better. I'll try and see whether I can find my way through that. Cheers.
23:32Hi quick question on object creation. In the following code, label field initialisation fails if using a word value with the same name. That just reveals that initialisation block is evaluated in the context of the duplicated object rather than in the context of the caller. See case (1) nok, compared with (2) with no conflicting names. Is this the desired effect ? Looks strange at first. One would like to be able to split the evaluation of the bloc given to make so as to keep set-words unchanged and eval their values only. Anyway, I came up with various strategies to bypass the issue (2 to 5). Is there a better way for doing this ? Cheers.

o: make object! [
    label: 'object
]
label: 'local
a: make o [ label: label ] probe a/label ; (1) NOK - object
l: :label b: make o [ label: l ] probe b/label ; (2) OK - local
c: make o [] c/label: label probe c/label ; (3) OK - local
d: make o reduce [ to-set-word 'label to-lit-word label ] probe d/label ; (4) OK - local
e: make o compose [ label: (to-lit-word label) ] probe e/label ; (5) OK - local

greggirwin
00:39@zwortex see https://github.com/red/red/wiki/%5BDOC%5D-Object-Notes
hiiamboris
10:00compose is my favorite way for that
10:11As for "looks strange at first", it's aimed at this behavior:
object [
   x: 1
   y: x * 2          ;) uses 'x' from the same object
   f: does [x * y]   ;) uses 'x' and 'y' from the same object
   ?? x ?? y         ;) debugging
]
10:13none of it would be possible if evaluation happened in some other context
zwortex
12:09Thanks @greggirwin for the link (handy faq), Thanks @hiiamboris for your comment.

The compose strategy is the good practice, then. It is also the one used for passing initial values to a view, as I've read somewhere else.

I said it looked strange as in my example, the spec. block was merely used for initialisation, not for specification. Indeed, I had used in my code a 6th alternate, that is to use a creator function instead.

o: make object! [
    label: 'object
    create: function [
        label [word!]
        return: [object!]
    ] [
        n: make self []
        n/label: label
        return n
    ]
]
o1: o/create 'o1
o2: o/create 'o2


It avoids mixing specification and initialisation, local context and target context. In addition, it gives the ability to perform type checking and whatever needs to be done at initialisation time.
16:57Hi, I got this one as well. While parsing, I found that context is not kept in case of recursive rules. For instance :

expr: [ any val ]
val: [ digit | "(" s: expr ")" e: (print [index? s index? e]) ]
digit: charset [ #"0" - #"9" ]
parse "1(2(3))4" expr ; (1)


Command **(1)** prints out 5 7 and 5 8 whereas I would expect 3 7 and 5 8

The same goes with copy operation. Is it this the expected behaviour and should I handle the variables myself or is there another way of doing it ? Regards.
hiiamboris
17:08This is indeed expected. There's no magic involved that would make Red predict your intent ;)
17:12Most natural way to make any word work like a stack is to use a stack. You have one for free - in function calls. Otherwise, just append & take/last into/out of a block.
17:13Parse is a stack too but it does not touch your words (without an explicit instruction to do so).
zwortex
17:19@hiiamboris. Thanks for your reply. I guess the following falls into the same category ?

Collect/keep do not synchronise in case of backtrack :
str: copy ""
collect: [ collect into str test ] 
test: [ ab | ac ]
ab: [ a b ]
ac: [ a c ]
a: [ keep "a" ]
b: [ keep "b" ]
c: [ keep "c" ]
parse "ac" collect
probe str


However in most cases, the only purpose of using collect/keep is to report matched rules not to report rules that were matched but subsequently backtracked. I'd rather have keep only keep results where the rules are not backtracked.

I've done something like this (same as the stack you mention) to do the job (at rule level), but I'd rather have it done whenever a backtrack takes place, as per default :

str: copy ""
enter: func [] [ append str "-" ]
success: func [] [ remove find/last str "-" ]
failure: func [] [ clear find/last str "-" ]
keep: func [ v [string!] ] [ append str v ]
test: [ ab | ac ]
ab: [ (enter) a b (success) | (failure) fail ]
ac: [ (enter) a c (success) | (failure) fail ]
a: [ copy v "a" (keep v) ]
b: [ copy v "b" (keep v) ]
c: [ copy v "c" (keep v) ]
parse-trace "ac" test
probe str
hiiamboris
17:36:+1:
See, how Red bends? ;)
toomasv
17:36@zwortex
One way to get what you expected:
memory: clear []
expr: [any val]
val: [digit | "(" s: (append memory index? s) expr ")" e: (print [take memory index? e])]
digit: charset [ #"0" - #"9" ]
parse "1(2(3))4" expr
3 7
5 8

hiiamboris
17:43And by the way, if there was a realistic way to backtrack execution of arbitrary pieces of code, Parse would've had this option ;)
zwortex
18:01@toomasv, thanks. I get it. Works fine. Keeping track of intermediate values - like doing assembler - or hp calculator with reverse polish notation.
@hiiamboris, I am not talking of universal backtrack but just the values collected with keep. Keep collects things in a series, that could be used as a stack - whenever you backtrack you pile out whatever was produced that should be abondonned. Exactly what the code is doing by hand at the expression level but that could be automatic and for each rule and alternate.
hiiamboris
18:33Nothing comes for free. I'm sure you will be able to see the drawbacks this approach brings.
18:45Tell you what. Design this. Backtracking of set-words and of collect parse keyword. And the interplay with keep function (which does not currently sync with parse's keep, but should). And with manual modification of the collected into series (with append/remove etc). And scenarios when you don't want to backtrack - how you handle this. And evaluate the performance cost. I'm sure the team will gladly weigh your design and if it will be beneficial, I don't see why it shouldn't be used.
GiuseppeChillemi
18:47I remeber having asked it before but I don't remeber the answer, I apologize I have to ask it again: is there a way to drag & drop to a Red window?
18:48And there is a way to intercept the new clipboard content?
hiiamboris
19:04Not implemented.
ne1uno
19:06GiuseppeChillemi you can use SendTo on many window managers and Windows to pass filenames like commandline options
GiuseppeChillemi
19:07Bonus included in bounty? O:-)
21:15@ne1uno Could you make an example? I have not understood.
ne1uno
21:19which OS? for windows, put a shortcut of your program in c:\Users\YOURLOGIN\AppData\Roaming\Microsoft\Windows\SendTo\ then right click sendto will make the filename[s] available on the commandline
21:19not exactly sure how on other OS, but it's probably easy to find info
zwortex
21:29@hiiamboris, you make it an enormous step. I don't see why. If collect handles the collecting series on its own, it only has to stack in calls to keep, and in case of backtrack, stack out whatever was collected since the last alternate. That would work even when collecting into an external series, provided that nobody messes with it and even so the parser could still set itself as the owner of the series and be warned of any advert changes, possibly abort. Therefore, as much as I understand the subject, the current behaviour of collect/keep just limits its use to non-backtracking grammars and/or data. That is probably fine in most cases anyway. If not, one can still perform the cleanup manually, as I have done. I should try also the callback provided by the parser that looks pretty handy for that purpose. Let me thank you by the way for your support those last few days, as I was performing my first steps into Red programming. Have a lovely weekend. Cheers.
hiiamboris
21:37:+1:
greggirwin
21:49@zwortex on object specs and evaluation, this is something else that could be fun for you to play with. Just because make works one way doesn't mean it has to be the *only* way. You could write a dialect to match the semantics you prefer. I often suggest that people do things at the mezz level, because it's easy to play that way, show others something that they can touch and play with, and also gives us a written history of ideas.
GiuseppeChillemi
22:04@ne1uno I am on Windows10 but I want to drag&drop mostly URLs
ne1uno
22:05from a browser?
22:07if something is in your clipboard, you can easily copy & paste. why d&d?
22:13if you put a shortcut on win10 desktop, you can drop on it to get a file name, it may work with URL
GiuseppeChillemi
22:23I want to drag an URL to a window and let it intercept the URL.
ne1uno
22:27an already open window would need to accept drops, so not quite the same.
GiuseppeChillemi
22:32Also Copy would be good. I suppose I have to poll the clipboard.
22:32(for URL text)

GiuseppeChillemi
22:47Is it possible to use images as backgroud of buttons or other elements?

toomasv
07:20At least on Windows it is possible:
img: draw 76x25 [pen off fill-pen red box 0x0 75x24 pen violet text 5x3 "Img-button"]
view [button with [image: img][probe "hi"]]
07:21[![image.png](https://files.gitter.im/5780ef02c2f0db084a2231b0/ldiN/thumb/image.png)](https://files.gitter.im/5780ef02c2f0db084a2231b0/ldiN/image.png)
GiuseppeChillemi
07:50Thank you, let's see if it will be possible in the Android version. People are more visual there than here.
Oldes
08:28@toomasv I have different result... looks like Red does not work well with scaling not exactly 100%
08:28[![image.png](https://files.gitter.im/5780ef02c2f0db084a2231b0/WEIK/thumb/image.png)](https://files.gitter.im/5780ef02c2f0db084a2231b0/WEIK/image.png)
toomasv
08:38Yes, resolution handling is not automatic. I think it can be solved in R/S, but I haven't tried.
Oldes
08:48I think that is a major issue. I don't think there is anybody working on modern high-resolution notebook with scaling set to 100%. I also understand it is not easy to deal with.
hiiamboris
10:06I think this is a glitch somewhere. Draw is supposed to be independent of OS and DPI. That is Draw default font size should be fixed and it should produce consistent results everywhere.
11:01https://github.com/red/red/issues/4759 reported
Oldes
12:25When we are talking about resolutions... I highly dislike that Red scales content according DPI settings... I would like to be able to turn it off and use maximum screen resolution instead. I want to have sharp original sized images instead of blurry scaled ones.
hiiamboris
13:10Make a wish ticket for this option maybe?
Oldes
13:58I will.. one day.. it needs some time to prepare argumentation which I don't have now. I just know that I like to have things under full control which is apparently not possible now in Red.
pekr
14:21@Oldes - not sure how difficult should it be either. Imo system/view/screens structure should, apart from resolution, contain such metric as scaling. Remember - you can have different scaling for different monitors.
Oldes
14:24Yes... that is related... I don't have system/view/screens/1/size == 1706x960 as Red now reports, but 2560x1440 (because I have scaling 150% not to have everything too small)
pekr
14:34I have 14,1" display with native 2560x1440 resolution, but set to FullHD 1920x1080and 125%scaling. Red reports my screen as being of 1536x864 ....
Oldes
14:41You cannot expect 1920x1080 from 2560x1440 using 125% scaling! But 1536x864 is strange. I would expect 2048x1152 for 125%
pekr
14:44But I have it set to FullHD in a Windows dialog box. The notebook though, has a higher real reasolution.
Oldes
14:44Ah... so you are even not using native resolution.
pekr
Oldes
14:45Why? :)
pekr
14:45Because 2560x1440 on a 14.1" display is a bit of a masochism :-) We bought such variants because the display has nic other parameters ...
Oldes
14:46You can just use the scale settings.
pekr
14:47It's not the same - similar, but not the same - as scale allows you to use only 125, 150, 175, 200% values?
Oldes
14:47Although I can understand your reasons, if you are still using Rebol2.
14:48It's not same... in your setup you have everything blurred.
pekr
14:48Most of the time, I use external monitor, so I don't mind, but at home, just with notebook, I use it like that. It was also a problem related during presentations on a projector (beamer), which supports only FullHD and then scales down so badly, that you could hardly read icon descriptions ...
bubnenkoff
18:40Why next code is work different? I thought slash is way to not depend on / or \

>> first split last split "F:\zak_data\notifications\test\fcsNotificationEA44_03731_318.txt" slash "_"
== "F:\zak"
>> 
>> first split last split "F:/zak_data/notifications/test/fcsNotificationEA44_03731_318.txt" slash "_"
== "fcsNotificationEA44"
hiiamboris
18:46> I thought slash is way to not depend on / or \

It's not. to-red-file is.

zwortex
13:03@greggirwin, I think I get the idea. I'll try to include that in my demo. Cheers.
16:05A question regarding objects in Red.

As there is no class in Red. Whenever you create a new object, I assume the code is duplicated as well.

If you have a lot of tiny objects, and a lot of functions, that is certainly bad in terms of memory. Is there a pattern to prevent that ?

I've made the following attempt in that respect : use a context object to hold the code, and data objects for the values, like the stateless servlet vs the cookies. Is this the same pattern to use for handling objects in Red when they are numerous ?

;; A pattern for handling lots of objects
obj: context [
    ; data object
    data: make object! [
        _ctx: none
        x: y: none
    ]
    _check: function [o [object!]] [
        if not in o '_ctx [
            make error! "Expecting self/data object"
        ]
        if not same? o/_ctx self [
            make error! "This obj does not belong to me !"
        ]
    ]
    create: function [x [integer!] y [integer!] return: [object!]] [
        o: make data compose [_ctx: (self) x: (x) y: (y)]
        return o
    ]
    show: function [o [object!]] [
        _check o
        print [ o/x o/y ]
    ]
    ;; the rest of the code
]
myo: obj/create 1 2
obj/show myo
hiiamboris
17:11Explicit reference like you do is one way. Implicit reference via bind is another. But you got it right: code should stay in a shared context rather than be duplicated.
zwortex
20:42@hiiamboris, not sure to understand the meaning of what you're saying about implicit reference via bind. In the following, is there a shared code between obj, ob1 and ob2 - meaning the binding takes place anytime you call the function, or does the binding takes place at copy time ?

obj: context [
    x: none
    show: function [] [
        print x
    ]
]
ob1: make obj [x: 1]
ob2: make obj [x: 2]
ob1/show ; shows 1
ob2/show ; shows 2


By the way, is this a bug ? Obj function with a global word is not rebound if a copy is made of it.
x: "global"
obj: context [
    show: function [] [ print x ]
]
ob1: make obj [x: 1]
ob1/show ; show global
hiiamboris
22:09That's not a bug. That's a gray area of current design ;)
I've stumbled upon it too.
Another logic would be: print x was a working function, with x: 1 it may be broken, so why break it? (but even this logic doesn't apply in some cases, sadly)
22:11Binding takes place after make creates the object (and before evaluating the spec). But my point was that you can use bind to rebind words after they were made. Remember: word is a symbol+context reference. That reference is yours to change as you see fit.
greggirwin
23:43More notes for the object wiki.

zwortex
10:32@hiiamboris, still on the implicit vs the explicit, have you got in mind something like (1) vs (2)

myprint1: function [o [object!]] [ ; (1)
    code: bind [ print [x y] ] o
    do code
]
myprint2: function [o [object!]] [ ; (2)
    print [o/x o/y]
]
myobj: make object! [x: 1 y: 2]
myprint1 myobj
myprint2 myobj


It would be **nice** if (1) could be written:
myprint3: function [o [object!]] [
    with o [
        print [x y]
    ]
]
10:38@hiiamboris, regarding the function bound to the global context that is not rebound when duplicated. That makes sense not to alter non local bounds. Though, it looks better to me, if you reset everything in the new context whatever it is. If you don't want that, you may still use explicit paths (in that case system/words/x - that might as well be renamed something more generic, like @, /, root or world). Then the bind would work the same be it the first time it is used, or another time : collect every set-words in the given block (and those would already be known), bind against the new context, done !
You've got similar problems when handling excel formulas : shall I use fixed or relative cell references. You may have both, but the style of the reference is not ambiguous. It derives from the writing of the reference : $A$1 or A1. Similarly, whatever word is written plain should be relative and therefore repurposed anytime a bind takes place, and whatever is written with the full path can be kept as is. The same with reference to files that either a full path, when starting with /, or a relative path.
rebolek
10:38with was in R3, I believe it was just a mezzanine function, basicaly like this: with: func [ctx code][do bind code ctx]
giesse
11:25with is trivial to add, but, performance is going to be bad in the interpreter, and the compiler won't know what to do with it. Which is why it's not there and generally people are encouraged to do things differently.
(I'd do bind/copy, but other than that it's just what @rebolek posted)
greggirwin
20:44My old with used bind/copy. It's a heavier solution, but with is very nice in use, IMO.
20:45My heaviest use of it was probably in UI data exchange code with faces.
GiuseppeChillemi
22:12About objects "dark areas", I was trying to clone a function context in Red and Rebol but I had not the expected results:

FF: Func [ /local arg base-obj proto final-obj] [

    arg: 22
    base-obj: make object! [arg: none]
    proto: [arg: arg]
    final-obj: make base-obj proto
    final-obj
] 
probe ff


>> probe ff
make object! [
    arg: none
]

22:12Expected 22
hiiamboris
22:52read https://github.com/red/red/wiki/[DOC]-Object-Notes
22:52the beginning
GiuseppeChillemi
23:41Thanks, I have imagined the arguments words context were set to the object one.

GiuseppeChillemi
00:01Otherwise I should do something like this (untested, I am in my bed)
00:02
Obj: make object! [a: b: c: none]
C: 33
B: 44 
Words: [b c]
Forall  words [
   Set in obj first words get first words 
]
00:02Oops ;-)
09:40While waiting for WORDS-OF reflector to work on Red function context, could someone tell me why WORDS-OF is stealing words in Rebol:

a: func [arg arg2][probe words-of bound? 'arg]
>> a 1 2
== [arg2]

09:43Note: using first reflector in place of WORDS-OF it works
09:43
a: func [arg arg2][probe head first bound? 'arg]
>> a 1 2
[arg arg2]

09:47Even values-of suffers from this problem.
Oldes
11:17Because it was buggy? Rebol3 does not allows access function! contexts:
>> a: 1 type? bound? 'a
== object!

>> do has [arg] [type? bound? 'arg]
== logic!

> You can't access function! contexts except during the running of the function, so BIND? shouldn't return the context. Having BIND? return true allows you to still tell whether the word is bound.
https://www.curecode.org/rebol3/ticket.rsp?id=886
11:20I don't think it's good idea to mess with function context bindings like you are trying to do.. although you may achieve somehow working state of what you are trying to do, you will create a very hard to debug code!
GiuseppeChillemi
14:38@Oldes I am trying to duplicate the function context to a normal one. I can do this but I have to get the words ed the values before passing them to the duplicator function.
Oldes
14:52Ladislav was asking years ago that Rebol3's bind? in function context could return function itself instead of true.. that could help you achieve what you are trying to do.
14:55It is exactly what Red does now:
>> f: func[arg1 arg2][type? context? 'arg1] f 1 2
== function!
>> f: func[arg1 arg2][spec-of context? 'arg1] f 1 2
== [arg1 arg2]
zwortex
15:58@rebolek, @giesse, @greggirwin - Thanks for the hints regarding with. As I understand, nice solution but possibly heavyweight.
GiuseppeChillemi
21:56@Oldes It's not the whole context, just the words. If you try to reduce it you get an error. You have to bind it's words to the function context and then reduce it.
21:58
f: func[arg1 arg2][
    reduce bind spec-of context? 'arg1 'arg1
] f 1 2
== [1 2]


But yes, I can clone the function context in this way.
22:02Curiosity goes beyond your current goal so:

>> reduce spec-of :f
*** Script Error: context for arg2 is not available
*** Where: reduce
*** Stack:


You ask yourself why the error is on ARG2 before than ARG1!?

Oldes
08:37It should be in red/bugs than... I think that source of above behaviour is, that Red does not copy requested spec and body of the function.. which may lead to situations like:
>> f: func[a][probe a] change spec-of :f 'b source f
f: func [b][probe a]
08:40> it's not the whole context, just the words..

because the spec-of is used.. not just context?.. and it's not just words.. it's function's spec block!
>> f: func["Test" arg /ref][spec-of context? 'arg] f 1
== ["Test" arg /ref]
08:53> You ask yourself why the error is on ARG2 before than ARG1!?

That is exactly the reason, why I said to you many times, that you are on a way leading to troubles! [last time here](https://gitter.im/red/help?at=5fd9ecde7beb2f6e63b5f18c)
09:04@GiuseppeChillemi you may want to use something like:
f: func["Test" arg1 arg2 arg3 /local w spec][
	print ["arg1:" arg1 "arg2:" arg2 "arg3:" arg3]
	spec: spec-of context? 'arg1
	parse bind spec 'arg1 [any [
		set w word! (
			print [w "=" mold try [get :w]]
		)
		| /local to end
		| 1 skip
	]]
]
f 1 2 3

But I must ask myself, why?
tinulac-leinad
09:20Hi,
Compilation problem on linux :
red-lastest code.red : ok
red-lastest -c code.red : ok
red-lastest -c -r -t windows code.red : ok
red-lastest -c -r code.red :
daniel@daniel-Lenovo-ideapad-500-15ISK:~/Apps/red/red_projets/dn-abc-tools$ red-lastest -c -r -o bin/load-abc load_abc.red 

-=== Red Compiler 0.6.4 ===- 

Compiling /home/daniel/Apps/red/red_projets/dn-abc-tools/load_abc.red ...
...compilation time : 1901 ms

Target: Linux 

Compiling to native code...
*** Compilation Error: argument type mismatch on calling: red/natives/repeat-init* 
*** expected: [struct! [
        header [integer!] 
        data1 [integer!] 
        data2 [integer!] 
        data3 [integer!]
    ]], found: [struct! [
        header [integer!] 
        ctx [pointer! [integer!]] 
        symbol [integer!] 
        index [integer!]
    ]] 
*** in file: %/home/daniel/Apps/red/red_projets/dn-abc-tools/load_abc.red 
*** in function: exec/f_ctx||394~value-path?
*** at line: 1 
*** near: [
    r3: 0 
    stack/reset integer/push 0 
    stack/mark-loop ~repeat 
    while
]

An Idea ? If can give the code (just simple thing for test..)
Thanks
.Daniel
bubnenkoff
14:11
Red []

thread_number: to-integer take second split system/script/args "="
print thread_number

Why 57 and not 9?
>> do/args %test1.red "-a=9"
57


rebolek
14:12
>> to integer! #"9"
== 57
14:13try something like
>> to integer! form #"9"
== 9

or this
>> load form #"9"
== 9
bubnenkoff
14:1457 is a code of "9"?
rebolek
14:14yes, see ASCII table
hiiamboris
15:32@tinulac-leinad can you give us a code snippet so we could reproduce the bug?
Oldes
20:30@tinulac-leinad please... use [GIST](https://gist.github.com/tinulac-leinad) instead of such a large and broken blocks of code pasted here next time!
hiiamboris
20:37Gitter truncated them.
20:39@tinulac-leinad also please remove all stuff from your code that's irrelevant to error reproduction.
tinulac-leinad
23:26@hiiamboris @Oldes
OK, I have put all the code in one file.
https://gist.github.com/tinulac-leinad/4e57809984f7310a971304986d06ae6b
Thanks for help !
Daniel

greggirwin
02:06@tinulac-leinad without an ABC file to test with, I can't check the full functionality, but I can dupe the compiler error on Win10. Since I get it with -u as well, it seems to be in the runtime compilation. You know your code, so it would help if you can pare it down to an absolute minimal example that produces the problem.
02:11needs: 'view 'util isn't correct, as it won't see the second value. Unless you've done some deep work, there is no util module I know of.
02:23I've narrowed it down to your declarations section, which is interesting. More interesting is if I have *only* those in the script, it compiles, but if I have something after it (so far the `parse-abc-line func commented out), it errors compiling.
02:30I stand corrected, and now have the culprit down to this section:
tunes-list: copy []
sets-list: copy []
tune: object [
  A: B: C: D: E: F: G: H: I: K: L: M: N: O: P: Q: R: S: T: X: Z: ""
  melodie: []
]
02:30I'll let someone else take it from there.
tinulac-leinad
08:44@greggirwin Hi Gregg,
Yes 'util is no more necessary , I have put all code in the same file for the moment.
Here is an ABC file for test purpose.

https://gist.github.com/tinulac-leinad/390b696646c63be18cb58c7c6fe0d392

notice that I canr run the code with no error with :
red-latest load-abc.red
red-latest -c load-abc.red is also ok
red-latest -c -r -t windows load-abc.red again ok ?
only red-latest -c -r load-abc.red give the error and, of course red-latest -c -e -r load-abc.red is also ok
I don't see what can make , in my code, the diff beetwin -c option and -c -r option ?
I'll try today to isolate parts of code and compile... maybe I can isolate better the cause...
toomasv
09:36@tinulac-leinad -c is flag for development -r is for release. No sense to use these together.
tinulac-leinad
14:52@toomasv Sorry ok for -c and -r options. But with only -r the result is the same...
The part of my code where the problem come il here.
tune: object [
  A: B: C: D: E: F: G: H: I: K: L: M: N: O: P: Q: R: S: T: X: Z: ""
  melodie: []
]
import-abc-list-from-file: function [ file /extern tunes-list tune ][
  doc: read/lines file
  attrs: charset [#"A" - #"T" #"X" #"Z"]
  foreach line doc [
    parsed-line: parse-abc-line line false
    if find/match parsed-line "X:" [
      current: length? append tunes-list copy/deep tune
    ]
    either parse/part parsed-line [attrs #":"] 2 [
      attr: to-word first parsed-line
      tunes-list/:current/:attr: parsed-line
    ][
        append tunes-list/:current/melodie parsed-line
    ]
  ]
]
either exists? F_TUNES_LIST [
  tunes-list: load F_TUNES_LIST
][
  import-abc-list-from-file request-file/title/file/filter
          "Select ABC Files "
          "%./data/sources"
          ["ABC Files " "*.abc"]
  save-data
]

and probably in the import-abc-list-from-file function
Notice that when the code is excuted the list of objects "tunes-list " is created in memory and tunes-lists/.../OBJ-attr give a good resut ..
smotti
15:09greetings. is there some documentation about the #system directive?
15:16it seems to be only mentioned in the Red/System spec under the #call directive in an example how to use call. but nothing about it in the red docs in the github repo.
hiiamboris
15:29@smotti Hi. It seems you're right. I can't find it too ;)
15:30Care to post an issue to https://github.com/red/docs/issues/ ?
15:31The only description I've found is in the [](https://github.com/red/red/commit/c9cfa3f07783e0ca164bd040d890b9ef43bab65b) commit message
smotti
15:40will do. thanks for that commit link.
greggirwin
19:20@tinulac-leinad I narrowed down the problem.
Red []

; Error
;A: B: C: D: E: F: G: H: I: K: L: M: N: O: P: Q: R: S: T: X: Z: ""
;A: B: C: D: E: F: G: H: I: K: L: M: N: O: P: Q: R: S: T: X: Z: none
;A: B: C: D: E: F: G: H: I: K: none
;A: B: C: D: E: F: G: H: I: none		; 9 Items  I: is a trigger
;A: B: C: D: E: F: G: I: none
;A: B: C: D: I: none
;A: I: none
I: none		; minimial example. It's case sensitive.

; OK
;A: B: C: D: E: none
;A: B: C: D: E: F: G: H: none
;A: B: C: D: E: F: G: H: K: none	; 9 Items
;i: none
19:21That is I: none is the culprit. Gives the same repeat-init* error. Please open a ticket for that.
19:24Also, in your original example, your single letter fields all refer to the same string, not different empty strings.
tune: object [
    A: B: C: ""
]
append tune/a "AAA"
append tune/b "BBB"
print tune/c

See [this](https://github.com/red/red/wiki/%5BDOC%5D-Why-you-have-to-copy-series-values) for a detailed explanation.

tinulac-leinad
00:15@greggirwin
HI gregg,
I have a simpified version of the code In the red REPL it do what it does load a list off musical pieces in a series (tunes-list) of objects (tune) . then you can access to one object of the list ads its attributes with success.
the code modified is here : https://gist.github.com/tinulac-leinad/4e57809984f7310a971304986d06ae6b
and a data files for tests is here : https://gist.github.com/tinulac-leinad/390b696646c63be18cb58c7c6fe0d392
results after do %load-abc.red
>> length? tunes-list
== 75
>> tunes-list/75/melodie
== [{|:DE/2F/2|G2 G2 G2 G2|GABG E2 D2|B2 B2 B2 B2|BcdB A3 A|^/} "BcdB G2 G2|GABG E2D2|DEGA BddB|A2 G2 G2 :||^/" "|:A2|BcdB ...
>> tunes-list/75/T
== "T: 29-3 Drunken Piper (jig)^/"
>>

Fine I hope, but....
I have add /binary to write and load files where I save the entire list of object... else I have a wrong list of lines...
AN now, its ok when I run do %load-abc.red in repl but at compile tine with -c or -r I have an error
-=== Red Compiler 0.6.4 ===- 

Compiling /home/daniel/Apps/red/red_projets/dn-abc-tools/test.red ...
...using libRedRT built on 18-Dec-2020/23:22:11
*** Compilation Error: load has no refinement called binary 
*** in file: /home/daniel/Apps/red/red_projets/dn-abc-tools/test.red
*** near: []

And if I delete the /binary but not for the write (/binary is ok for compile) refinement in the code.
1 ) the code compile with -c but not with -e
2) at the object list is created with success at the first time but at the second the ist is created from file and is erroneous cause of the non binary save.

There are 2 thing that lock wrong here.
- the /binary for save that work in repl but dont compile.
- the code that compile fine with -c but not whith -r
As you can see I am a newbee to red and your previous answer make me confusing.. Ok, after verification and correction, it work now (thank for help) but the fist error at compile time (-r only) continue and I have that curious error with the /binary refinement.
Cordialy,
Daniel



greggirwin
03:44I can't review right now, but note that you still have I: in there, which I deduced was the source of the compilation problem.
tinulac-leinad
10:08@greggirwin Hi gregg,
Well I have prefixed all the A: B:.... with "t" tA: tB:... and so on.
Like that the program compile fine.... it's ok (owether I don't figure why "I" for an attibute name is a problem).
The second problem is the impossible use of the load/binary refinement at compile time but works fine in a REPL.... Is this a bug or lack in the compiler ?
A solution will be tu use a map! instead of object! but I am not sure that one of the values element of a map can be of a different type ? and if it is possible that one of the values can be a serie ....
hiiamboris
10:17Where did you get load/binary from anyway?
10:18What's it even supposed to do?
tinulac-leinad
14:42@hiiamboris /binary is a refinement for read and write.
The interest is to load a complete serie, for example in one command.
I want to store ans load a serie of objets. in my example 75 objects stored fro memory and load again with one line of code.
But, i don't know why, il work fine in the REPL and at compile time te refinement is not know by the compiler.
saving the list without /binary cause a bad list in memory 225 lines of text insted of 75 objects and of course you can't access the objects and attributes as needed.
The refinement is explained on the doc and here https://www.red-by-example.org/#load
I hope that if we can use it in rep and not compile is probably a lack or bug in the compiler.
As a newbie with Red I let another verify if my idea is write and pos an issue if needed.
hiiamboris
15:33compiler won't let you override critically important Red words
15:34I suggest using Redbin for this
15:38documented [here](https://github.com/red/docs/blob/master/en/redbin.adoc)
Numeross__twitter
17:56Hello !
It'd help me to know if there's some way to compose a block with given variables' paths.
Here's an example:
foo: 3
bar: [30. 60.]
parents-data: #(
    factor: 'foo
    vector: 'bar
)
code: [     ; block I want to compose
    (vector/1 * scaling-factor)
    (vector/2 * scaling-factor)
]

Thanks :)
18:31idk why I didn't think to parse the block, I'll do that but let me know if there's an other way
toomasv
18:48Not sure if I got correctly what you want to do:
parents-data: #(
    factor: foo
    vector: bar
)
code: [     
    (pick get parents-data/vector 1) * scaling-factor
    (pick get parents-data/vector 2) * scaling-factor
]
;>> [30.0 * scaling-factor 60.0 * scaling-factor]

NB! Map values are not evaluated on creation.
greggirwin
18:49@tinulac-leinad the I: issue is a bug, please report it.
18:52On saving and loading, note that the RBE page says "*certain types* of binary files can be handled".

Serializing basic data is really easy in Red. Just use save and load. If you have objects, you need to reduce the loaded data so they are constructed. Redbin should only be needed (and it's new-ish so report errors there) if you have cycles in your data structures.
18:56@Numeross__twitter as @toomasv's example shows, you'll need to give Red a little help to find the data. code has no idea where to look for vector without that.
hiiamboris
19:25> Redbin should only be needed (and it's new-ish so report errors there) if you have cycles in your data structures.

Without mold/all support for all types, it's needed much more often ;)
Numeross__twitter
20:14@greggirwin @toomasv Ok, I see, thank you !
It's not exactly what I had in mind, but I don't think what I was trying to do was the best solution anyway. I think bind will do
greggirwin
20:25@Numeross__twitter note that maps aren't a context, so you can't bind to them.

@hiiamboris indeed. Let's chat about it.
hiiamboris
21:13sure
tinulac-leinad
23:29@greggirwin Thanks Gregg! all work fine now with save and reduce load... and do no "I:" ;)
Daniel

litew
13:23Is there a way to send requests to website with self-signed SSL certificate? As workaround I added curl [options](https://github.com/red/red/blob/master/runtime/simple-io.reds#L1779) to allow insecure requests and it worked but I'm not sure this is proper way to fix this.
Numeross__twitter
14:51Hello !
I have an issue, and I have nailed it to the fewes lines I could.
I could do what I want in a simpler way, but I would like to know why this doesn't work.
Here I have the path 'scale1/scaling-factor that turns into 'graph/nodes/scale1/data/scaling-factor as intended.
Then I want to separate the path after 'data into two :
; process the path to have the actual path
edge-path-to-actual-path: func [path] [

    ; this works as intended
    ;return 'graph/nodes/scale1/data/scaling-factor

    rejoin ['graph/nodes path/1 'data (next path)]
]

to-path: edge-path-to-actual-path 'scale1/scaling-factor

; separates after 'data
probe parse to-path [collect [keep thru 'data keep [some word!]]]

What is going on !?
hiiamboris
14:59should be rejoin ['graph 'nodes .. I guess
15:01no, ignore that
15:08the next path part is wrong instead
15:08
>> type? fifth to-path
== path!
15:10Suggestion: change rejoin to as path! compose [graph nodes (path/1) data (next path)]
15:13You should also use keep pick else you get a path within a path. Using blocks for visualization:
>> probe parse as [] to-path [collect [keep thru 'data keep some skip]]
[[graph nodes scale1 data] scaling-factor]
== [[graph nodes scale1 data] scaling-factor]
>> probe parse as [] to-path [collect [keep pick thru 'data keep some skip]]
[graph nodes scale1 data scaling-factor]
== [graph nodes scale1 data scaling-factor]
15:14And be careful with overriding to-path. It's a builtin function, never know what may break.
Numeross__twitter
15:15Thank you a lot !
16:02Here's how I solved my problem :
>> compose [('a/b)]
== [a/b]
>> compose [(as [] 'a/b)]
== [a b]

rejoin and compose don't un-nest paths
Thanks again for your help :D
hiiamboris
16:07Right! Glad you figured it out ;)
greggirwin
19:11@litew what option are you using with Curl? @rebolek is one of our resident experts in this area, but maybe https://github.com/red/red/wiki/%5BDOC%5D-Guru-Meditations#how-to-make-http-requests is enough info to get you there.

rebolek
07:24@litew I believe it shouldn’t be a problem. What errors are you experiencing?
08:12@litew Sorry, you’re right, it’s not possible to read a site using self-signed certificate. I believe it would be possible once we switch from SimpleIO to FullIO.
09:00Actually it should be possible in the current IO branch, but it’s not very user friendly yet.
litew
14:18@greggirwin @rebolek So it's well known thing so it's totally OK for me, I'll just continue merging my ugly hack after every git pull :)
14:19simple-io:

#define CURLOPT_SSL_VERIFYPEER  64
#define CURLOPT_SSL_VERIFYHOST  81

request-http: func [
...
curl_easy_setopt curl CURLOPT_SSL_VERIFYPEER 0
curl_easy_setopt curl CURLOPT_SSL_VERIFYHOST 0
...
rebolek
14:27@litew if you feel adventurous enough, you can use the IO branch, but be prepared that you would neet to write your own HTTP(s) read function :-)
litew
14:37@rebolek I think it's impossible to handle it currently due to my low skills in Red programming, nevertheless, could you please post link to this IO branch?
rebolek
15:22@litew https://github.com/qtxie/red/tree/IO2 if your skills are low currently then this branch probably wouldn’t be of much help to you as it’s not documented and highly experimental currently.
litew
16:11@rebolek understood. Thank you.
rebolek
16:25@litew OTOH if you are interested to learn how it works, I’m happy to help.
greggirwin
17:43@litew @rebolek is that CURL change safe, portable, and non-breaking? If so, it could be a PR and everyone wins.
litew
19:12@greggirwin It's libcurl's builtin options so I would assume this is portable and non-breaking change. But I can't say this is safe change from information security's point of view mainly because it changes cURL's default behaviour of not trusting to unverified SSL certificates (verification checks are usually made across local system's Certificate Authority store), which in turn could lead to miss of MITM-attack.

cURL utility, which obviously uses libcurl, offers -k (--insecure) option to explicitly disable SSL certificate's verification checks in such case.

That's why I called it ugly hack :-( It is appropriate to use when user knows what he is doing and makes http-requests to well-known webserver for which he knows that he can trust it even if it shouts out errors about security.
greggirwin
20:56Thanks for the info @litew. @rebolek do we have a wiki page related to URLs where we could add this? Your work and http-tools refs should be someplace easy to point to, and a wiki page can work for that.

bubnenkoff
09:51I have found mention here:
> The difference between script and options:
The arguments to the script. These are passed from the operating system command line or from the do function that was used to evaluate the script.

So what and when should I use?
hiiamboris
09:56Just use options until you are 100% sure this is not what you need.
bubnenkoff
11:56I need help with algorithm. It work perfect with small data . But if I have few millions of elements in data like:
number: none
        objects: [
            name: none
        ]

it start to scan data from top to down to find unfilled elements and it's take a lot of time. Is there any ideas how it can be improved?
Some way to prevent start from top again and again.
data: [
    regNum: none
    maxPrice: none
    lots: [
        number: none
        objects: [
            name: none
        ]
        number: none
        objects: [
            name: none
        ] 
        number: none
        objects: [
            name: none
        ] 
        number: none
        objects: [
            name: none
        ]         
        number: none
        objects: [
            name: none
        ]   
    ]
]

data-walk: function[data tag value] [
	changed?: false
	fill-data: func[data] [
		forall data [
			either block? data/2  [
				fill-data data/2
				] [
				if equal? to-string data/1 to-string tag [
					if (changed? = false) [							
						if none? reduce data/2 [
							data/2: value
							changed?: true
							break
							]
						]
					]
				]
			]
	]

	fill-data data ; filling
	
]

list: ["regNum" 777 "maxPrice" 950 "number" "1" "number" "2" "name" "Apples" "name" "Bananas"]

foreach [a b] list [data-walk data a b]

probe data
toomasv
14:111) You are (re)creating fill-data for each pair of elements in list.
2) For each pair of elements you start comparing elements from beginning.
3) You have millions of elements.
Oy-oy
14:13E.g. alternative:
data: [
    regNum: none
    maxPrice: none
    lots: []
]
list: ["regNum" 777 "maxPrice" 950 "number" "1" "number" "2" "name" "Apples" "name" "Bananas"]

numbers: clear []
names: clear []
fill-data: function [tag value] [
	switch tag [
		"number" [append numbers value]
		"name" [append names value]
		"regNum" [data/regnum: value]
		"maxPrice" [data/maxPrice: value]
	]
]

foreach [a b] list [fill-data a b]

n1: length? numbers
n2: length? names
either n1 >= n2 [
	forall numbers [
		append data/lots compose/deep [
			number: (numbers/1) 
			objects: [name: (names/(index? numbers))]
		]
	]
][
	forall names [
		append data/lots compose/deep [
			number: (numbers/(index? names)) 
			objects: [name: (names/1)]
		]
	]
]
probe data

I'm pretty sure this is much faster, but not so sure it satisfies all your constraints.
tinulac-leinad
14:26Some questions about objects :
object and context in Red are exactly the same thing ?
copy for make a true copy of an object, inheritance (more make true copy of an object with addition of function or full redefinition of existing on (there is no 'super for reference to ancestor).
the on-change* function is interesting and useful ... the source code of this function is not copied on the memory for each instance of an object , it's not present on a probe nor on a file produce whith "save" .
does each copy or instance have just a reference to this function ?
it can be modifier on copy like other functions and it's a good thing.
Is there a raison for explain that other objects functions are not in chain of references too ?
hiiamboris
15:34on-change* gets copied as any other function, because it *has* to be *bound* to new object
you can see it in mold/all output
15:34context and object is the same thing, but this may change in the future I think
15:34there is no inheritance, as Red is not an OOP language
15:35copy only copies a set of *copyable* types - not including inner objects, maps
15:38for a full copy I recommend following the strategy used in VID: save a spec of the object, then make objects with this spec
bubnenkoff
16:10> E.g. alternative:
>
> data: [
>     regNum: none
>     maxPrice: none
>     lots: []
> ]
> list: ["regNum" 777 "maxPrice" 950 "number" "1" "number" "2" "name" "Apples" "name" "Bananas"]
> 
> numbers: clear []
> names: clear []
> fill-data: function [tag value] [
> 	switch tag [
> 		"number" [append numbers value]
> 		"name" [append names value]
> 		"regNum" [data/regnum: value]
> 		"maxPrice" [data/maxPrice: value]
> 	]
> ]
> 
> foreach [a b] list [fill-data a b]
> 
> n1: length? numbers
> n2: length? names
> either n1 >= n2 [
> 	forall numbers [
> 		append data/lots compose/deep [
> 			number: (numbers/1) 
> 			objects: [name: (names/(index? numbers))]
> 		]
> 	]
> ][
> 	forall names [
> 		append data/lots compose/deep [
> 			number: (numbers/(index? names)) 
> 			objects: [name: (names/1)]
> 		]
> 	]
> ]
> probe data
>

> I'm pretty sure this is much faster, but not so sure it satisfies all your constraints.

Big thanks! I will learn. As you remember I need time to understand how it's work)
tinulac-leinad
16:39@hiiamboris
Curious. In this stupis sample gg is make from ff and copy the actual values of it's attributes. and... A function (I think there is no interest fo copy functions if the object as to go in a list (duplicate) But as you can see with mold, I cant see the code of on-change*... But no more reference too. on-change is present and works .
on-change* is fully copied and not just a reference how can I see it ?
>> gg: make ff[
[    on-change*: func [word old new][
[        if word = 'a [
[            if new > 0 [
[                a: new * 2
[                b: a
[            ]
[        ]
[    ]
[    ]
>> mold gg
== {make object! [^/    a: -1200^/    b: 100^/    test: func [][^/        self/a + self/b^/    ]^/    autre-chose*: func [essai][^/        rejoin ["ceci est un" essai]^/    ]^/]}
hiiamboris
17:12Again. Use print mold/all
tinulac-leinad
21:22@hiiamboris Oh, yes I see with Mold/all....
THe cat that I can't see the on-change* func like aby other when just mold the object make me confuse and so a list of object duplicate the on change* code. ...
It's probably not a good Idea to have functions on objects stored in lists or files.
thanks.

bubnenkoff
07:57I need to generate string like:
WHERE IN (1,2)


How to substitute 1,2 in correct form?
>> second split "-a=1,2" "="
== "1,2"


So I need change quote marks to brackets before appending to WHERE IN
rebolek
08:05There are no quote marks.
08:06You can use for example
rejoin ["WHERE IN (" second split "-a=1,2" "=" ")"]
bubnenkoff
08:17Thanks!
greggirwin
18:53@bubnenkoff the double quotes you see in the console around strings are part of their literal form, not part of the string itself. In certain cases curly braces are used.
>> "1,2"
== "1,2"
>> {1,2}
== "1,2"
>> {"1,2"}  ; here the braces are the string end markers, and the quotes are part of the string.
== {"1,2"}
>> "^"1,2^""  ; so you don't have to do this
== {"1,2"}

gltewalt
05:40@smotti Would this help you with system?
05:40https://github.com/red/red/wiki/%5BNOTES%5D-Red-System-Notes
GiuseppeChillemi
11:25I want to create a block for VID, it consists of 3 parts. The inner code is a foreach loop. In the first one I want to start a panel declaration and put the closing square bracket in the last one, how could I do?



a: ["one" "two"  "three"]

vid-block: collect [
   keep [
      some VID elements
      panel 200x200 [;<----------- opening it here
   ]
  
   foreach [a b] data [
        keep collect [button 30x20 (a) []]
     ]

   keep [
   some vid elements
     ] ;Closing panel bracket 
  ]
]

view VID-BLOCK


11:27I mean, is there a way to inser the square bracket quoting it?
toomasv
11:56@GiuseppeChillemi
data: ["one" [probe face/text] "two" [probe event/offset] "three" [ep/text: "Epilogue"]]

vid-block: collect [
	keep [
		below text "Example:" ;some VID elements
		panel white 200x200 ;<----------- opening it here
	]
	keep/only collect [ ;<-------- collect into panel
		foreach [a b] data [
			keep compose/only [button 40x20 (a) (b)]
		]
	]
	keep [ep: text ""] ;some vid elements
]

view vid-block
litew
11:59Offtopic: did anyone manage to join #red_* rooms via Matrix Element client for Android? Can't find where to add additional server (gitter.im) to search rooms from, meanwhile on desktop version of Element it finds red rooms normally (#red_help:gitter.im) after adding gitter.im to the list of servers.
hiiamboris
15:48I'm using old Riot.im client, it allows specifying homeserver url in the room search.
15:48Element is a no-go for me, can't tell.
GiuseppeChillemi
16:19@toomasv I din't knew about keep/only as only does not appear in the HELP of the collect function
toomasv
16:26@GiuseppeChillemi Go to sources:
?? collect
...
    keep: func [v /only] [either only [append/only collected v] [append collected v] v] 
...
hiiamboris
16:37or collect [? keep]
GiuseppeChillemi
16:51So, keep is visible only inside collect...
greggirwin
18:42Correct.