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

AltME groups: search

Help · search scripts · search articles · search mailing list

results summary

worldhits
r4wp250
r3wp2441
total:2691

results window for this page: [start: 1 end: 100]

world-name: r4wp

Group: #Red ... Red language group [web-public]
Pekr:
1-Mar-2012
Those were just tries. Any of the above logo is imo better than what 
Graham originally posted. But I am not satisified either. Here's 
my take, what needs to be considered for the logo to actually "work":


- you should define a brief - namely a description of qualities/characteristics 
of Red. What is Red, what sets it apart, what does it mean to you, 
what should it mean to ppl, what differentiates it from others, etc.


- type of logo - only letters? Letters plus pictogram? Shoul pictogram 
only decorate logo, or is part of the name? Pictograms are often 
related to the business, but I am not sure, if you are easily able 
to relate pictogram to "red", as it is a name of the color. Nor am 
I sure, if pictogram would express a programming language. What I 
would suggest, would be either - pictogram contains "R", which also 
works as a filetype icon. Or pictogram expresses some quality - e.g. 
>> (REBOL/Red prompt), [R] block as one of the main concepts (series)


- color scheme - not much options with something named Red, right? 
:-)


- usability - you should think about the color scheme, and logo in 
various forms - normal, inverse, black&white, icon, letterhead, business 
card, ppt presentation, etc. You can look for inspiration to how 
I aproached 2zone media logo with the agency - http://www.xidys.com/pekr/2zone_media_logotypes/
BrianH:
15-Jun-2012
You can make a port work a lot like a series, and you mostly did 
with the virtual block scheme. FOREACH and PARSE not working on ports 
can be a bit annoying, but they would only work on a subset of the 
port types that either work like series or (theoretically) like files 
(like open/direct file ports in R2).
DocKimbel:
29-Jun-2012
Red/System has no memory manager. You need to use the allocate/free 
wrappers provided by the runtime (see %Red/red-system/runtime/libc.reds). 


Once Red's memory manager will be stable, we could easily add some 
simple functions to make it available from Red/System too, so you'll 
be able to either manually manage memory or rely on Red's memory 
manager (including being able to call the GC).
BrianH:
5-Jul-2012
Giuseppe, those are called properties. The getter/setter functions 
you often find in GUIs are basically the same thing, but properties 
hide that in regular assignment syntax. We don't need getter properties 
in REBOL-like languages because we don't use parentheses to call 
functions, but setter functions appearing to be assignment statements 
might appeal to some.


I've had a lot of experience with properties in languages like Delphi; 
most of the popular languages that currently have property support, 
either in syntax or as a convention, are derived from Delphi. It 
makes code a little easier to write, and a lot harder to debug. The 
main advantage to implementing them in Red or R3 would be to make 
it easier to interoperate with .NET or COM objects.


Automatic delegation is something else. With automatic delegation, 
you automatically forward a method call from one object to another, 
just by declaring it as such. That doesn't really work in REBOL-style 
direct-bound functions because we don't have an implicit self parameter 
(we have self, but it's not a parameter). Red would need to have 
a completely different function binding model for that kind of thing 
to work; which it would likely have anyways, due to it being compiled 
rather than interpreted.
Rebolek:
22-Jul-2012
Doc, I can still reproduce it with this code:

x: 0.0
x: either x > 0.0 [x][0.0 - x]
print [x lf]

If I assign the result to 'y instead of 'x, it works.
Rebolek:
22-Jul-2012
When I change order, the code works:

x: 0.0
x: either x <= 0.0 [0.0 - x][x]
print [x lf]
Rebolek:
22-Jul-2012
But this also throws 11: float stack check error when used in function:

fabs: func [x [float!] return: [float!] ][
	either x < 0.0 [0.0 - x][x]
]
print [fabs -3.14 lf]
Rebolek:
22-Jul-2012
Final workaround :)

fabs: func [
	x			[float!]
	return:	[float!]
][
	x: either x < 0.0 [0.0 - x][x]
	x
]
print [fabs -3.14 lf]
DocKimbel:
25-Jul-2012
#221 is about keeping the x87 FPU stack clean in case of a nested 
`either` expression.
Rebolek:
31-Jul-2012
BTW, yesterday I've encountered a strange bug that's very hard to 
separate. The bug is that EITHER will always execute FALSE block, 
even if the condition is TRUE (EITHER is in function and the function 
is in WHILE loop, but that's not enough to trigger the bug). When 
I try to separate the problem the bug is gone. When I leave the function 
as is and just remove all unrelated stuff, the bug is also gone. 
It happens only when I compile my whole project. When I have more 
time, I will once again try to separate the problem and when unsuccesful, 
I will post the project as is for you to check it.
Rebolek:
2-Aug-2012
Doc, have a look at http://box.lebeda.ws/~rebolek/sintezar.zip

Compile file %sintezar.reds and see function ADSR in %env.reds. Even 
when I pass TRUE, EITHER always executes FALSE block. I tried to 
simplify it, but I wasn't succesfull, so it's bit bigger project 
than just few lines, sorry :)
BrianH:
5-Aug-2012
Keep in mind that even UTF-16 is not a fixed-size encoding. Each 
codepoint either takes 2 or 4 bytes.
Steeve:
11-Aug-2012
is: func [
		[catch]
		{Current face inherits from a block!}
		spec [block!]
		/local locals old when init
	][
		either all [
			find spec set-word!	; locals founds
			not empty? exclude  ; new ones (not found in the current face)

    first locals: construct copy spec ; copy: because [construct] modifies 
    the block (R2 bug ?)
				first face
		][

   ; Would be simpler, faster and safer using R3 (objects can be expanded)
			; rebuild face with new locals 

   ; (make face spec : can't be used here because of the special bounding 
   rules)

   when: face/when					; prevent copy/deep of when and init blocks
			init: face/init
			face/when: face/init: none
			set locals none

   resolve* locals face			; initialize locals with current face (if 
   intersect)

   face: make old: face locals		; rebuild current face with new locals
			face/when: when
			face/init: init
			do-safe bind bind spec face self; run style constructor 

   bind bind init face self		; rebound current face constructor (which 
   is currently running)

   error? set old :bound-err		; prevent old object from being used anymore
			old: none
		][
			; no new locals

   do-safe bind bind spec face self		; just run style's constructor 
		]
		if error throw-exit
	]
