Getting back to the subject of Spin 2, I think I do agree that one of the things that would be most useful on the new platform would be a standard way to call objects written in different languages. It'd be really nice if C, Spin, PASM, and Forth could all interoperate.
Given that PASM is the base that everything else is built on, I'd suggest defining the interface there first and providing ways for Spin2 bytecode to call out to PASM/hubexec functions and vice-versa.
A standard message passing protocol might help here, and would certainly be useful for inter-COG communication.
I think hubexec is the mechanism that could be used for this "messaging/invoking/whatever" between cogs and languages.
Since any cog can call the same shared hubexec code, all we need to do is define a protocol/API and place come known PASM code at a know location in hub memory. Then just have the Spin interpreter know how to use it and provide some calls to expose it.
The details need to be ironed out, and it probably needs to be a fixed number of available message passing "slots" due to memory concerns. In any case, I can see this allowing things like sharing of drivers and cross language invoking.
However, it doesn't solve the issue of JasonDorie's vector object. We need a way to allow one object to access the data/vars of another object given an object instance thing (pointer/data struct). Maybe we just need data structs and the ability to get the pointer to one and reference it's members via the pointer.
I think hubexec is the mechanism that could be used for this "messaging/invoking/whatever" between cogs and languages.
Since any cog can call the same shared hubexec code, all we need to do is define a protocol/API and place come known PASM code at a know location in hub memory. Then just have the Spin interpreter know how to use it and provide some calls to expose it.
The details need to be ironed out, and it probably needs to be a fixed number of available message passing "slots" due to memory concerns. In any case, I can see this allowing things like sharing of drivers and cross language invoking.
However, it doesn't solve the issue of JasonDorie's vector object. We need a way to allow one object to access the data/vars of another object given an object instance thing (pointer/data struct). Maybe we just need data structs and the ability to get the pointer to one and reference it's members via the pointer.
Won't adding structs to Spin force you to also add typed parameters to methods and typed variables? It seems like that will go a long way toward moving it to C. I guess you could use a similar scheme to how pointers currently work.
x := long[p]
This essentially typecasts p to a pointer to a long and dereferences it. How would that extend to a struct?
At what point do these changes make Spin something else? We've already had many conversations about whether P2 is a Propeller or something else. Can anyone (preferably Chip) define what makes Spin unique in such a way that it could be used as a litmus test for proposed new features? Then, if a proposed feature doesn't fit the definition, leave it out. Or add it in and call it something other than Spin.
That's actually a good point.
Calling it 'Spin' is going to signal it can compile Spin files, and it seems clear that P1 code is not going to be trivial to port. Not a good way to manage expectations.
Since Spin2 is never going to swallow Spin1 code, it may be smarter to look around at existing work, and select a language that Spin2 can be a sensible subset/superset of, and use a new name ?
At what point do these changes make Spin something else? We've already had many conversations about whether P2 is a Propeller or something else. Can anyone (preferably Chip) define what makes Spin unique in such a way that it could be used as a litmus test for proposed new features? Then, if a proposed feature doesn't fit the definition, leave it out. Or add it in and call it something other than Spin.
That's actually a good point.
Calling it 'Spin' is going to signal it can compile Spin files, and it seems clear that P1 code is not going to be trivial to port. Not a good way to manage expectations.
Since Spin2 is never going to swallow Spin1 code, it may be smarter to look around at existing work, and select a language that Spin2 can be a sensible subset/superset of, and use a new name ?
Maybe just make Spin2 pretty much the same as Spin and let anyone who needs more move to C or C++? Why reinvent those languages? We could even add Propeller-specific primitives to C if necessary.
At what point do these changes make Spin something else? We've already had many conversations about whether P2 is a Propeller or something else. Can anyone (preferably Chip) define what makes Spin unique in such a way that it could be used as a litmus test for proposed new features? Then, if a proposed feature doesn't fit the definition, leave it out. Or add it in and call it something other than Spin.
That's actually a good point.
Calling it 'Spin' is going to signal it can compile Spin files, and it seems clear that P1 code is not going to be trivial to port. Not a good way to manage expectations.
Since Spin2 is never going to swallow Spin1 code, it may be smarter to look around at existing work, and select a language that Spin2 can be a sensible subset/superset of, and use a new name ?
Anyway, I would suggest that what makes Spin Spin is its tight integration of a high level language and assembly language.
PropGCC does a pretty good job of integrating assembly...
I hope with P2 there will be a better way of passing arguments to assembly.
This is very complicated with P1.
Probably a turn off as it's the first part of assembly code and hard to understand...
I hope with P2 there will be a better way of passing arguments to assembly.
This is very complicated with P1.
Probably a turn off as it's the first part of assembly code and hard to understand...
Maybe just make Spin2 pretty much the same as Spin and let anyone who needs more move to C or C++?
Seems an immediate conflict.
If P2 improves ASM passing, even that aspect is no longer Spin1....
Yet, if you leave it as-is, you noble Spin2 with a decades-old constraint.
Maybe the language needs 2 forks, and a compiler switch (like FPC does)
However, even the aspiration "just make Spin2 pretty much the same as Spin" is going to have a poor value for "pretty much", given the massive difference lists.
I hope with P2 there will be a better way of passing arguments to assembly.
This is very complicated with P1.
Probably a turn off as it's the first part of assembly code and hard to understand...
Maybe just make Spin2 pretty much the same as Spin and let anyone who needs more move to C or C++?
Seems an immediate conflict.
If P2 improves ASM passing, even that aspect is no longer Spin1....
Yet, if you leave it as-is, you noble Spin2 with a decades-old constraint.
Maybe the language needs 2 forks, and a compiler switch (like FPC does)
However, even the aspiration "just make Spin2 pretty much the same as Spin" is going to have a poor value for "pretty much", given the massive difference lists.
I don't agree. There is nothing that says P1 Spin can't get the new argument passing as well as long as its backward compatible to the existing Spin. They don't have to diverge.
I don't agree. There is nothing that says P1 Spin can't get the new argument passing as well as long as its backward compatible to the existing Spin. They don't have to diverge.
Haven't you just invented a second Spin1 there, which is going to get even more confusing ?
Or do you envision this as a PC-side change only, so ROM-Spin does not change ? Is that possible ?
I don't agree. There is nothing that says P1 Spin can't get the new argument passing as well as long as its backward compatible to the existing Spin. They don't have to diverge.
Haven't you just invented a second Spin1 there, which is going to get even more confusing ?
Or do you envision this as a PC-side change only, so ROM-Spin does not change ? Is that possible ?
Yes, a PC-side change only. No change the the ROM-based interpreter.
jmg,
The only thing in ROM on the P1 is the interpreter for Spin bytecode. As long as we can compile down to that bytecode, then we can "back port" features to the P1 Spin. For example, the ternary operator.
Phil,
As has been said, it's gross syntax. Also, your example for the vector object doesn't work that simply, because you need to have accessors for each element.
Perhaps we just need a mechanism like # for constants that allows access to VARs?
Phil, that requires intimate knowledge of the objects VARs and the compilers potential rearranging of those VARs in memory. Longs, words, bytes, are segregated...
Phil, that requires intimate knowledge of the objects VARs and the compilers potential rearranging of those VARs in memory.
No so, if the elements of a vector or matrix are in an array, which they would be. (For example, you don't need a separate accessor for each character in a string, right?)
Phil, that requires intimate knowledge of the objects VARs and the compilers potential rearranging of those VARs in memory. Longs, words, bytes, are segregated...
Why couldn't that be provided by the compiler? Since everything is compiled as a single unit, the order and offsets of each VAR should be pretty easy to make available.
I think hubexec is the mechanism that could be used for this "messaging/invoking/whatever" between cogs and languages.
Since any cog can call the same shared hubexec code, all we need to do is define a protocol/API and place come known PASM code at a know location in hub memory. Then just have the Spin interpreter know how to use it and provide some calls to expose it.
The details need to be ironed out, and it probably needs to be a fixed number of available message passing "slots" due to memory concerns. In any case, I can see this allowing things like sharing of drivers and cross language invoking.
However, it doesn't solve the issue of JasonDorie's vector object. We need a way to allow one object to access the data/vars of another object given an object instance thing (pointer/data struct). Maybe we just need data structs and the ability to get the pointer to one and reference it's members via the pointer.
Won't adding structs to Spin force you to also add typed parameters to methods and typed variables? It seems like that will go a long way toward moving it to C. I guess you could use a similar scheme to how pointers currently work.
x := long[p]
This essentially typecasts p to a pointer to a long and dereferences it. How would that extend to a struct?
x := struct(Vector)[p].x
Maybe something like that?
type inference is a thing you know :P spin has pretty simple types (machine word, reference, etc...) these are "monomorphic" (at the risk of being too academic) so each value should have unique syntax to uniquely determine the type of the variable used. if a variable has multiple types over time simply perform a "union" of those types, no need to tag that union either as there is no union type to represent this notion.
I think hubexec is the mechanism that could be used for this "messaging/invoking/whatever" between cogs and languages.
Since any cog can call the same shared hubexec code, all we need to do is define a protocol/API and place come known PASM code at a know location in hub memory. Then just have the Spin interpreter know how to use it and provide some calls to expose it.
The details need to be ironed out, and it probably needs to be a fixed number of available message passing "slots" due to memory concerns. In any case, I can see this allowing things like sharing of drivers and cross language invoking.
However, it doesn't solve the issue of JasonDorie's vector object. We need a way to allow one object to access the data/vars of another object given an object instance thing (pointer/data struct). Maybe we just need data structs and the ability to get the pointer to one and reference it's members via the pointer.
Won't adding structs to Spin force you to also add typed parameters to methods and typed variables? It seems like that will go a long way toward moving it to C. I guess you could use a similar scheme to how pointers currently work.
x := long[p]
This essentially typecasts p to a pointer to a long and dereferences it. How would that extend to a struct?
x := struct(Vector)[p].x
Maybe something like that?
type inference is a thing you know :P spin has pretty simple types (machine word, reference, etc...) these are "monomorphic" (at the risk of being too academic) so each value should have unique syntax to uniquely determine the type of the variable used. if a variable has multiple types over time simply perform a "union" of those types, no need to tag that union either as there is no union type to represent this notion.
I'm not sure I follow what you mean but the syntax I gave for longs is existing Spin syntax. My suggestion for structs was intended to be similar. I don't know how you would use type inference to handle an expression like "x.foo". The presence of the "." would certainly allow you to infer that it was a structure reference but you wouldn't be able to determine what type of structure if more than one structure had a "foo" field. Another option to what I suggested is this:
x := Point[p].x
This looks a lot more like "long[p]" so it might be a better choice.
Edit: Changed the example to Point rather than Vector because an "x" field doesn't make much sense with a vector. Oops.
That's true, and that's what the question was about: vector math, in the context of what's possible now with Spin1.
In the more general case with Spin2, we've already discussed methods that return lists, rather than scalars, which I think -- and Chip seems to think -- is a good thing.
To be Spin like, imho, a struct would be a block type (like VAR, DAT, etc.) with a name. An instance of it would just use the struct name and give it a var name.
Usage would be with the var name dot member name (e.g. myStruct.aMember). You would be able to take the address of it as will other things.
The pointer could be un-typed, and usage of the pointer would use the struct name with the syntax like with long/word/byte (e.g. StructName[pointervar].member).
To be Spin like, imho, a struct would be a block type (like VAR, DAT, etc.) with a name. An instance of it would just use the struct name and give it a var name.
Usage would be with the var name dot member name (e.g. myStruct.aMember). You would be able to take the address of it as will other things.
The pointer could be un-typed, and usage of the pointer would use the struct name with the syntax like with long/word/byte (e.g. StructName[pointervar].member).
That's what I suggested a few messages ago. I guess it's rather obvious. I mean the pointer reference part. In any case, I agree.
To be Spin like, imho, a struct would be a block type (like VAR, DAT, etc.) with a name. An instance of it would just use the struct name and give it a var name.
Usage would be with the var name dot member name (e.g. myStruct.aMember). You would be able to take the address of it as will other things.
The pointer could be un-typed, and usage of the pointer would use the struct name with the syntax like with long/word/byte (e.g. StructName[pointervar].member).
One good thing about Prop2 is that bytes, words, and longs can sit in hub memory at any offsets, unlike in Prop1. This means there's no more need to segregate groups of longs, words, and bytes in VAR memory. That was done in Spin1 to avoid interstitial gaps between differently-sized variables.
So, structures are not only welcome, but more practical than before.
I'm not entirely understanding the object limitations of Spin1, like Jason Dorie was talking about. Could someone explain what's needed, relative to what Spin1 already has? I want to understand this.
Comments
Given that PASM is the base that everything else is built on, I'd suggest defining the interface there first and providing ways for Spin2 bytecode to call out to PASM/hubexec functions and vice-versa.
A standard message passing protocol might help here, and would certainly be useful for inter-COG communication.
Eric
That's not the plan.
SPIN will be lean, not incorporate all the hardware features, and in-line as well as PASM procedures and or PASM COGS will do the rest.
Since any cog can call the same shared hubexec code, all we need to do is define a protocol/API and place come known PASM code at a know location in hub memory. Then just have the Spin interpreter know how to use it and provide some calls to expose it.
The details need to be ironed out, and it probably needs to be a fixed number of available message passing "slots" due to memory concerns. In any case, I can see this allowing things like sharing of drivers and cross language invoking.
However, it doesn't solve the issue of JasonDorie's vector object. We need a way to allow one object to access the data/vars of another object given an object instance thing (pointer/data struct). Maybe we just need data structs and the ability to get the pointer to one and reference it's members via the pointer.
Calling it 'Spin' is going to signal it can compile Spin files, and it seems clear that P1 code is not going to be trivial to port.
Not a good way to manage expectations.
Since Spin2 is never going to swallow Spin1 code, it may be smarter to look around at existing work, and select a language that Spin2 can be a sensible subset/superset of, and use a new name ?
I hope with P2 there will be a better way of passing arguments to assembly.
This is very complicated with P1.
Probably a turn off as it's the first part of assembly code and hard to understand...
Seems an immediate conflict.
If P2 improves ASM passing, even that aspect is no longer Spin1....
Yet, if you leave it as-is, you noble Spin2 with a decades-old constraint.
Maybe the language needs 2 forks, and a compiler switch (like FPC does)
However, even the aspiration "just make Spin2 pretty much the same as Spin" is going to have a poor value for "pretty much", given the massive difference lists.
Haven't you just invented a second Spin1 there, which is going to get even more confusing ?
Or do you envision this as a PC-side change only, so ROM-Spin does not change ? Is that possible ?
-Phil
The only thing in ROM on the P1 is the interpreter for Spin bytecode. As long as we can compile down to that bytecode, then we can "back port" features to the P1 Spin. For example, the ternary operator.
Phil,
As has been said, it's gross syntax. Also, your example for the vector object doesn't work that simply, because you need to have accessors for each element.
Perhaps we just need a mechanism like # for constants that allows access to VARs?
-Phil
-Phil
type inference is a thing you know :P spin has pretty simple types (machine word, reference, etc...) these are "monomorphic" (at the risk of being too academic) so each value should have unique syntax to uniquely determine the type of the variable used. if a variable has multiple types over time simply perform a "union" of those types, no need to tag that union either as there is no union type to represent this notion.
Edit: Changed the example to Point rather than Vector because an "x" field doesn't make much sense with a vector. Oops.
you are solving a single specific case, and not the more general case, which a language should.
That's true, and that's what the question was about: vector math, in the context of what's possible now with Spin1.
In the more general case with Spin2, we've already discussed methods that return lists, rather than scalars, which I think -- and Chip seems to think -- is a good thing.
-Phil
It makes stuff that would be a complete mess without them, very clean and simple with them.
Structures, and pointers to structures solve a lot of problems very cleanly.
Usage would be with the var name dot member name (e.g. myStruct.aMember). You would be able to take the address of it as will other things.
The pointer could be un-typed, and usage of the pointer would use the struct name with the syntax like with long/word/byte (e.g. StructName[pointervar].member).
One good thing about Prop2 is that bytes, words, and longs can sit in hub memory at any offsets, unlike in Prop1. This means there's no more need to segregate groups of longs, words, and bytes in VAR memory. That was done in Spin1 to avoid interstitial gaps between differently-sized variables.
So, structures are not only welcome, but more practical than before.
I think it all works out fine even passing by value (just make a local instance). Heck, I think it could even compile down to Spin1 bytecode.
I'm not sure I do either. That's how the whole accessor method thing got started. Hopefully Jason can elaborate.
-Phil