« October 2004 | Main | February 2005 »

November 30, 2004

renaissance period

The last two articles spell out 'mistake'. Now is time for 'rebirth' or large changes to the codebase, which includes re-implementation and even some file-renaming.

Sequences have been explained as pretty much a colon definition in CX. If you have ever done a concatenative language, you'd understand what I just meant. The main thing is that sequences need inp- they need input because they ARE the fundamental way of taking action in CX, and with CX being applicative, you must be able to apply the fundamental actions to something. Now, inp is only for sequences, and acts no differently inside a list or outside a list: if it is found inside braces, the evaluation of the next word will replace that 'inp'.

The new evaluation system implements tail call optimization and lays easy paths for compilation, callstack tracing, and user defined objects. Next article should be one of success, and specification of how to use these things.

Posted by Rex at 08:30 PM | Comments (0)

November 28, 2004

[inp]ossible things in sequences

I've discovered that it is impossible to have control over the contents of a sequence from outside the sequence without using variable names. One may want something similar to inp, but for sequences. The design of CX doesn't allow this.

I cannot think of a time when a user would have to do it, but if you have a sequence without any lists, and want to use that sequence in an applicative way, you can only use a plain variable (not inp). To understand this fact, one must understand how and when inp is used.

inp is a special word that is only to be used in lists. CX has applicative lists, and inp is the symbol for placement of the argument. Lists are made with square brackets, and if the word inp is found inside the brackets, the evaluation of the next word is moved into the place of the inp. Here are some examples of ways to use inp:

[ inp inp ] 3 => [ 3 3 ]
[inp inp] [inp] 3 => [ [3] [3] [3] ]
+[2 inp] 5 => 7

Outside of lists, inp cannot be used. If a sequence does not use a list, no inp is allowed in the sequence either, because using the word that points to a sequence is just like typing out the sequence itself. Therefore we cannot have applicative sequences. At most, we can have a sequence of words where the next word after the sequence itself will be used:

set["twice" unquote {*[2 inp]}] (standard 'twice' function)
set["twiceAlias" unquote {twice}]
twiceAlias 3 => 6

Of all of the programming I've done in CX, I've never come across this, but I did notice it in an irc conversation , where I accidentally used inp at the top level, inside a sequence. This gives sequences the feeling of word definitions in concatenative langauges. A person might be writing functions too big if this problem is hit. Consider factoring. At the same time, just becuase I haven't found a case where one would have to do such a thing doesn't mean I shouldn't think of a more efficient way to deal with it than variables.

Please comment. Btw, the title of this article evaluates to
[ ossible ] things in sequences
Remember: inp must be in a list.

Posted by Rex at 01:13 AM | Comments (1)

November 26, 2004

Sequences!

ConteX has gained the advantage of sequences. Sequences are like quotes, except are 'active'. When a word contextualizes to a sequence, the evaluator executes the sequence.

The concept is something I personally have never seen before, but it works fine in this language. Before telling what sequences really are and how they are used, I must present the set of dillemas I was hit with in the designing of this language.

When I first made CX, I had few harsh and stiff rules in my mind. One of those rules were about the 'set' command, being the central way of constructing things upwards from the foundation. set would take a list containing 1 string, then one of anything. The string that set would take would be put into the context that the user is currently in (right know, you are stuck in the 'prim' context). Functions are in included in the scope of 'anything', so they were to act just like strings, numbers, or any literal. To build a function, a person would set ["theName" {the quote}] , then whenever the person refers to theName, the quote would be executed.

This has a problem. You've set["theName" { the quote }], and now you aren't getting { the quote } back when you mention theName. In other words, the evaluator was made to execute any quote that a word contextualized to. I thought of it as an ugly thing, but I couldnt find a better way. The other options were:

-just make theName refer to { the quote } so that saying theName doesn't execute it , but returns it. Now use eval theName, and you can continue. The problem with this is that you'd have to eval every damn function. That is tedious. Also notice that eval itself would have to be eval'd if I wanted it to be concidered a function- now you can't do anything, unless you have some kind of inconsistancy.

-just leave things the way they are: if I set["x" {+[2 3]}] x=> 5 . This was the ugly status quo and I can find more reasons it should not BE. It is inconsistant, number one, because when I set "x" to anything else, and later use x, that something else can replace the x and the code will work fine. For example, if I set["x" {+[3 4]}] , then later say +[x 3], the x in the list for addition should expand to [ {+[3 4]} 3 ] , which would make the '+' function fail because one of the list nodes is NaN.

-The BEST solution is to make a switch on the quote to say whether or not it should execute on contextualization or not. imagine if I had the primitive: 'switchOn' and 'switch Off'. When you pass switchOn the quote, the quote is turned 'on', and when something contextualizes to it, it is executed, not referred to. set["x" switchOn {+[2 3]}] , now x => 5. then, set["x" {+[2 3]}] , now x => {+[2 3]} . now, set["y" switchOn x], y => 5 ! Isn't that beautiful?