Kaj:
20-Aug-2012
The constructions in the runtime you replaced were very inefficient. 
Normal EITHER constructions seem to have less overhead than SWITCH 
and CASE. It's more or less independent from the number of clauses. 
It may be the default clause, especially when one is needed in CASE
DocKimbel:
21-Aug-2012
In the current implementation, 'comment can only be used at root 
level (so not nested in IF, EITHER, ... body blocks). So, it's not 
true multiline comment support.
DocKimbel:
23-Aug-2012
So far, I suppose that the issue is caused by either:
- lack of relocation ability from the DLL (my #1 suspect)

- compatibility issue(s) with some system DLL (msvcrt.dll most probably)
- another unknown reason

I'll try to add relocation data to the DLL tonight.
Kaj:
27-Aug-2012
Don't really have WINE, either. I'd have to dig out the laptop
sqlab:
4-Sep-2012
I am for sure no expert regarding unicode, but as red is a compiler 
and open source, why not not add flags that the user has to choose 
which unicode/string support he wants; either flexibility, but of 
cost of speed or no unicode support, then he  has to do the hard 
work by himself
Janko:
10-Sep-2012
Doc, Services like Plimus or Fastspring probably have option to get 
you wire transfer or at least check (or some send you prepayed visa). 
Not eactly meant for your case, but if you don't find anything else. 
You could (I hope) make a "products" with them and then. I used them 
for similar transactions when nothing else could come into play. 
Paypal wasn' working here either and even now it's very clunky to 
retrieve the $$ from it.
sqlab:
14-Sep-2012
I would prefer Red to compile either to the directory, where the 
source is by default or at least not to the system/options/home path, 
but to the path I get with pwd
DocKimbel:
14-Sep-2012
Kaj: what do you think of that? (for Red/System)

    #define MAX(a b) [either a > b [a][b]]

    print MAX(78 12)

outputs: 78
DocKimbel:
14-Sep-2012
Here's a more complex example:
    
    #define MIN(a b) [ either a < b [a][b] ]
    #define MAX(a b) [ either a > b [ MIN(p/a p/b) ][p/b] ]

    p: "Hello"
    print MAX(2 1)

outputs: H
Pekr:
17-Sep-2012
Reading all the discussion about R/S source inclusion in the Red 
- it seems pretty complicated and confusing at best. Apart from the 
three options discussed on friday, it is the "least powerfull" one. 
It is not any kind of inlining R/S code into Red from the runtime 
point of view, hence I wonder, why it is not simply called an #include? 
I know you might want to two cases now:

#include %some.red
#include %some.reds


But that's distinguishable, and unifies the naming, as well as it 
does what the name suggests - it is just preprocessor kind of directive 
for including either the red, or r/s source into Red ....
Pekr:
30-Sep-2012
there is no other option to SQLite, other embedded databases are 
either not free, or don't use SQL syntax (e.g. mySQL)
DocKimbel:
1-Oct-2012
Implemented IF and EITHER, I just wanted to share their implementation 
with you (extract from Red compiler source)::

	comp-if: does [
		comp-expression		
		emit compose [	
			if (logic-true?)
		]
		comp-sub-block
	]
	
	comp-either: does [
		comp-expression		
		emit compose [	
			either (logic-true?)
		]
		comp-sub-block
		comp-sub-block
	]

Shouldn't be more complex than that, no? ;-)
Pekr:
11-Oct-2012
I can't decode anything from inspecting the sources yet. I can look 
into natives, there are some forall-loop etc functions whose purpose 
I don't understand. Then I can see datatypes, but where should I 
look for the definition of 'if, 'either, 'until, 'forall, 'while, 
etc.? :-)
Kaj:
13-Oct-2012
It's basically unrelated to Thumb. It's not necessarily about hardware 
floating point, either, but it's a different way of supporting it
Kaj:
18-Oct-2012
type: either dt/value = TYPE_DATATYPE [
    TYPE_DATATYPE
][ 
    dt/value
]
Group: Announce ... Announcements only - use Ann-reply to chat [web-public]
Arnold:
1-Jul-2012
New version of the mirror game placed on same spot. Only on first 
screen the coloring doesn't work. See what happens if you comment 
the line before the last. Bold did not work for me either, could 
be the mac and font arial.
MaxV:
25-Oct-2012
Rebol [Purpose: {make wikibook entry}
Author: "Max Vessi"
version: 1.0.0
]
my?: func [
    "Prints information about words and values."
    'word [any-type!]

    /local value args item type-name refmode types attrs rtype temp
][       
    temp:  copy ""
    if all [word? :word not value? :word] [word: mold :word]

    if any [string? :word all [word? :word datatype? get :word]] [
        types: dump-obj/match system/words :word
        sort types
        if not empty? types [
            print ["Found these words:" newline types]
            exit
        ]
        print ["No information on" word "(word has no value)"]
        exit
    ]
    type-name: func [value] [
        value: mold type? :value
        clear back tail value
        join either find "aeiou" first value ["an "] ["a "] value
    ]
    if not any [word? :word path? :word] [
        append temp reduce [mold :word "is" type-name :word]
        exit
    ]

    value: either path? :word [first reduce reduce [word]] [get :word]
    if not any-function? :value [

        append temp reduce [uppercase mold word "is" type-name :value "of 
        value: "]

        append temp either object? value [ reduce ["^/" dump-obj value] ] 
        [mold :value]
        exit
    ]
    args: third :value
    append temp  "= USAGE: = ^/ "

    if not op? :value [append temp reduce [ uppercase mold word " "] 
    ]
    while [not tail? args] [
        item: first args
        if :item = /local [break]

        if any [all [any-word? :item not set-word? :item] refinement? :item] 
        [
            append temp reduce [append mold :item " "]

            if op? :value [append temp reduce [append uppercase mold word " "]
	    value: none]
        ]
        args: next args
    ]
    append temp  "^/" 
    args: head args
    value: get word
    append temp "^/= DESCRIPTION: = ^/"
    either string? pick args 1 [
        append temp reduce [first args]
        args: next args
    ] [
        append temp "^/''(undocumented)''^/"
    ]

    append temp reduce [ "^/^/"uppercase mold word " is " type-name :value 
    " value."]
    if block? pick args 1 [
        attrs: first args
        args: next args
    ]
    if tail? args [exit]
    while [not tail? args] [
        item: first args
        args: next args
        if :item = /local [break]
        either not refinement? :item [

            all [set-word? :item :item = to-set-word 'return block? first args 
            rtype: first args]
            if none? refmode [
		append temp "^/= ARGUMENTS: =^/"
                refmode: 'args
            ]
        ] [
            if refmode <> 'refs [
                append temp "^/= REFINEMENTS: =^/"
                refmode: 'refs
            ]
        ]
        either refinement? :item [	   	  
            append temp reduce ["*'''" mold item "'''"]

            if string? pick args 1 [append temp reduce [" -- " first args] 
	    args: next args]
            append temp "^/"
        ] [
            if all [any-word? :item not set-word? :item] [
                if refmode = 'refs [append temp "*"]
                append temp reduce ["*'''" :item "''' -- "]

                types: if block? pick args 1 [args: next args first back args]

                if string? pick args 1 [append temp reduce [first args ""] 
		args: next args]
                if not types [types: 'any]
                append temp rejoin [" (Type: " types ")"]
                append temp "^/"
            ]
        ]
    ]
    if rtype [append temp reduce ["^/RETURNS:^/^-" rtype]]
    if attrs [
        append temp "^/= (SPECIAL ATTRIBUTES) =^/"
        while [not tail? attrs] [
            value: first attrs
            attrs: next attrs
            if any-word? value [
                append temp reduce  ["*'''" value "'''"]
                if string? pick attrs 1 [
                    append temp reduce [" -- " first attrs]
                    attrs: next attrs
                ]
                append temp "^/"
            ]
        ]
    ]
    editor temp
    exit
]
Group: Ann-Reply ... Reply to Announce group [web-public]
Cyphre:
2-Jul-2012
hmm, the game doesn't work here:
** Script Error: labelfont has no value
** Where: zet-label-kleur
** Near: panel-rechts/pane/:p/font: labelfont
either onoff [panel-rechts/pane/:p/font: lbl-r/font]
>>

Any ideas?
Cyphre:
2-Jul-2012
I didn't change anything with the source.  Even this doesn't work:
>> do http://arnoldvanhofwegen.com/stuff/mirror.rebol
connecting to: arnoldvanhofwegen.com
Script: "Mirrorgame" (none)
** Script Error: labelfont has no value
** Where: zet-label-kleur
** Near: panel-rechts/pane/:p/font: labelfont
either onoff [panel-rechts/pane/:p/font: lbl-r/font]
>>
Rebolek:
2-Jul-2012
Arnold, I looked at the script (btw very cool game!) and you can 
replace nested 'either in zet-label-kleur with 'case for better readability.
MaxV:
25-Sep-2012
GPL means "free speech" not "free beer"!

 Many people believe that the spirit of the GNU Project is that you 
 should not charge money for distributing copies of software, or that 
 you should charge as little as possible — just enough to cover the 
 cost. This is a misunderstanding.


Actually, we encourage people who redistribute free software to charge 
as much as they wish or can. If this seems surprising to you, please 
read on.


The word “free” has two legitimate general meanings; it can refer 
either to freedom or to price. When we speak of “free software”, 
we're talking about freedom, not price. (Think of “free speech”, 
not “free beer”.) Specifically, it means that a user is free to run 
the program, change the program, and redistribute the program with 
or without changes.


