07.04.2009

Numb Ers

So, today we will look at numbers in Babedepupi!

In the last post we used numbers as if they were a construct of the language, i.e. 432 would stand for fourhundredthirtytwo. While it's convenient, it's a special construct. Which is stupid and ugly!
Indeed we want numbers to be real objects. We can look at numbers being just sets with a certain number of elements. So we define:

UnaryNumber LinkedList
+ number
number iterate
add self

- number
number iterate
remove
* number
number iterate
+ self
print

iterate
result = result + "1"


print just prints the number in an unary representation. You might wonder, what self is. It is indeed the equivalent to the self of Smalltalk. While it looks like a keyword, we will see that we can define it in the language (?). This notation is of course quite unhandy, so we want at least to define binary numbers. We will bootstrap them with the UnaryNumbers. (A change to the syntax from the last time is that the last line of the method is the return value, so no need for a methodName = ... -statement (thx toon). Also I have to rethink blocks. Now they are just indendations without parameters. It would be cool to bootstrap as such that we don't need special syntax for classes and methods. But let's now close this parenthesis).

One UnaryNumber
new
UnaryNumber new
list add
0
BinaryNumber new
1
BinaryNumber new + one

0 = UnaryNumber new
1 = One new

BinaryNumber UnaryNumber
print
result = "0"
iterate
space = ""
result [ result count ] = "0" ?
result [ result count ] = "1"
else
result += "0"
realResult = ""
space = ""
result iterate
realResult = space + item
space = " "
0
* 1 + 1
1
* 1 + 1 + 1


Now we can redefine 0 and 1:

1 = BinaryNumber new  + 1
0 = BinaryNumber new


And finally we can do arithmetics with binary numbers:

1 0 1 0 1 0 +  1 0 1 1


Similarly to the above procedure we can implement decimal numbers. I won't do that here, because I'm lazy.

As I got from the comments from the last post, some people think, parentheses are so great (yeah, I mean you). We can add working parenthesis to our language by just defining them in the mother of all classes, Object:

Object
( expr )
expr


We have to introduce new syntax, naminly prefixes for methods. Notice the delay after the (. It designates a prefix. The next argument (here expr) is always self! So in this statement we just return self. With this definition we can write:

( ( 1 0 0 1 +  1 1 1 ) *  1 0 )


Now how do we model strings? We could do the same thing like with numbers, just defining characters as global variables and being able to concatenate them (for instance 'a' 'b' would be the messaga 'b' sent to the variable 'a', obviously representing the character a). But I don't see a purely object oriented way of representing characters themselves - at most as numbers (?).

Next time, we will bootstrap the system, or something. You know that crazy stuff with the meta thing! And the fireworks.

That's all, have a good N 1 0 0 0.

PS: Performance? What?

7 Kommentare:

debern hat gesagt…

Just an afterthought:

+ number
metaAdd 0 add
* number
metaAdd 1 number +
^ number
metaAdd 1 number *
^^ number
metaAdd 1 number ^

metaAdd init number operation
number iterate
init = init operation self

Toon Verwaest hat gesagt…

While there are some cool things in this text; half of the code is totally unreadable if you don't explain how the iterate stuff works (at least to me).

The addition of parentheses in the language itself is cool; but with 2 problems:

* you always have to add spaces between parentheses! can't you get rid of that somehow?
* Prefix methods are cool; but I wonder how the system will ever figure out if it's a prefix method or not? If there is no default way of interpreting the first "identifier" as identifier or prefix method; you get ambiguities and make it very slow since both paths have to be followed. What if I now decide to make an identifier like "( = 10"? Maybe that's even a better way of introducing parentheses:

( Object
doesNotUnderstand something )
something

In the examples, for example the Print of UnaryNumber (wth is a unary number anyway??) it's quite not understandable what "result" is
You should really write a compiler/interpreter for your language. It shouldn't be too hard ...

But cool you keep on keeping us up to date ;)

Greetings from België

Unknown hat gesagt…

Yeah, I think I'll have to do a small hacky interpreter, to try it out. It will not have first class instvars or the like, though :).

Unary number is 1111 = 4, 11 = 2. Just base 1.

For the parentheses. Yeah, I thought of defining the parentheses as ( = aParentheseObject. But then you don't have a message send, since the next thing that follows is already the argument :(
We'll see with the interpreter, how it'll work out :)

Toon Verwaest hat gesagt…

...which is obviously why I used doesNotUnderstand

debern hat gesagt…

Yeah it ate away the indent, so I even thought it was scheme :D.

This would work, although you can't name your variables like method names of "Object" though! But otherwise yeah.

Toon Verwaest hat gesagt…

Now I finally get your unary numbers. This is totally broken. You can't mutate numbers! If you write:

a = 5
a * 3

this will have changed a to now be 15. If I understand your text correctly at least ...

debern hat gesagt…

Well then I'll just copy the number into a local before multiplying it. And then return the multiplied local.