<?xml version="1.0"?>
<rss version="2.0">
 <channel>
  <title>REBOL 3.0 Front Line</title>
  <link>http://www.rebol.net/cgi-bin/r3blog.r</link>
  <description>A place for publishing comments and discussions about REBOL 3.0.</description>
  <language>en-us</language>
  <copyright>Carl Sassenrath 2008</copyright>
  <generator>REBOL Messaging Language</generator>
  <item>
   <title>Simple, Clean VID Requirements</title>
   <link>http://www.rebol.net/r3blogs/0132.html</link>
   <author>Carl Sassenrath &lt;no-spam@rebol.com&gt;</author>
   <pubDate>Tue, 6 May 2008 12:48:34 -0400</pubDate>
   <description>Over the years, I've written a lot about VID, the REBOL Visual Interface Dialect. VID is important because it is how we create GUI's in REBOL. 

We are now ready to complete VID3 for R3.

We want to be sure we get it right. How do we measure &#034;right&#034;?  Well, we each have different requirements, but in general, we should all be happy with it. And, I need to be happy with it too, which is critical.

My VID requirements can be boiled down to just a  few lines, not even one page. Of course, we want all the normal features like speed and reliability, but here are the requirements I think are essential:

\table

Requirement

Details

=row

Easy to build a &#034;page&#034;

We know how HTML pages are built. Simple ones are fairly easy. I want VID to be even easier, and it can be. It is not difficult, and only in this way can we get a lot of people, even non-programmers to build VID pages.

=row

All the basic GUI elements

We need all the basic GUI elements as a standard part of VID. What elements do I mean? Well, we need at least the HTML basic widgets/gadgets. I want to be able to create a selection text list or a table with just a few words - and, nothing complicated about it. (Of course, we will add a lot more than just the basic HTML widgets, since most apps need more than that.)

=row

Smart defaults and options

We want VID to make smart choices for the common patterns.  We know what these patterns are. VID2 taught us that. So has the web. If we are forced to specify the same argument or attribute multiple times, then we have failed this requirement. I would also include the need for smart options. If I want to limit a text field to just numeric entry, it should only require a special option word, not code.  We can build a lot of GUI's quickly this way.

=row

Not difficult to extend

We do not want VID to be difficult to modify or add new styles, new looks, and new behaviors. Any user should be able to change the look of something just as easily (and maybe easier) than they would change a CSS (style sheet) in HTML. If an &#034;average scripter&#034; cannot understand how to do this, then we failed our design.

=row

Easy application interface