Free programs are sometimes distributed gratis, and sometimes for 
a substantial price. Often the same program is available in both 
ways from different places. The program is free regardless of the 
price, because users have freedom in using it.


Nonfree programs are usually sold for a high price, but sometimes 
a store will give you a copy at no charge. That doesn't make it free 
software, though. Price or no price, the program is nonfree because 
users don't have freedom.


Since free software is not a matter of price, a low price doesn't 
make the software free, or even closer to free. So if you are redistributing 
copies of free software, you might as well charge a substantial fee 
and make some money. Redistributing free software is a good and legitimate 
activity; if you do it, you might as well make a profit from it.


Free software is a community project, and everyone who depends on 
it ought to look for ways to contribute to building the community. 
For a distributor, the way to do this is to give a part of the profit 
to free software development projects or to the Free Software Foundation. 
This way you can advance the world of free software.


Distributing free software is an opportunity to raise funds for development. 
Don't waste it!


In order to contribute funds, you need to have some extra. If you 
charge too low a fee, you won't have anything to spare to support 
development
Kaj:
26-Sep-2012
The implementation language doesn't matter for licensing, either
BrianH:
26-Sep-2012
It is common to use this FAQ entry as a way to make GPL extensions 
that wrap proprietary components: http://www.gnu.org/licenses/gpl-faq.html#WindowsRuntimeAndGPL


Developers commonly put links on their web site to the vendor's web 
site to download the DLL. However, it's iffy with GPL2 because the 
actual exception is worded like this:

However, as a special exception, the source code distributed need 
not include anything that is normally distributed (in either source 
or binary form) with the major components (compiler, kernel, and 
so on) of the operating system on which the executable runs, unless 
that component itself accompanies the executable.