I've almost explained it all, but there are small things that need to be fixed in the last option. First of all, we have not seen switchOff. let's try it.

set["x" switchOn {+[2 3]}]
x
=> 5
set["y" switchOff x]
y
=> {+[2 3]}

I know. It looks fine for a second, but remember that I want complete consistancy, or as much as possible. On the definition of "y" , switchOff x would really 'expand' to switchOff 5, because x was switched on, and when something contextualizes to a switched on quote, it is evaluated, remember?

So now, I evince to you the best way. Sequences. The final conclusion uses most of the concept just explained in the previous paragraph, but is polished with a different kind of switchOff and different names for those functions. Rather than explaining all that stuff, I'll just re-write the 4 lines of CX code , using the final concept:

set["x" unquote {+[2 3]}]
x
=> 5
set["y" quote "x"]
y
=> {+[2 3]}

I called them unquote and quote to give the user the concept that the actions are really being taken on the braces around the quote. In other words, unquote takes away the braces on a quote, and quote puts them back on! The quotes are are "switched on" are called sequences, becuase they are just sequences of words, just like a quote, but these sequences of words have no " { " and " } ". They are bare, and when you use a word that contextualizes to a sequence, it is as though you typed the sequence out manually. You must use unquote to produce sequences. The new switchOff, quote, takes a string to escape the inconsistancy mentioned before.

NEATO ay? Ok, it's not perfect, but it's damn near close.

unquote {+[2 3]} => + [ 2 3 ]

Should it have returned 5? I chose no. This would be the last dot of inconsistancy. The same sequence can be given to the evaluator and we don't get 5. This is because of a new rule about sequences: The only way to evaluate a sequence is to have a word contextualize to it. Think about this: when the hell would you unquote a quote and want it to evaluate anyway? You could just type out the damn sequence. Conclusion is that we've gained the advantage of quoting/unquoting at the cost of a small inconsistancy that has no disadvantage.

Posted by Rex at 10:19 AM | Comments (0)

November 22, 2004

no means yes and yes means no

ConteX has gained a new evaluation technique: "live contextualization"."no means yes and yes means no!" This really means that it is not impossible to say the original word 'no'. This is the effect of live contextualization, a term I made to label the way the CX interpreter now evaluates code.

ConteX has changed significantly in the past 2 weeks. New features include file reading, primitives that give control over parsing and evaluation, and even support for complex numbers, big numbers, ratios, and numbers with hundreds of digits, ( from a math lib thanx to a code share from Slava Prestov. ) So now we are presented with a whole new set of problems before the release of ConteX 0.36. These problems circle around implementing 'inp', and contextualizing order.

Contextualizing order is actually the problem. Inp is a matter of my design, and is practically already solved. Anyway, in CX, 1 day ago, the following would happen:

set["x" 3]
set["talk" { set["x" 4] print x }]
talk

computer returns 3

Ugly , huh? This is because that code is contextualized into literals FIRST, then evaluated. Instead, each word needs to be contextualized and THEN evaluated. This is in the works right now. Contextualizing and evaluating each word- one at a time- is the key.

This has been fixed. Now, the Evaluater has a great design that contextualizes each word, and evaluates them. Only thing is that inp is broken again. oh noooo!

In our initial example, no means yes and THEN yes means no:


set["no" "yes"]
set["yes" no]
[ yes no ] => [ "yes" "yes" ]

( this is the only way to convert the english sentence into CX without ever referring to a word that doesnt exist, yet applying live contextualization )
When someone says "no means yes and yes means no", if you applied the new defintion of "no" at the "and", then by the time the person says "and yes means no", it means "yes means ( no, which means "yes")", or "yes means yes". Now, no means yes and yes means yes and there is no way to say no!
Try explaining that to your friend: "Applying live contextualization, you've taken away the ability to use the original meaning of 'no' !"

Posted by Rex at 05:34 AM | Comments (0)

November 06, 2004

quoted lists

CX, being implemented in java, uses objects in the implementation for lists and quotes. There are times when a list is really a quote until finally being contextualized into a list.

For example:

set["x" {+[2 c]}]
set["c" 3]
x => 5

In this code, x is set to be a quote: +[2 c]. the list in this quote is special because the letter 'c' wasn't evaluated on the spot. The whole list had to be implemented as a special kind of quote. when the quote is refered to , it will be evaluated into the list as though it was [2 c] the whole time.

The parser knows when to do this by having a quote-level counter. For every '{' encountered, the quote level goes up, and the quote level goes down for every '}' character found. The quote level starts at 0, so if the parser encounters a beginning of a list, it checks the quote level for being above zero. If it is above zero, the list is made as a quote. Else, the list is just a list.

So, if the list in { [ here ] } is parsed to be a quote, then when things are sent to the evaluater, how does the evaluater know if it was { { this } } or the previous? The object used for holding quotes has an instance boolean called 'returnList', which tells this information. Here is the source file for the quote, which is called Stack.java because of how it operates.

Posted by Rex at 04:22 PM | Comments (0)