The GUI is just the front end of an application. It must be attached to application code that does something useful (what is often called the &#034;model&#034;). This &#034;attachment&#034; needs to be fairly simple and clear in VID. There are different methods depending on the type of application. In a quick script, I may want to place code in the GUI itself. For larger apps, I may want to keep the GUI well-isolated from any app code.

/table

So those are the requirements that we will use to evaluate our VID 3 design.  If I've missed any critical ones (we know there are many less critical ones), please let me know, and if I agree, I will add it to the above list.

Detailed discussion of this topic is in the R3-Alpha AltME world. Or, post your comments here.
</description>
  </item>
  <item>
   <title>Port documentation updated</title>
   <link>http://www.rebol.net/r3blogs/0131.html</link>
   <author>Carl Sassenrath &lt;no-spam@rebol.com&gt;</author>
   <pubDate>Fri, 25 Apr 2008 13:31:35 -0400</pubDate>
   <description>Major revisions to the documentation for Ports in R3 have been made and published to REBOL 3.0 Ports on the wiki site. This includes numerous working REBOL 3 Port examples of how to do things like copy and transfer (over TCP) large files. Of course, you will need the latest alpha test version of R3 in order to run those.</description>
  </item>
  <item>
   <title>More about Port layers - the OSI Model</title>
   <link>http://www.rebol.net/r3blogs/0130.html</link>
   <author>Carl Sassenrath &lt;no-spam@rebol.com&gt;</author>
   <pubDate>Mon, 21 Apr 2008 12:50:46 -0400</pubDate>
   <description>This is a follow-up to my Pruning down READ and WRITE article and the comments posted there. Sorry, it is a bit long, but this topic requires a deeper discussion.

---OSI Layer Model

Before I begin, please review OSI layers model. This is the standard layered model of network architecture that has been around for about 30 years.

Ok, so what does it all mean?

When you design any type of &#034;operating system&#034; (and that can include a runtime system such as a TCP stack), you try break it down into clean, well isolated (decoupled) layers. At least, that is always the goal. However, it's not always possible to make it perfect, because the layers interact, and sometimes that interaction is complex or the necessity of performance requires closer coupling than is ideal. (In fact, that's why after 10 years of being a total object-oriented system advocate, I backed away from it. But I digress, that is the subject of a separate blog.)

---Layers in Ports

REBOL ports are no exception. You can apply the OSI model to ports (even though we use them for more than just networking.)

For example, if you open a port, and you need to provide an awake function for it, then you are creating code at Layer-5, the session level. Layers 1-4 below it are handled by the operating system, its device drivers, and hardware.

If you don't need to write an awake function, then you are using a higher level port. For example, if you write:

    data: read http://www.rebol.com

the HTTP port scheme knows about things like headers, transfer lengths, and content encoding. In this example, HTTP is working at layers 6 and 7. Part of HTTP is to send headers which must be interpreted. In other words, they obtain a context and a meaning. The data is no longer just a string of bytes.

In REBOL, we can create and use ports at different levels.

The lowest level is that of reading raw bytes. When you open a REBOL TCP port and start reading and writing data, you are sending bytes. The meaning of those bytes is not defined by the port itself, it is defined by your application. TCP I/O is a lower level operation.

However, once you begin to interpret the meaning of those bytes, you move to a higher level, and there can be multiple levels.

---So, you want it decoded?

One of the first steps to &#034;get the meaning&#034; is to decode the bytes.
To convert a stream of bytes into a string of characters, you need to know how the characters are encoded. Are they in UTF-8 or UTF-16, or maybe the data are in a compressed format?

You can then ask, &#034;how do we know the encoding?&#034; Well, there are two main methods:

#It is embedded in the data. Something about the data tells us its encoding. For example, Unicode can use a BOM to tell us its encoding. Many image formats include a &#034;magic&#034; signature to tell us what they are, e.g. JPEG uses &#034;JFIF&#034;. An HTTP header tells us information about the encoding of the data.

#It is specified separate from the data. The encoding is specified to a function that handles the data. This is the /as option we talked about before. For this to work, we already know the encoding in advance. It came from somewhere external to the data. For example, if we noticed that the filename suffix was .jpg, then we can use that information for decoding the format. This is what MIME types are all about.

In reality we often use a mix of these. For example, we may examine HTTP data to find the content-encoding, which we then specify to a decoding function.

---So, you want content?

Decoding often means a lot more than just converting bytes to characters. An image file contains structures that give you information about the image, such as its width, height, colors, compression, and more. Even a text file may be in REBOL format that gets loaded into block format so we can interpret its content.

In the design of a system, we must ask ourselves where do we want this content decoding to happen, and how &#034;automatic&#034; is it?

An extreme case would be to ask: If you read bytes from a TCP port, does &#034;the system&#034; automatically determine the bytes are an image and return to you a decoded image datatype?

I think we can obviously say no to that. We want TCP as a stream of bytes. Any other decoding should be part of a separate layer.

This layer rule about bytes versus content applies to a lot more than just images. In R3 it also applies to text, because we now care about Unicode, and have become more text sensitive.

---Building the Layers

Ok, so we are now at the fun part: What is the smartest way to handle these layers?

Well, REBOL already has a basic model. We know that the load function is supposed to take data and produce content. We load REBOL code and data, we load an image, and we load a sound. We also know that we read raw bytes from a network or a file.

That basic model provides the top and the bottom layers, but the question is, do we want to access the intermediate layers too?
In the past, we would write:

   insert port &#034;some text data&#034;

and expect:

   probe copy port
   &#034;some text data&#034;

But now, we support Unicode, so we have added an additional requirement. What is the encoding of the text? And, where does it get decoded?

In order to handle that, we invented the /as refinement to indicate the encoding. Using R3 port read method, it was:

   text: read/as tcp-port 'utf-8

However, applying this refinement at a lower level makes the lower level a lot more complicated! At first, it may not seem like it, but once you get into the details, you find some problems. For example, UTF-8 encoding is multi-byte per character. What happens if we read from TCP, and we don't get all the bytes necessary to decode the last character? We must hold it in a special buffer and insert it into the head of the next part of the data stream. This also goes for CRLF text line conversions as well.

In the past, the way we solved this problem was to use multi-level ports. For example, when you use the HTTP scheme and read from its port, it is not the actual TCP port, it is a virtual port. Within the HTTP scheme code itself is a hidden TCP port.

So, the HTTP port is doing whatever &#034;magic decoding&#034; it needs to do in order to create the result we need.

Using this approach, we can say that maybe we can allow read of an HTTP port to return properly decoded text. In such a case, read is returning a string datatype not a binary datatype. That may be fine.

Of course, we want to determine how far to go with that model. For example, if I read an image using HTTP, do we get an image returned from read? I'd say no. In that case it may return a byte stream, because we may not want the image fully decoded at this point. For example, if it is JPEG, we might want to write it as a JPG file.

So, it is conceivable that we can create a TCPS scheme, for TCP String, that provides a layer on top of the lower level TCP to deal with the necessary string encoding. The TCPS scheme can be implemented in REBOL itself, allowing it to be extended and improved without requiring native code changes. It would then be possible to write:

    &#062;&#062; port: open tcps://example.com:8080
    &#062;&#062; write port &#034;a string&#034;
    &#062;&#062; print read port
       &#034;got it&#034;

And, because open now defines a concept of specification, it is possible to even provide information about the type of encoding we want to use. An example would be:

    port: open [
           scheme: 'tcps
           host: &#034;example.com&#034;
           port-id: 8080
           encoding: 'utf8
    ]

Of course, the TCPS scheme would be implemented with TCP, with that port being embedded within it. And, that's the main point: The lower level TCP layers do not need to deal with encoding and decoding. It just cares about bytes.

---Back to the goal...

So, is this a good approach?

It depends on what we want, doesn't it? In REBOL, we have this objective:

#Simple things should be simple.

#Complex things should be possible (and as simple as possible).

So, we want to be able to simply get text from a file, or data from a REBOL script, or an image from an image file. We want to write code like:

   data: get-the-contents-of %file
   data: get-the-contents-of web-url

Earlier, people objected to the idea that we might provide helper functions such as:

   data: read-text %afile

because it would mean enumerating that for all datatypes, such as read-image, etc.. I agree.

But, if we want to avoid that, we need to say that we are going to use a much smarter function, one that can properly identify the content and decode it.

I do not think of that as the main purpose of read. To me, that seems more like what load does. And, we are allowed to make load as smart as we want. For example, load may use a system table that contains suffixes and take a MIME-style.

The result may be something like this:

    image: load %photo.jpg
    code: load %script.r
    text: load %info.txt

where, .jpg, .r, and even .txt are defined within a system/load-types table of some kind. In the case of .txt, the default would examine the BOM for UTF encoding. I think we can do a smart design job of keeping it simple.

For things like network transfers, when we write more complex code such as handling our own transfers with our own port awake functions, I do not think it is a big problem to deal with a few more details, such as encoding.

And, of course, as we find patterns to more complex usage, we can create new schemes or add options to existing schemes, to help simple things remain simple.
</description>
  </item>
  <item>
   <title>Simple TCP example: HTTP web page transfer</title>
   <link>http://www.rebol.net/r3blogs/0129.html</link>
   <author>Carl Sassenrath &lt;no-spam@rebol.com&gt;</author>
   <pubDate>Sat, 19 Apr 2008 13:58:59 -0400</pubDate>
   <description>(Updated 21-Apr-2008)

Here is a really simple example of how to do low level TCP networking  to fetch a web page from a server using the HTTP protocol.

Normally, to use HTTP you would use a simple line like:

    data: read http://www.rebol.com

It would handle things like redirection and HTTP errors. But, for our example below, we will show how to do low-level asynchronous TCP.

---Important notes...

To begin, let me point out a few important things, then I will give you the full script, then I will explain how it works.

#The recent Unicode installment requires that we use binary for network
transfers. Why? Because strings can be encoded (such as in UTF-8
format), but don't worry. It's not hard to handle them.

#This code is tested under the lastest alpha release (2.100.5 - coming
soon to servers near you). It should work on older versions, but has not
been tested.