Read literally, it would exclude runtime libraries that aren't bundled 
with the OS. It's more unambiguously OK with GPL3.
Henrik:
27-Sep-2012
I haven't followed the conversation either. For me it's still the 
basic issue that one license is (way) more complex than the other. 
Therefore I would work with the tool that has the least complicated 
license.
BrianH:
27-Sep-2012
In the official statements that refer to the versions of R3 that 
have the current system model (approx. the last dozen versions), 
the functions included with R3 are referred to as the "Runtime Library". 
The other online docs haven't been updated to reflect the current 
system model, and most of them haven't even been updated for R3 yet, 
still referring to their R2 behavior. There are indications either 
way, enough to drive a trial through. We need an unambiguous published 
statement to be sure we won't be sued for using R3, or that at least 
such suits will fail.
BrianH:
27-Sep-2012
Agreed, though it doesn't matter whether the library is interpreted 
either. You can statically link a native library to the interpreter 
for use by interpreted or native code, and it can legally affect 
the code that is using it. The only way around it is to declare that 
code to be part of the interpreter rather than part of the runtime 
library, which can only be done with permission of the rights-holder 
of that code.
MaxV:
25-Oct-2012
Rebol [Purpose: {make wikibook entry}
Author: "Max Vessi"
version: 2.0.0
]
my?: func [
    "Prints information about words and values."
    'word [any-type!]

    /local value args item type-name refmode types attrs rtype temp
][       
    temp:  copy ""
    if all [word? :word not value? :word] [word: mold :word]

    if any [string? :word all [word? :word datatype? get :word]] [
        types: dump-obj/match system/words :word
        sort types
        if not empty? types [
            print ["Found these words:" newline types]
            exit
        ]
        print ["No information on" word "(word has no value)"]
        exit
    ]
    type-name: func [value] [
        value: mold type? :value
        clear back tail value
        join either find "aeiou" first value ["an "] ["a "] value
    ]
    if not any [word? :word path? :word] [
        append temp reduce [mold :word "is" type-name :word]
        exit
    ]

    value: either path? :word [first reduce reduce [word]] [get :word]
    if not any-function? :value [

        append temp reduce [uppercase mold word "is" type-name :value "of 
        value: "]

        append temp either object? value [ reduce ["^/" dump-obj value] ] 
        [mold :value]
        exit
    ]
    args: third :value
    append temp  "= USAGE: = ^/ "

    if not op? :value [append temp reduce [ uppercase mold word " "] 
    ]
    while [not tail? args] [
        item: first args
        if :item = /local [break]

        if any [all [any-word? :item not set-word? :item] refinement? :item] 
        [
            append temp reduce [append mold :item " "]

            if op? :value [append temp reduce [append uppercase mold word " "]
	    value: none]
        ]
        args: next args
    ]
    append temp  "^/" 
    args: head args
    value: get word
    append temp "^/= DESCRIPTION: = ^/"
    either string? pick args 1 [
        append temp reduce [first args]
        args: next args
    ] [
        append temp "^/''(undocumented)''^/"
    ]

    append temp reduce [ "^/^/"uppercase mold word " is " type-name :value 
    " value."]
    if block? pick args 1 [
        attrs: first args
        args: next args
    ]
    if tail? args [exit]
    while [not tail? args] [
        item: first args
        args: next args
        if :item = /local [break]
        either not refinement? :item [

            all [set-word? :item :item = to-set-word 'return block? first args 
            rtype: first args]
            if none? refmode [
		append temp "^/= ARGUMENTS: =^/"
                refmode: 'args
            ]
        ] [
            if refmode <> 'refs [
                append temp "^/= REFINEMENTS: =^/"
                refmode: 'refs
            ]
        ]
        either refinement? :item [	   	  
            append temp reduce ["*'''" mold item "'''"]

            if string? pick args 1 [append temp reduce [" -- " first args] 
	    args: next args]
            append temp "^/"
        ] [
            if all [any-word? :item not set-word? :item] [
                if refmode = 'refs [append temp "*"]
                append temp reduce ["*'''" :item "''' -- "]

                types: if block? pick args 1 [args: next args first back args]

                if string? pick args 1 [append temp reduce [first args ""] 
		args: next args]
                if not types [types: 'any]
                append temp rejoin [" (Type: " types ")"]
                append temp "^/"
            ]
        ]
    ]
    if rtype [append temp reduce ["^/RETURNS:^/^-" rtype]]
    if attrs [
        append temp "^/= (SPECIAL ATTRIBUTES) =^/"
        while [not tail? attrs] [
            value: first attrs
            attrs: next attrs
            if any-word? value [
                append temp reduce  ["*'''" value "'''"]
                if string? pick attrs 1 [
                    append temp reduce [" -- " first attrs]
                    attrs: next attrs
                ]
                append temp "^/"
            ]
        ]
    ]
    append temp "^/= Source code =^/"
    append temp  reduce ["<pre>" join word ": "]
    if not value? word [print "''undefined''" exit]
    either any [native? get word op? get word action? get word] [
        append temp reduce ["native" mold third get word]
    ] [append temp reduce  [ mold get word "</pre>"] ]
    editor temp
    ;write clipboard://  temp
    exit
]
Ladislav:
7-Nov-2012
encapping is important for my bussines
 - encapping is not a problem in R3 either
BrianH:
29-Nov-2012
Pekr, he already did port it to ARM Linux, but at the time noone 
working on the project had an ARM machine to test with other than 
an Android phone. And porting the core to Android is the simple part; 
the host would need to be rewritten almost completely for Android 
due to the different application model. Noone was using Amiga either. 
The only alternate platform that was getting any use by the project 
members was Syllable.
ChristianE:
30-Dec-2012
Hi Brian! In order to make the ODBC extension bootable, I've commented 
out the last lines in src/boot/odbc.r, because otherwise R3 chokes 
on the word EXTEND not being bound to a context on boot time. It's 
not available as SYS/EXTEND either, but of course, there must be 
some way to use EXTEND.
Bo:
4-Jan-2013
>> do http://development.saphirion.com/experimental/oneliner-prime-numbers.r

** Access error: cannot open: tcp://development.saphirion.com:80 
reason: -12
** Where: open open unless sync-op either read
** Near: open conn port
Bo:
4-Jan-2013
I got a slightly different message when I tried it with 3G instead 
of WiFi, for some reason:


>> do http://development.saphirion.com/experimental/oneliner-prime-numbers.r

** Access error: cannot open: tcp://development.saphirion.com:80 
reason: -12

** Where: open open unless sync-op either read either read-decode 
case load -apply-do
** Near: open conn port
Scot:
21-Jan-2013
I don't think the first part (Case for non-developers learning to 
program) relies on either version of REBOL.
Arnold:
22-Jan-2013
no rebol.informe.com/portal here either.
Gregg:
13-Feb-2013
While I'm against blind copying, I think MaxV is simply trying to 
build some momentum. He's been very active, and I appreciate all 
his past efforts. If we open a dialog, we'll either come together 
or disagree in a friendly manner. :-) As much as I believe in talking 
first, sometimes that stalls efforts as well. Now at least we have 
something  to look at and use for further discussion.


And while I don't like having too many channels, and use only a few 
consistently, his new portal looks nice and incorporates a lot of 
functionality already.
Scot:
13-Feb-2013
As an observer of open source projects since there were open scource 
projects, I see some challenges that no open source community that 
in my opinion have yet to be overcome, outside a limited vertical 
or academic market.

1.  Self-interest:  Each person views the code as their own opportunity 
to promote their own goals.  Since it costs nothing except time and 
effort and there is no remuneration, people develop forks that suit 
themselves.  When the need for them disappears, the support for them 
vanishes.  Result:  Whether a company owns the source or a company 
makes money with the source you are always dependent upon somebody 
who has more at stake than you do.  Right now that means Sapphirion.

2. Money:  Even with open source projects it takes money to push 
them forward.  If a company can make money they will pay for it themselves. 
 if somebody else needs the port or feature, they donate if there 
