Spin2
David Betz
Posts: 14,516
@cgracy Do you have a language definition for Spin2? I realize that you haven't finished it yet but I believe you said in your video that it was nearly complete so I'm assuming that the language design itself is mostly frozen. What I'm wondering is if you have provided a way to pass a reference to an object as a parameter to a method. That was the biggest gap in the original Spin as far as I'm concerned and I'm wondering if you've addressed that in Spin2.
Comments
We have function pointers, anyway, and you can make a pointer from any method. It takes two longs. Once it's set up, you can pass its address around and any method can use it. You'd just better be sure your numbers of parameters and return values are in agreement.
sure one has to take care of parameters/returns, but this sounds extremely nice.
I poked you a little bit at the webinar with cooperating and looking at @ersmith extensions. I do understand your point of view that you need to build/think thru your own vision.
Actually I poked you to get Spin2 at least out to test it. It will not be nailed in stone anyways, there will be tons of versions of the interpreter, because you have to include the interpreter into your binary anyways.
One of the Dave's and David's which I always mix up had the brilliant Idea that a smart compiler could - theoretically - just include the used bytecodes and code to save COG mem for user defined functions.
Anyways, being able to call HUBexec PASM code is one step, how about the other way around?
Do you have any idea how to 'callback' from PASM to SPIN? Can I call a function Pointer from PASM back to SPIN, assuming I am running code in/with the interpreter COG?
curious,
Mike
It would be a lot simpler to make your main context Spin, then call to PASM code which returns values which Spin makes decisions from.
To make a method pointer:
MPTR[address_of_pointer_to_assign] := {object_name{[index]}.}method_name{[index]}
To use a method pointer:
~~method_pointer{:number_of_return_values_if_not_zero}{[index]}{(parameter1{,parameter2...})}
The method pointer stores the entire context (including pbase, vbase, and method index).
I remember all the talk about blank objects, but if I'm thinking correctly, this simple mechanism will cover for everything. Do you see a shortcoming? One thing I see is that this is very generic and the compiler doesn't know or care about numbers of parameters or their names. It's all a run-time issue.
As to expect Eric does it the formalized(?) way, type checking and such, and Chip does give a whatever about conventions, and it might be good so.
The freedom to shoot yourself in the foot if your types/parameters don't match allows also to USE this side effect for interesting things.
Spin2 will be very interesting.
Mike
I find eric's example very easy to read, understand and use. It hides the object structure details.
chip's proposal assumes you know precisely what you're doing and understand the object structure details. More complicated in my eyes
Here is an idea. Maybe Parallax should contract with Eric to implement a byte code backend for his FastSpin suite of languages. The actual definition of the byte codes could be done by Chip and Eric together and the implementation of the byte code interpreter could be done by Chip. The result would be a cross platform implementation of Spin, BASIC, and C for both the P1 and the P2 that can support either native code generation for speed or byte code generation for space efficiency. Since the front end of Spin, BASIC, and C are already done and working this should be a fairly quick process. The alternative is to end up with a Spin2 that is actually less capable than FastSpin and only runs under Windows.
In OOP if you want to call a method on an object that object has to come from some class. A type. The caller has to have a pointer or reference to that type. The caller cannot be written before it has a definition of the type it is calling the method on. (Give or take some further messing with inheritance and so on)
Of course as you have noticed none of the particular formality is needed: I believe that is right.
In my current favorite language, Rust, there are no classes, no inheritance etc. Rather it is built around 'traits'.
With traits one can define methods that can be used by some other objects, which may not even be written yet.
For example: One can write a trait without knowing anything about any objects like so: The someone else can create an object: All of which sounds more like what you are thinking about.
You could get a pointer to a base method and then [index] the particular method.
I'm just not remembering why you'd need to know everything exactly beforehand. That's like making everything NOT flexible.
I don't know where I'm going, exactly, but I do know how to find my way there. It's too early to collaborate, yet.
Thing is in the procedural C world we have structs and functions and you end up writing:
a = area(&someCircle);
(Assuming you need more than one circle you need to specify which one with that parameter.
In the C++ world we end up writing:
a = someCircle.area();
Which is perhaps syntactically nicer. The messy instance pointer is hidden. Here C++ knows which circle we mean because someCircle is an instance of class Circle.
With Rust traits you end up being able to write the same. But you can also write:
a = area(&someCircle)
The OOP style syntax is just syntactic sugar.
I'm not sure how this all applies to Spin. If I recall correctly Spin objects were not classes. One could only have one instance of an object. Do I recall correctly or has that changed for Spin 2?
Okay. This is ringing a bell. I think that's why we hashed out the phantom object declarations a while back. It would allow us to reuse VAR space for objects whose code is present, but they are not given VAR space, yet.
Yes, but if the point is to make things interchangeable, you would have the same types of routines at each unique index for many different objects.
This is how I feel about it too. Other aspects of Spin are loose, Chip calls it "Wild Programming." Seems these ideas are in line with that overall feel.
There is nothing here that cannot be undone or changed. ---except for that which is not yet done.
I saw someone put fresh ordinary drip coffee grounds onto vanilla ice cream. I know, right? My response too. WTH?
But, then I had a scoop. Guys, coffee is the pepper of ice cream. It's insane good. Aromatics, the texture of the coffee bits, creamy vanilla... You should try it. I love it personally.
Who knew?
Let's see the chef prepare the dish. Then we can talk about the taste of the food.
Nobody can know at this point. Wrong isn't even in the discussion yet.
Also, there are different perspectives in play here. Chip is thinking in terms of something that will compile on P2, rapidly. And that in some potential environment that works very differently from the usual build chain on a PC.
That's a very different take on things. Understanding what it's gonna mean pretty much means seeing an expression of it.
I'm pretty sure that overall idea governs things like boiling this down to the nubs, as was just done. Needs to be simple, fast, flexible.
The fastspin Spin dialect does have both, but while the object pointers are documented (as you've seen) method pointers are not. The syntax for method pointers in fastspin seems to be different from what Chip chose, so probably it isn't worth documenting until Chip's final Spin2 specification is released.
For BASIC and C both function and object pointers work pretty much the way you would expect. "@obj.method" (or "&obj.method" in C) creates what's essentially a closure which will call the given method for the given (particular) object. Under the hood this is represented as a single 32 bit pointer to a pair of longs, one of which is a pointer to the object's data and one of which is a pointer to the function itself.