#The transfer is asynchronous by default. In other words, when
you ask to read data from the network, the read function returns
immediately, and a handler function will be called whenever new data
arrives.

---The code...

Ok, so here is the full script, all 50 lines of it:

    REBOL [Title: &#034;Tiny HTTP Reader&#034;]

    read-http: func [
        &#034;Perform an HTTP transfer&#034;
        url [url!]
        /local spec port
    ][
        spec: decode-url url
        spec/2: to-lit-word 'tcp
        port: open spec

        port/awake: func [event] [
            ;print [&#034;Awake-event:&#034; event/type]
            switch/default event/type [
                lookup [open event/port]
                connect [send-http-request event/port]
                wrote [read event/port]
                read  [
                    print [&#034;Read&#034; length? event/port/data &#034;bytes&#034;]
                    read event/port
                ]
                close [return true]
            ] [
                print [&#034;Unexpected event:&#034; event/type]
                close event/port
                return true
            ]
            false ; returned
        ]
        port
    ]

    send-http-request: func [port] [
        write port to-binary ajoin [
            &#034;GET &#034; port/spec/path &#034; HTTP/1.0&#034; crlf
            &#034;Host: &#034; port/spec/host crlf
            crlf
        ]
    ]

    print &#034;reading...&#034;
    rp: read-http http://www.rebol.net/builds/
    wait [rp 10]
    close rp
    print to-string copy/part rp/data 4000

---How it works...

The example starts with the main read function:

    read-http: func [...

It decodes a URL into a block that we use to open a port:

    spec: decode-url url
    spec/2: to-lit-word 'tcp
    port: open spec

You can add a probe to see what spec is:

    [scheme: 'http host: &#034;www.rebol.net&#034; path: &#034;/builds/&#034;]

The second value in the block is the scheme type, which we must
change from HTTP to TCP for the port to be opened by the TCP scheme (a native device.)

The open function accepts several different types of specifications. Our spec block is just one possibility.

Also keep in mind that the port does not open immediately. When open returns, it only means that the port was created, but not that the TCP connection (socket) has been made.

The fun stuff starts with the line:

    port/awake: func [event] [

This defines the port awake handler that will receive TCP events
during the transfer. Each time an event arrives, the awake handler
will be called. It is a callback function.

This line dispatches the event, based on its type:

    switch/default event/type [

For our TCP example, we care about these types of events:

*lookup - when the host address has been found by DNS.

*connect - when we have connected to the host (web server). At that point, we
send our request. More on that below.

*wrote - when the write has done. Now, we start to read data.

*read - a packet has been received, save its data, and ask for the next one.

*close - the port has closed. Returns TRUE to cause an event.

If the event does not match those, then we assume it is an error, and we
print a message and terminate the transfer.

Note that the awake function returns either TRUE or FALSE. This is
important. A TRUE value is used to say &#034;we are done.&#034; It will cause
wait to return, as I will show below.

We send the request to the server with the function:

    send-http-request: func [port] [

This function builds a little HTTP header. It's about as simple as it
can be. We use ajoin to build a string and then we must call
to-binary to convert it to binary. The default is UTF-8 encoding.
(Other encodings can be done too, but more on that separately.)

You may notice we build an HTTP 1.0 header. You could use a 1.1 header,
but if you do that, the TCP socket (the connection) may remain open,
and the only way to know you are done is to parse the HTTP reply header.
Since we don't want to do that for this little example, we use HTTP 1.0.
It closes the socket after the reply has been sent.

Finally, we are ready to make it happen:

    rp: read-http http://www.rebol.net/builds/
    wait [rp 10]
    close rp

This calls our new function with a URL to read, and it returns a port
(rp). We then use that port to wait for the read to finish or for a
timeout to occur. Here the timeout is 10 seconds. Then, we close the
port. This is done to force any cleanup of the TCP/IP stack state.

And, finally, we print the result with:

    print to-string rp/data

We use to-string to decode the page contents to text. It assumes
UTF-8 Unicode encoding. But, of course, other encodings are possible
too.

Ok, so when you run the code, you'll see a progress report, then the
HTTP page contents:

    Evaluating: web-net.r
    reading...
    Read 252 bytes
    Read 1964 bytes
    Read 5136 bytes
    Read 9768 bytes
    Read 15860 bytes
    Read 23412 bytes
    Read 32424 bytes
    Read 42896 bytes
    Read 54828 bytes
    Read 68220 bytes
    Read 83072 bytes
    Read 99384 bytes
    Read 117156 bytes
    Read 136388 bytes
    Read 156035 bytes
    HTTP/1.1 200 OK
    Date: Sat, 19 Apr 2008 17:50:43 GMT
    Server: Apache
    Last-Modified: Fri, 04 Apr 2008 23:28:12 GMT
    ETag: &#034;1ec06f-4bc3-78b87b00&#034;
    Accept-Ranges: bytes
    Content-Length: 19395
    Connection: close
    Content-Type: text/html; charset=UTF-8

Notice that the HTTP header shows the content type is UTF-8. So, the
to-string decoding did the right thing.

Voila! There's the TCP example in R3. Yes, it's just a start, but you can
build on it. For instance, you may want to parse the HTTP header to
determine the Content-Length and Content-Type.

Have fun.
</description>
  </item>
  <item>
   <title>SKIP and SEEK on Ports</title>
   <link>http://www.rebol.net/r3blogs/0128.html</link>
   <author>Carl Sassenrath &lt;no-spam@rebol.com&gt;</author>
   <pubDate>Wed, 16 Apr 2008 13:38:27 -0400</pubDate>
   <description>As you may or may not know, in R3, a port value no longer stores the series offset. Instead, the offset is determined at a lower level within the port object.

As a clear example, if you write:

   port: open %file
   d1: read/part port 100
   d2: read/part port 100
   ...

You will read the first 100 bytes, then the next 100 bytes, etc.

But, what if you want to read 100 bytes offset at a specific location, say 1000 bytes into the file. There are two possible solutions.

---Method 1: use a refinement

We can add the /at refinement:

   data: read/part/at port 100 1000

The advantage is that the seek operation occurs during the read action itself, so the port handler and device are only called once. This eliminates a small amount of overhead, at the small cost of an extra refinement.

Another advantage is that you can read part of an unopened file:

    data: read/part/at %file.txt 100 1000

So, everything happens on that one line. It can be useful at times.

---Method 2: Make the AT action work for ports

This would be defined to specify the absolute position, and would effect the port state.

   at port 1000
   data: read/part port 100

And, because at returns the port, you can write:

   data: read/part at port 1000 100

The advantage is that we can eliminate one refinement from read, but we must make the additional call for at, which is an extra call to the port handler, dispatched to the device.

---SKIP also could be allowed

For both of these, it would also be possible to support skip, a relative offset function:

   data: read/part/skip port 100 512

and:

   data: read/part skip port 512 100

---My opinion...

I would say that I am leaning toward the refinement. The two main reasons are:

#It eliminates an extra call to the port handler and device, and it calls the seek immediately before the actual low level read.

#It works for un-opened files, so you can easily fetch a chunk from a file without opening it beforehand.

Note that it may also be possible to allow both the refinement and the at but is there an advantage in that?

But, I'm writing all of this to get your comments, so let me know your thoughts.</description>
  </item>
  <item>
   <title>Pruning down READ and WRITE</title>
   <link>http://www.rebol.net/r3blogs/0127.html</link>
   <author>Carl Sassenrath &lt;no-spam@rebol.com&gt;</author>
   <pubDate>Wed, 16 Apr 2008 12:56:39 -0400</pubDate>
   <description>As you know, read and write functions in R3 will default to binary, rather than string. This is necessary because:

#Strings are encoded as binary, for example UTF-8. So in order to decode them, we must know how they are encoded. If the file has no BOM (byte order marker) then its encoding is unknown and must be provided to the function itself.

#Running in binary mode will not accidentally corrupt a file. This is the ancient FTP transfer binary/text problem. If you transferred an image using FTP text mode, the file could be damaged if line terminators where found.

A few days ago, I proposed new read and write functions that add an /as refinement. This refinement allows you to specify the encoding:

  data: read/as file 'utf-8
  write/as file data 'utf-16le

This is useful because the encoding can be specified as part of the function call. However, this also makes this approach the standard method for reading and writing all decodings, even those for image files, etc. For example:

   image: read/as file 'jpeg

Our plan was to add an intermediate layer in read and write to allow for codecs (encoding and decoding). They would be stream oriented to allow for partial transfers, and also &#034;fragments&#034; (when not enough data has been received to finish a well-aligned encoding or decoding process.)

Of course, all of that makes read and write more complicated.

---The question is: do we want to do that?

Another factor is that the old R2 lower level I/O functions read-io and write-io have been eliminated from R3. The read and write functions have that capability now.

So, we can say that it all boils down to: are read and write lower-level or higher-level functions?

---After some consideration, I think they should be lower-level functions.

This would mean that they should be as fast and efficient as possible. This also implies that they should have as few refinements as possible (because, as in any language, the more function arguments there are, even if optional or local, the more overhead the function call has, because those slots must be allocated in the function frame.)

Ok, if we do that, function like read can be defined as:

    read file /part size /skip len

That's really pruned down compared to R2. We could prune it even more by adding a seek function to eliminate the /skip refinement.

---So, what about the primary REBOL rule of keeping things simple?

This is important, and the solution would be to provide higher level mezzanine functions that provide the necessary encoding.

For example, we could have:

    str: read-text file
    write-text file str

This read-text function could be smart in many ways. For example, it could examine the BOM of the file to determine the encoding. It would also make the line termination corrections.

Note, because it is a mezzanine function, users have access to easily improve it over time.

We would also provide an /as refinement:

    str: read-text/as file 'utf-16le

and, even:

    write-text/bom/as file 'utf-16le

To indicate we want the BOM inserted at the head of the file data.

So, there you go. Let's do a quick survey of REBOLers and get some comments.</description>
  </item>
  <item>
   <title>Week of 14-Apr-2008</title>
   <link>http://www.rebol.net/r3blogs/0126.html</link>
   <author>Carl Sassenrath &lt;no-spam@rebol.com&gt;</author>
   <pubDate>Mon, 14 Apr 2008 14:53:59 -0400</pubDate>
   <description>The R3 project focus this week is defining the primary read and write options for ports, files, URLs (includes open). Most of the required changes relate to how we specify Unicode encodings. Other changes are intended to eliminate unnecessary refinements. Specs will be posted on the DocBase wiki.
</description>
  </item>
  <item>
   <title>Test suite - A progress report</title>
   <link>http://www.rebol.net/r3blogs/0125.html</link>
   <author>Carl Sassenrath &lt;no-spam@rebol.com&gt;</author>
   <pubDate>Wed, 9 Apr 2008 14:06:53 -0400</pubDate>
   <description>Just a quick progress report on the R3 test suite...

The new test suite is running, as a first draft design. It will be published soon (maybe today?) for the R3-Alpha test group (a private test group). In addition, I will be providing documentation to explain how it works, and how users can extend the tests simply by modifying the test suite data files. Once the R3-Alpha group approves the tests, they will be released more openly.

The test engine is built mainly on the reflective test approach, where thousands of test vectors (singular test expressions) are generated and then tested, driven by small test specification files -- each typically only a page in length.

As a result, the tests require validation through inspection of their log files. Once inspected, a hash checksum tracks if changes have occurred, in either the results (test failures) or from the introduction of new tests.

The method seems sound, but I think there could be a problem with the quantity of tests generated. Currently, with only five (of 56) datatypes tested, there are more than 22'000 test vectors, and they build exponentially. We may end up with more than a million test vectors for the final suite.

Although the hash approach works well for detecting failures and other variations, one must compare the test log files to determine specific differences. And, I am a bit concerned that the comparison required may be beyond the capabilities of most &#034;diff&#034; (change differencing) programs.

This will require some thought. Since the log output is a set of vectors itself, it may be possible to develop a specific diff method that works well for these larger data sets. (If not, then we may need to borrow La Sorbonne's supercomputer to analyze our results each time.)

Once the tests are released, let me know your opinion in this area.
</description>
  </item>
  <item>
   <title>The Story of ALTER</title>
   <link>http://www.rebol.net/r3blogs/0124.html</link>
   <author>Carl Sassenrath &lt;no-spam@rebol.com&gt;</author>
   <pubDate>Fri, 4 Apr 2008 20:02:26 -0400</pubDate>
   <description>Alter is a mezzanine function that is a shortcut for alternating between insert and remove of a value.

Alter looks to see if a specified value is already part of a collection (in block). If not, it adds it. Otherwise, it removes it.

Here is an example:

    &#062;&#062; flags: []

    &#062;&#062; alter flags 'resize
    &#062;&#062; flags
    == [resize]

    &#062;&#062; alter flags 'maximize
    &#062;&#062; flags
    == [resize maximize]

    &#062;&#062; alter flags 'resize
    &#062;&#062; flags
    == [maximize]

Alter came about during the creation of VID(2), where we wanted to add or remove flag values from various blocks of flags.

Some users have suggested that the function is not worthwhile and should be removed from REBOL.

Should it be removed?
</description>
  </item>
  <item>
   <title>OSX Intel - Alpha V 2.100.3</title>
   <link>http://www.rebol.net/r3blogs/0123.html</link>
   <author>Carl Sassenrath &lt;no-spam@rebol.com&gt;</author>
   <pubDate>Mon, 31 Mar 2008 16:58:47 -0400</pubDate>
   <description>A preliminary alpha test version for OSX -- the first to be released to alpha testers. Largely, this is untested -- so keep watch for any significant problems and report them to us.</description>
  </item>
  <item>
   <title>Alpha V 2.100.3</title>
   <link>http://www.rebol.net/r3blogs/0122.html</link>
   <author>Carl Sassenrath &lt;no-spam@rebol.com&gt;</author>
   <pubDate>Sat, 29 Mar 2008 02:10:47 -0400</pubDate>
   <description>This release fixes many bugs found in 2.100.2 (the first Unicode prototype for wider testing, released two days ago.)

In this release, special focus was placed on fixing all known crash bugs.

Please run as many basic low level tests, such as datatype functions (polymorphic actions), as you can on this release. We would like to have a solid core ready for beta release during April.
</description>
  </item>
  <item>
   <title>Meaning of TO-LOCAL-FILE</title>
   <link>http://www.rebol.net/r3blogs/0121.html</link>
   <author>Carl Sassenrath &lt;no-spam@rebol.com&gt;</author>
   <pubDate>Fri, 28 Mar 2008 19:58:14 -0400</pubDate>
   <description>For R3 Unicode, we need to more precisely define a few functions. One of those is to-local-file -- used to convert file names from REBOL format to the local OS format.

Specifically, if we want to-local-file to return a string (given a file datatype), then that string remains in REBOL's internal format, not the OS native format (e.g. wide-chars on Win32 and UTF8 on Linux).

So, when we say to-local-file we only mean the higher level conversion of the string, not the lower level encoding of the filename. That encoding must occur later, such as when the file is opened for read or write.
</description>
  </item>
  <item>
   <title>R3 Project Status Update</title>
   <link>http://www.rebol.net/r3blogs/0120.html</link>
   <author>Carl Sassenrath &lt;no-spam@rebol.com&gt;</author>
   <pubDate>Thu, 27 Mar 2008 12:22:33 -0400</pubDate>
   <description>This week we concentrated our full attention on testing the new R3 Unicode core (but not just Unicode testing, all datatypes).

We've generated more than 30'000 test vectors and found and fixed dozens of bugs discovered in that testing (including several important ones that would cause R3 to crash.)

Although we think that 30'000 tests is only about 30% of the total tests needed, it is a good start and has helped us to make a more reliable core.

If you are interested in helping with the R3 testing effort at the core level (no-externals, no graphics, no gui, no network), please let us know by posting a message in R3-Alpha or via RT Feedback.
</description>
  </item>
  <item>
   <title>Redefining BINARY!</title>
   <link>http://www.rebol.net/r3blogs/0119.html</link>
   <author>Carl Sassenrath &lt;no-spam@rebol.com&gt;</author>
   <pubDate>Wed, 5 Mar 2008 14:24:48 -0500</pubDate>
   <description>I've ready your feedback on my prior note about the use of INSERT for the BINARY datatype. Thanks for the quick feedback.

In order to make progress and resolve these issues as quickly as possible, we have to break down the problem into smaller chunks.

For example, these are fundamentally different binary actions (bin is a binary series):

    insert bin &#034;test&#034;
    insert bin 123

The first is a question of auto-encoding (converting) a string to be a binary value; should it be UTF-8 encoded and should LF's be converted to CRLFs.

The second is a question of semantics: are we asking for the byte value 123 or the integer string representation &#034;123&#034; to be inserted? (And then you could then add the above encoding question on top of that.)

In R2, we converted 123 to &#034;123&#034; then inserted that. Why?  It came from this the desire to have:

    port: open/string %file
    insert port 123  ; here port is of string type

be very close to:

    port: open/binary %file
    insert port 123  ; here port is of binary type

We wanted them to be consistent. You can see why by the example.

However, in real life, there is no such thing as perfect consistency. There are always exceptions, even in the mathematics of computer languages and denotational semantics.

After all, what does it mean to do this?

    insert bin image

Such a statement implies that a flat binary serialization of an image has meaning. In reality, it is of little use to us as written, because an IMAGE is  a composite value, it includes more than just image data; we need to know at least the width of a line in pixels and size of a pixel, or we lose information in the above insert.

This is true of many other datatypes as well. What does it mean to have any specific datatype converted to or from binary? Examples? There are many:

    to-binary &#034;text&#034;
    to-binary 123
    to-binary 12.3
    to-binary #123
    to-binary 1:23
    to-binary 1-2-2003
    to-binary image
    to-binary object
    to-binary charset &#034;abc&#034; ; a bitset

And, of course, you have the reverse conversions. I will not list them; they are pretty obvious.

In the past, we've had &#034;the luxury&#034; of ignoring a precise definition of BINARY.

We can no longer afford to do that. It must be precisely defined.

Yet, time is short. R3 must move along.

\note Possible conclusion?

My current inclination (working conclusion) is that perhaps we need to remove all to-binary conversions entirely, then bring them back one-at-a-time as we can properly define them.  And, if we cannot define them, they will not exist.

In this way we will avoid creating a set of new incompatibilities with our future R3 implementations.

/note</description>
  </item>
 </channel>
</rss>