are enough people interested. So you either pay a company or pay 
into a project, either way you pay.

3. Leadership:  Usually a company ends up taking leadership because 
the original leaders begin to tire of the constant promotion and 
hard work.
Gregg:
19-Feb-2013
I'm OK either way. I go back to Announce more for REBOL/Red related 
things, which this is related to.
Kaj:
20-Feb-2013
To be able to handle such a file on Windows, you should either have 
an auto-converting editor, or convert them yourself. On the other 
hand, REBOL does it automatically
Scot:
27-Feb-2013
I gathered that.  Wish Carl could either be or attract the kinds 
of people that can sell what he makes.  I'm sure what he's working 
on next will be just as mind blowing and advanced.
Gregg:
1-Mar-2013
Graham, I haven't tried to grab a cookie or anything yet, but just 
running the SO bot errors out first thing:

** Script error: lastmessage-no has no value
** Where: get ajoin case ?? do either either either -apply-
** Near: get :name

What optimizations are you looking for?
Group: Rebol School ... REBOL School [web-public]
Pekr:
4-Mar-2012
ah, should be 0.1 e.g. actually. So - wait returns either when there 
is any event on the ports, or at the certain time interval ...
caelum:
23-Mar-2012
I just wrote some code that seems to work.

; Checks to see if port is already open

either error? is-port-open: try [listen-port: open/binary/no-wait 
tcp://:xxx] [
	; Port already open, so do nothing
][
	; Port can be used so run the program
]
Steeve:
21-Apr-2012
Currenlty 'a stands for either an object or a string, you can't be 
that vague.
You must choose a clear name  to identify the decimal attribute
Steeve:
21-Apr-2012
and fact1 must be initialized accodingly.
Either with 'a either with 'a/a
Steeve:
21-Apr-2012
fact1: 'a
get-prop: func [o][either object? o [first next second o][o]]

blk: [greater? to-decimal get-prop do bind reduce [fact1] obj num1]objs: 
[]
caelum:
22-Apr-2012
Is it possible to change the background color of the view led? Or 
are the only states available 'true' and 'false' which are green 
and red? I want different background colors for 'true' and 'false' 
states.

