« Goals for release 0.38 | Main | ConteX Developer's Guide »

April 14, 2005

CX 0.38 half done

Im half done with 0.38 'Eagle'. The goals grew, as I've detected a simple design flaw that I needed to nip fast before I built upon it. Therefore, the prototype based OO and user defined types were delayed until 0.39.

Before I noticed the design flaw, I accomplished the building and access to arrays, and started on the construction of other objects (which will be done soon):

(cx:) make["ar1" array[ "this" "is" "my" "life"] ]
(cx:) ar1
array[ "this" "is" "my" "life" ]
(cx:) nth[ar1 3]
"my"
(cx:)

Isn't that awsome? The array, when printed back, appears as the code required to build the array! The main reason this is done is because it simplifies the expirience with the language. It shows a precise correlation with the construction of the entity and the entity's appearance after construction. I'll be continuing this throughout the rest of CX.

Also, notice that the array index starts with 1 and not 0. All index values in CX will be counting numbers. I believe this is a way to rid the mocking of low level languages ( like C ) where indexes start at 0 only because of the pointer arithmetic involved in arrays. Pointer arithmetic is hidden from the CX programmer.

Eagle will be release as soon as I finish all-around object constuction and allow easy access to all of the java collections.

Now, the problem with CX. In Dove, there are two possible tags for the quotes: @ and $. @ meant scoped, and $ meant unscoped. Each quote would keep track of the number of times the word 'inp' is used in the quote, and if that quantity is more than 0, the quote would be declared to be unary (taking input). The problem with this is that one may want to have a function that uses the 'inp' of its surrounding context. For example:

(cx:) make["tell-inp" @{ print-line inp }]
(cx:) make["inp" 3]
(cx:) tell-inp
(cx:)

What happened here is that tell-inp required input and is not waiting for it. I wanted it to print 3, but since 'inp' was found in it, it became a unary function. I first thought this auto-input thing was going to be great. So I took a break and sat around thinking about how to preserve this remote-context word definition power, without any crappy overlapping of inp's... then a solution hit me. here is my dream (this is a fantasy, and will work when CX 0.39 is released) :

make["my-function" @{
expand-inputs this
println arg3
}]
my-function[ "my" "life" "sucks" ]
computer prints: sucks

What in the world was expand-inputs and where did arg3 come from? expand inputs would be a decorator, which is a function that defines words in the given context. It is not really specially marked as a decorator- that is just a term to use for eliminating confusion about a function's purpose. expand-inputs would look like this:

make["expand-inputs" @{
make["the-context" inp]
make["num" 1]
each[
{
make["var-name" string-cat["arg" to-string num]]
make-in[the-context var-name inp]
inc "num"
}
the-context
]
}]

So far, all of this code would be in the same context. CX is dynamically scoped, but has a special feature to spawn lexical boundaries between chunks of code. To do so, you pass a code block to context: , and that block then becomes the constructor for a context. When this is done, all of the variables begin to persist, and the new context cannot refer to anything in the current context, unless this context is passed as an argument. Let's reuse my-function as a constructor to build a context and refer to something inside of it.

make["my-context" context:{my-function["a" "b" "c"]}]
computer prints: c
from[my-context "arg2"] => "b"

I made a context which continued to exist as my-context. I'm not sure if I'll call it 'from', but that is the way to call/refer to functions/variables in another context. 'from' would be built with a primitive for running a quote inside another context:

make["from" @{
expand-inputs here
remote-eval[arg1 arg2]
}]

Finally, the difference between here and this is important and can help you understand contexts even more. When the function 'context:' is given a quote with a call in it, a new mapping of variables-to-values is created. Within this new context , 'this' refers to that context itself. If the code was run without being passed to context:, it would make a new scope, but not a new context. 'here' refers to the current scope. 'this' refers to the current context. I may change these two to this-context and this-scope.

All of this context stuff is well-thought-out after I took a good break from coding CX to relax myself and take every route possible (mentally) as I also play with Factor, Slava Pestov's language which exploits the power of concatenative programming and factoring out code.

Posted by Rex at April 14, 2005 08:47 PM

Comments

Post a comment




Remember Me?