view center-face layout [
	across
	l1: led
	label "State" state: field

	btn "Change led state" [
		either l1/data [
			l1/data: false
			state/text: "False"
		][
			l1/data: true
			l1/data: true
			state/text: "True"
		]
		show [l1 state]
	]
]
Gregg:
24-Apr-2012
set 'parse-phone-num func [
        num [string!]
        /local  digit digits sep _ext_  ch nums pin ext
    ] [
        digit:  charset "0123456798"
        digits: [some digit]
        sep:    charset "()-._"
        _ext_:  ["ext" opt "." | "x"]

        nums: copy ""
        rules: [
            any [
                some [sep | copy ch digit (append nums ch)]
                | _ext_ copy ext digits
                | "pin" copy pin digits
            ]
            end
        ]
        either parse trim num rules 
            [reduce ['num nums 'ext ext 'pin pin]]
            [none]
    ]

    set 'well-formed-phone-number? func [num /local data] [
        either none? data: parse-phone-num num [false] [
            any [
                found? find [7 10] length? data/num
                all [11 = length? data/num  data/num/1 = #"1"]
            ]
        ]
    ]
Gregg:
24-Apr-2012
set 'format-phone-number func [
        num [string! object!] "String or object with /text value"
        /def-area-code area-code [string! integer!]
        /local left right mid obj res
    ] [
        left:  func [s len][copy/part s len]
        right: func [s len] [copy skip tail s negate len]
        mid:   func [s start len][copy/part at s start len]

        if object? num [obj: num  num: obj/text]

        res: either data: parse-phone-num num [
            ; discard leader if it's there.
            if all [11 = length? data/num  data/num/1 = #"1"] [
                data/num: right data/num 10
            ]
            rejoin [
                rejoin switch/default length? data/num [
                    7  [ compose [

                        (either area-code [rejoin ["(" area-code ") "]][])
                        left data/num 3 "-" right data/num 4
                    ]]
                    10 [[
                        "(" left data/num 3 ") "
                        mid data/num 4 3 "-" right data/num 4
                    ]]
                ][[data/num]]

                reduce either data/ext [[" ext" trim data/ext]] [""]

                reduce either data/pin [[" pin" trim data/pin]] [""]
            ]
        ][num]

        if obj [
            obj/text: res
            attempt [if 'face = obj/type [show obj]]
        ]
        res
    ]
Gregg:
24-Apr-2012
parse-int-values: func [

    "Parses and returns integer values, each <n> chars long in a string."
    input [any-string!]

    spec [block!] "Dialected block of commands: <n>, skip <n>, done, 
    char, or string"
    /local
        gen'd-rules ; generated rules
        result      ; what we return to the caller

        emit emit-data-rule emit-skip-rule emit-literal-rule emit-data
        digit= n= literal=
        int-rule= skip-rule= literal-rule= done= build-rule=
        data-rule skip-rule
][

    ; This is where we put the rules we build; our gernated parse rules.
    gen'd-rules: copy []
    ; This is where we put the integer results
    result: copy []

    ; helper functions

    emit: func [rule n] [append gen'd-rules replace copy rule 'n n]
    emit-data-rule: func [n] [emit data-rule n]
    emit-skip-rule: func [n] [emit skip-rule n]
    emit-literal-rule: func [value] [append gen'd-rules value]
    emit-data: does [append result to integer! =chars]

    ; Rule templates; used to generate rules

    ;data-rule: [copy =chars n digit= (append result to integer! =chars)]
    data-rule: [copy =chars n digit= (emit-data)]
    skip-rule: [n skip]

    ; helper parse rules
	digit=: charset [#"0" - #"9"]
    n=: [set n integer!]
    literal=: [set lit-val [char! | any-string!]]

    ; Rule generation helper parse rules
    int-rule=: [n= (emit-data-rule n)]
    skip-rule=: ['skip n= (emit-skip-rule n)]
    literal-rule=: [literal= (emit-literal-rule lit-val)]
    done=: ['done (append gen'd-rules [to end])]

    ; This generates the parse rules used against the input

    build-rule=: [some [skip-rule= | int-rule= | literal-rule=] opt done=]


    ; We parse the spec they give us, and use that to generate the

    ; parse rules used against the actual input. If the spec parse

    ; fails, we return none (maybe we should throw an error though);

    ; if the data parse fails, we return false; otherwise they get
    ; back a block of integers. Have to decide what to do if they
    ; give us negative numbers as well.
    either parse spec build-rule= [
        either parse input gen'd-rules [result] [false]
    ] [none]
]
Endo:
26-Apr-2012
I use my own functions, returns always in ISO format, YYYY-MM-DD 
HH:NN:SS


padz: func ["Pad to right with zero." s n [integer!] /left /with 
c [char! string!]] [

    head insert/dup either left [tail form s] [form s] first form either 
    with [c] [#"0"] n - length? form s
]

format-date: func [d [date!]] [

 ajoin [d/date/year "-" padz d/date/month 2 "-" padz d/date/day 2 
 either d/time [ajoin [" " padz d/time/hour 2 ":" padz d/time/minute 
 2 ":" padz to-integer d/time/second 2]] [""]]
]
Gregg:
27-Apr-2012
date-to-epoch: func [
    "Returns a unix time (epoch) format from a date."
    date [date!]
][
    ; If no time is given, negate our zone to give us 0:00 UTC
    if none? date/time [date/time: negate now/zone]
    ; This uses the epoch base in UTC, so we assume that either
    ; the date is also in UTC, or has a zone offset included.
    ; DIFFERENCE fails for huge time differences, so we subtract
    ; them instead, giving us a difference in days, and multiply
    ; by the number of seconds in a day.

    either attempt [positive? res: to integer! difference date 1-Jan-1970/0:0:0] 
        [res]
        [date - 1-Jan-1970/0:0:0 * 86400.0]
]
PeterWood:
3-May-2012
Something like this should work:

>> ;; position at 2nd last char of ln+nl
>> ln+nl: back back tail ln+nl
== #{0D0A}
>> ;; see if the first of the two chars is a linefeed
>> either #"^(0a)" = first ln+nl [size-nl: 1] [size-nl: 2]
== 2
Henrik:
7-May-2012
A problem with VID is that there is not a true standard way to set 
texts in various styles, so each style may either use /TEXT (which 
is IMHO the wrong way) or SET-FACE (which IMHO is the right way).
Endo:
8-May-2012
Garbage chars may appear if you don't. Read the above note.

Either way, you set some long text, or clear it when there was some 
long text.
Gregg:
23-Jun-2012
Arnold, for the dir issue:

>> ?? dirize
dirize: func [
    {Returns a copy of the path turned into a directory.}
    path [file! string! url!]
][

    either #"/" <> pick path length? path [join path #"/"] [copy path]
]

>> ?? undirize
undirize: func [
    {Returns a copy of the path with any trailing "/" removed.}
    path [file! string! url!]
][
    path: copy path
    if #"/" = pick path length? path [clear back tail path]
    path
]
Ladislav:
28-Jun-2012
However, Joel's TALLY is not universal either. Joel criticized the 
problem with exceptions of the LESSER? function in his ML posting. 
But there are also exceptions related to the EQUAL? function which 
make his implementation non-universal (for some blocks B their elements 
are incomparable using the EQUAL? function). Such blocks cannot be 
processed using Joel's TALLY.
Henrik:
29-Jun-2012
So, you either re-build that layout, or you manipulate the face object 
tree directly.
Arnold:
30-Jun-2012
If I could switch it from a text to a label it would be nice. As 
yet I have this puzzling experience:
REBOL []
high-on: high-on-odd: false
swap-even: func [/local n] [

    either high-on [for n 2 8 2 [ panel-rechts/pane/:n/font/color: 'white] 
    high-on: false

    ][              for n 1 7 2 [ panel-rechts/pane/:n/font/color: 'black] 
    high-on: true ]
    show panel-rechts]

swap-odd: func [/local n] [

    either high-on-odd [for n 1 7 2 [panel-rechts/pane/:n/font/color: 
    'white

                                     panel-rechts/pane/:n/style: 'lbl-h-la-white] high-on-odd: false
    ][for n 1 7 2 [panel-rechts/pane/:n/font/color: 'black

                   panel-rechts/pane/:n/style: 'lbl-h-la-normal] high-on-odd: true]
    show panel-rechts]

spiegel-styles: stylize [
    lbl-h-la-normal: text left middle 40x100
    lbl-h-la-white: label left middle 40x100]
    
view layout [styles spiegel-styles
	across
	panel-rechts: panel [below space 0x0

    lbl-h-la-white "_" lbl-h-la-white "_" lbl-h-la-normal "_" lbl-h-la-normal 
    "_"

    lbl-h-la-normal "_" lbl-h-la-normal "_" lbl-h-la-normal "_" lbl-h-la-normal 
    "_"]
    return
    button "Even" [swap-even] button "Odd" [swap-odd]
    button "Debug" [print dump-face panel-rechts
    print panel-rechts/pane/1/font/color
    print panel-rechts/pane/1/color
    print panel-rechts/pane/1/style]
]

Where the first two labels change when button Odd is clicked. and 
then stay unchanged and the debug button shows the changes as expected 
(by me)
DocKimbel:
23-Jul-2012
This function should help you:

form-error: func [err [object!]][
	foreach w [arg1 arg2 arg3][
		set w either unset? get/any in err w [none][
			get/any in err w
		]
	]
	reform [
		"***" system/error/(err/type)/type #":"
		reduce system/error/(err/type)/(err/id) newline
		"*** Where:" mold/flat get in err 'where newline
		"*** Near: " mold/flat get in err 'near newline
	]
]
BrianH:
31-Jul-2012
The only trick is that you either need extra temp vars for the loop 
variables, or to modify an existing temp var. As a bonus in R3, FORSKIP 
and FORALL are faster than FOR or FOREACH, since no rebinding of 
the code block is necessary.
Endo:
8-Aug-2012
I wrote a run length encoding function, may be useful for someone 
else too:

rle: func ["Run length encode" b /local v r i j] [
	v: 1 r: copy []
	j: next i: b
	unless empty? b [
		until [
			either all [not tail? j equal? first i first j] [
				v: v + 1 j: next j
			] [
				append r reduce [v first i] v: 1 i: ++ j
			]
			tail? i
		]
	]
	r
]
BrianH:
8-Aug-2012
Here's a version for R3 parse, with some optimizations:

rle2: funct ["Run length encode" b [series!]] [
	output: copy [] x: none

 r: either any-block? :b [qr: copy [quote 1] [(qr/2: :x) any qr]] 
 [[any x]]
	parse :b [any [pos1: set x skip r pos2: (
		reduce/into [subtract index? :pos2 index? :pos1 :x] tail output
	)]]
	output
]
BrianH:
8-Aug-2012
rle2: funct ["Run length encode" b [series!]] [
	output: copy [] x: none

 r: either any-block? :b [qr: copy [quote 1] [(qr/2: :x) any qr]] 
 [[any x]]
	parse/case :b [any [pos1: set x skip r pos2: (
		reduce/into [subtract index? :pos2 index? :pos1 :x] tail output
	)]]
	output
]

>> rle2 [a a A b b c d D d d d]
== [2 a 1 A 2 b 1 c 1 d 1 D 3 d]
BrianH:
8-Aug-2012
I tried to come up with a more optimal R3 version without using parse, 
but I got blocked by case-sensitivity, without considering binding. 
I suppose I could just consider binding too, or unbind the results. 
It also doesn't do structural comparison of functions, either in 
the parse or procedural version.
DocKimbel:
8-Aug-2012
Here's a R2 solution with same rules for string! and block! series:

rle: func [s [series!] /local out c i][
    out: make block! 1

    parse/case/all s [
        any [
            [end | c: (
                c: either word? c/1 [to-lit-word c/1][c/1]
                i: 1
            )]
           skip
           some [
               c (i: i + 1)
               | (repend out [i c]) break
           ]
       ]
    ]
    out
]

>> rle "aaabbcx"
== [3 #"a" 2 #"b" 1 #"c" 1 #"x"]

>> rle [a a a a a]
== [5 a]

>> rle [a a a a a b b]
== [5 a 2 b]

>> rle [a a A b b c d D d d d]
== [3 a 2 b 1 c 5 d]
DocKimbel:
8-Aug-2012
Another version of 'rle for R2 that uses two pointers (like your 
R3 version) instead of a counter:

rle: func [s [series!] /local out c pos1 pos2][
    out: make block! 1

    parse/case/all s [
        any [
            [end | c: (
                c: either word? c/1 [to-lit-word c/1][c/1]
            )]
           pos1: skip

           some [c | pos2: (repend out [offset? pos1 pos2 c]) break]
       ]
    ]
    out
]
BrianH:
9-Aug-2012
If you follow the /into option standard you can do chained calls 
to RLE too:


rle: func [s [series!] /into out [any-block!] /local emit pos1 pos2 
cont][
	unless into [out: make block! 2]

 emit: [(out: insert/only insert :out offset? :pos1 :pos2 first :pos1)]
	parse/case/all :s pick [[
		any [pos1: skip (cont: first :pos1) any cont pos2: emit]
	] [
		any [
			pos1: unset! any unset! pos2: emit |
			pos1: skip some [
				pos2: unset! :pos2 emit break |
				pos2: skip (

     cont: unless strict-equal? first :pos1 first :pos2 [[end skip]]
				) cont |
				pos2: emit break
			]
		]
	]] any-string? :s
	either into [:out] [head :out]
]
BrianH:
9-Aug-2012
R3 version, same /into option:


rle: funct ["Run length encode" s [series!] /into output [any-block!]] 
[
	unless into [output: make block! 2] x: none

 r: either any-block? :s [qr: copy [quote 1] [(qr/2: :x) any qr]] 
 [[any x]]
	parse/case :s [any [pos1: set x skip r pos2: (

  output: reduce/into [subtract index? :pos2 index? :pos1 :x] :output
	)]]
	either into [:output] [head :output]
]
BrianH:
9-Aug-2012
Sorry, same unset problems, have to use POKE:


rle: funct ["Run length encode" s [series!] /into output [any-block!]] 
[
	unless into [output: make block! 2] x: none

 r: either any-block? :s [qr: copy [quote 1] [(poke qr 2 :x) any qr]] 
 [[any x]]
	parse/case :s [any [pos1: set x skip r pos2: (

  output: reduce/into [subtract index? :pos2 index? :pos1 :x] :output
	)]]
	either into [:output] [head :output]
]
BrianH:
10-Aug-2012
In mezzanine style:

decode-rle: func [
	"Decode a run length encoded block"
	rle [any-block!] "Block of [integer value]"

 /into "Insert into a buffer instead (returns position after insert)"
	output [series!] "The output buffer (modified)"
	/local x
] [
	unless into [
		x: 0  foreach [i v] :rle [x: x + :i]  output: make block! x
	]

 foreach [i v] :rle [output: insert/only/dup :output get/any 'v :i]
	either into [:output] [head :output]
]


Instead of testing for strict format compliance of the input block, 
it uses get-words to keep people from sneaking in functions and then 
passes the length value to + and INSERT/dup, counting on the type 
tests of those functions to do the screening for us.
BrianH:
10-Aug-2012
decode-rle: func [
	"Decode a run length encoded block"
	rle [any-block!] "Block of [integer value]"

 /into "Insert into a buffer instead (returns position after insert)"
	output [series!] "The output buffer (modified)"
	/local x
] [
	unless into [
		x: 0  output: make block! forskip rle 2 [x: x + :rle/1]
	]
	forskip rle 2 [output: insert/only/dup :output :rle/2 :rle/1]
	either into [:output] [head :output]
]
BrianH:
11-Aug-2012
Here's a version of my last one above, but with Steeve's trick adapted 
to make a /compare option. It defaults to its old case-sensitive 
behavior.

rle: func [
	"Run length encode to series of [length value]"
	s [series!] "The series to encode"

 /into {Insert into a buffer instead (returns position after insert)}
	output [any-block!] "The output buffer (modified)"
	/compare "Comparator function for equvilance"
	comparator [any-function!]
	/local x r qr b e
] [
	unless into [output: make block! 2] x: none
	r: case [
		compare [[any [e: if (apply :comparator [:x :e/1]) skip]]]
		any-string? :s [[any x]]
		'else [qr: copy [quote 1] [(poke qr 2 :x) any qr]
	]
	parse/case :s [any [b: set x skip r e: (
		output: reduce/into [offset? :b :e :x] :output
	)]]
	either into [:output] [head :output]
]
BrianH:
11-Aug-2012
Whoops, forgot a bracket:

rle: func [
	"Run length encode to series of [length value]"
	s [series!] "The series to encode"

 /into {Insert into a buffer instead (returns position after insert)}
	output [any-block!] "The output buffer (modified)"
	/compare "Comparator function for equvilance"
	comparator [any-function!]
	/local x r qr b e
] [
	unless into [output: make block! 2] x: none
	r: case [
		compare [[any [e: if (apply :comparator [:x :e/1]) skip]]]
		any-string? :s [[any x]]
		'else [qr: copy [quote 1] [(poke qr 2 :x) any qr]]
	]
	parse/case :s [any [b: set x skip r e: (
		output: reduce/into [offset? :b :e :x] :output
	)]]
	either into [:output] [head :output]
]
BrianH:
13-Sep-2012
They can't necessarily be added in the C code either. IIRC the devices 
table is fixed-sixe and allocated in the core code. I welcome evidence 
to the contrary.
Ladislav:
3-Oct-2012
OK, this is the long version:

tail-func: func [
    {

  Define a recursive user function with the supplied SPEC and BODY.
     	The function can use a special TAIL-CALL local function
     	to perform a tail-recursive function call.
    }
    [catch]


 spec [block!] {Help string (opt) followed by arg words (and opt type 
 and string)}
    body [block!] {The body block of the function}
    /local the-function tail-call context-word
] [
	; define a new 'tail-call local variable
	tail-call: use [tail-call] ['tail-call]
	
	; bind the given BODY to "know" the 'tail-call variable
	body: bind/copy body tail-call
	
	; find a local word in SPEC
	context-word: find spec word!
	if context-word [context-word: first context-word]
	
	; define the TAIL-CALL function
	set tail-call func spec compose [
		(
			either context-word [
				; set parameters to the new arguments
				compose [set parameters values? (context-word)]
			] [[]]
		)
		throw/name none 'tail-call
	]
	
	; define the function
	the-function: throw-on-error [
		func spec compose/deep [
			(either context-word [context-word] [[]])
			while [true] [
				catch/name [
					return do [(body)]
				] 'tail-call
			]
		]
	]
	
	if context-word [
		; get the function context
		context-word: bind? first second :the-function
		
		; replace the context word in the function body by NONE
		change second :the-function none

		; adjust the TAIL-CALL body
		; replace the 'parameters word

  change/only at second get tail-call 2 bind first context-word context-word
	]

    :the-function
]

values?: func ['word] [second bind? word]
Ladislav:
5-Oct-2012
Rebol [
    Title: "Catch"
    File: %catch.r
    Date: 5-Oct-2012/17:49:58+2:00
    Author: "Ladislav Mecir"
    Purpose: {
    	Catches local throw'
    	Ignores non-local throws
    }
]

; Error definition
system/error: make system/error [
	throw': make object! [
		code: system/error/throw/code + 50
		type: "throw' error"
    	not-caught: ["throw' not caught"]
    ]
]

catch': func [
    {Catches a throw' from a block and returns the value.}
    [throw]
    block [block!] "Block to evaluate"
    /local err disarmed
] [
	use [throw'] copy/deep compose/only [
		; "localize" 'throw' in the block
		block: (block)

		throw': func [[catch] value [any-type!]] [
			disarmed: disarm err: make error! [throw' not-caught]
			set/any in disarmed 'arg1 get/any 'value
			disarmed/arg2: 'throw'
			throw err
		]

		get/any either all [
			error? set/any 'err try block
			(
				disarmed: disarm err
				disarmed/type = 'throw'
			)
			disarmed/id = 'not-caught
			disarmed/arg2 =? 'throw'
		] [
			in disarmed 'arg1
		] [
			'err
		]
	]
]
Group: Databases ... group to discuss various database issues and drivers [web-public]
Sujoy:
18-Apr-2012
for i 1 length? ieflat 3 [either select i1 ieflat/:i [f: select i1 
ieflat/:i append f :i][append i1 ieflat/:i repend i1 reduce [to-block 
:i]]] ;am sure there is a better way of doing this...
Sujoy:
18-Apr-2012
for i 2 length? ieflat 3 [either select i2 ieflat/:i [f: select i2 
ieflat/:i append f (:i - 1)][append i2 ieflat/:i repend i2 reduce 
[to-block (:i - 1)]]]
Sujoy:
18-Apr-2012
for i 3 length? ieflat 3 [either select i3 ieflat/:i [f: select i3 
ieflat/:i append f (:i - 2)][append i3 ieflat/:i repend i3 reduce 
[to-block (:i - 2)]]]
Arnold:
10-Nov-2012
select * from table where answer = useranswer
select * form table1, table2 where table1.field = table2.field

Do you have google? Any MySQL tutorial out there holds the answer 
to your question.

Or want to compare from wihin your REBOL script? It is either [ left 
= right][do-something][do-else-thing].
Group: !Syllable ... Syllable free operating system family [web-public]
Kaj:
27-Jun-2012
I have all of Enlightenment working except the widget set. I have 
DirectFB working and am currently building GTK and Qt on top of that. 
I have all of Qt built but nothing GUI works. I have all of GTK working 
except GTK itself, so no GUI there, either, but I'm still working 
on that
AdrianS:
21-Sep-2012
Kaj, I'm curious what the plans are wrt Syllable (either desktop 
or server) and Raspberry PI. I see that more and more OSs are able 
to run on it now - just read about webOS, for example.
AdrianS:
21-Sep-2012
I got the browser to be unresponsive again and tried to kill the 
process using the System Information Processes tab, but that didn't 
work and the info applicaton became unresponsive as well. At that 
point the mouse didnt work either and when I tried to send the OS 
a ctrl-alt-del, that didn't do anything.
Kaj:
22-Sep-2012
Yeah, I saw that. Wouldn't be of much use to us then, either
Kaj:
22-Sep-2012
I'd have to give it cookies first to find out for sure. Don't want 
to do that, either
Group: Web ... Anything related to the WWW [web-public]
Arnold:
19-Sep-2012
makedoc2 results on the other hand were nicer but that was not it 
either.
Andreas:
4-Oct-2012
To "keep everything in sync" with Git, you have have to do pairwise 
syncs. Each pairwise sync can be initiated from either side, the 
respective commands being "fetch" (from remote to local) and "push" 
(from local to remote).


If you want to keep many separate sites in sync, mediating the sync 
via a central host makes sense (as it avoids the exponential explosion 
of pairwise syncs).


If you have SSH access to your web host, using your web host for 
a central Git repository is trivial (assuming you have - or can get 
- Git installed on the web host).
1 / 2691[1] 2345...2324252627