Strangely enough Larry Wall, the crazy lunatic inventor of Perl, was a winner in the IOCCC at some point. His entry was a single line of C that took me half a day to figure out. It basically printed out "This is Unix" or something almost like that but it was hard to tell that it might do that. Wish I could find a link to that code now.
Phil,
I don't know about obfuscated ASCII programming art,
As you probably know, the obfuscated C contest is not about ASCII art but just being as obtuse as possible. For example, one of Larry's other entries: http://www.ioccc.org/1987/wall.c
PropGCC offers a better alternative to SPIN. PropGCC still needs more stuff to be built up around it. But, when that happens, I won't see a reason why to use SPIN anymore.
I really hope Chip sticks up for his language Spin. It looks like I will have to go back to using C for the PropellerII. What a shame.
Chip has his upgraded version of his compiler that implements all of the PASM2 stuff. I will be integrating/porting that into "my" compiler after the validation tool is done. I believe the plan is to use "my" compiler as the official one going forward (after the validation process). Chip, Jeff, and I have talked some about this process. Just to be extra clear, it's not all final yet, so things may change.
I put the "my" in quotes up there, because it's really not my compiler so much as it is Parallax's compiler that I ported and others helped with getting it to where it is now. I think calling it the Open Source Spin Compiler or something like that is better.
I really hope Chip sticks up for his language Spin. It looks like I will have to go back to using C for the PropellerII. What a shame.
Do not fret, ratronic, there will be Spin on the Prop 2. Chip wants it, Jeff wants it, I want it, and we are the ones doing it. Parallax plans to have both Spin (2) and propgcc for the Prop 2. It's not one or the other, it's both!
With all due respect to you guys, who I admire as the great software engineers you all are, I really like how Chip realized SPIN. I went to fetch some old conversations only to remember the old forum server is down now. In those Chip explained the ideology behind SPIN:
Lean input. Every character or omission of it adds value. Line noise type stuff is OK, so long as it is really useful.
Lean structure. Things can get done in simple consistent ways. Structures are nice, but so is a simple block of RAM.
Reuse. Spin is meant to get lobbed together so people can quickly grab things and get to their task without reinventing the wheel.
Easy. In general this doesn't mean simple, just lean in terms of the number of things one needs to know about to write programs.
Honestly,I would love to get the list of things we all say we need and see how Chip would do them. To me, that is Spin. Sorry. I mean well, but I see a relative mess brewing.
At the least I would prefer to see at least one guiding pass at the language done that way.
SPIN is the most productive and fun programming I have done. I want that to carry forward, if that helps to convey my intent. It seems to me C and C++ have a place here and that place does not completely overlap with SPIN.
I have found it takes years of spin programming to find its limitations. I see strings and floating point have been mentioned, but I think the problem is more to do with the structure of objects - which is exactly the sort of thing that can be improved.
Take strings. You get a string object from the obex and put it in your program and call it from the main program. That works fine. But let's say you have a main routine, and a sub object and a sub object of that and within that sub-sub object you want to do some string manipulation. You can create another copy of the string object but that takes memory. Or you can pass a request up the chain of command to the main object, then down into the string object, then pass an answer back to the calling routine. It gets complicated.
A simplistic solution is to add strings to spin. But I wonder if a more generic solution is to rewrite the spin pre-processor so all objects have access to all other objects? That way, you could add a string object, and a float object, rather than adding strings as part of the language.
That also side-steps the issue of forking because there is no forking. Spin stays as it is. But you can effectively add all those extra features like strings and floating point using the current obex code.
So my vote is for a smarter pre-processor that can allow any object to reference any other object, regardless of whether it was declared in the main object or in a sub object.
The ultimate cool spin feature would to be able to declare a string object once, and anywhere in the program or any object you write the word "string." and as soon as you hit the "." it brings up a drop down menu of all the methods available.
Do not fret, ratronic, there will be Spin on the Prop 2. Chip wants it, Jeff wants it, I want it, and we are the ones doing it. Parallax plans to have both Spin (2) and propgcc for the Prop 2. It's not one or the other, it's both!
That is good news, Roy. If there is a Spin for the Prop 2 then there will be a Catalina as well.
I would like to see more informative error and warning messages. For example:
- When using a variable name that is present in both the method and a DAT block
- When using both spaces and tabs for indentation (not all of us have the markers!)
- All the BST warnings (the "No # on JMP" is most useful)
- Declaring variables in a DAT section without an initial value (this creates another reference for the following memory location).
I would also like to see conditional statements (#define, #ifdef, ...) and macros for substitution.
Also, what about the following:
{ {{ }} }
In most other languages, that would be considered a compile error (two extra '}' ), but in Spin (BST only?) it compiles just fine. Which shouldn't be the case, since a block comment is supposed to ignore everything between the starting and ending characters.
Spin's block comments are a little smarter than that, Cody. (( and )) are separate "operators", distinct from { and }. What you've posted is not, and should not be, an error.
Spin's block comments are a little smarter than that. (( and )) are separate "operators", distinct from { and }. What you've posted is not, and should not be, an error.
-Phil
Ok. And operators inside a comment should be ignored, except for the comment closing operator. The first {{ should be ignored, since it's in the comments and hence the }} would not match, and so the first } of the }} should be considered the closing operator.
Maybe a warning, but it should just do it anyway. That kind of thing happens to be something I like about SPIN. Not saying it's good practice. Maybe an analogy would be UNIX. One can to fantastically stupid things or powerful things...
Better, warning text could be "Warning, mixed type expression evaluates to: [value]"
A warning would do for me. It's just that for all those JavaScript and other language users "string" + "string" gives you "stringstring".
I have only ever done this once when trying out a ton of things in Spin while I was trying to write a PASM assembler that would accept Spin PASM syntax. It sort of worked but then BST came along and I had no need to continue with it any more.
And operators inside a comment should be ignored, except for the comment closing operator.
Not always. Super-comment operators take precedence over regular comments. BTW, this is not an unusual state of affairs. In many languages, the same thing happens inside double quotes, viz:
"He said, ""It's alive!"""" would evaluate to He said, "It's alive!"
When a quoted string is scanned during parsing, doubled double-quotes do not end the string, but result in a single double-quote character. Spin does not do this with quotes, though. I wish it did.
Anyway, since Spin does not have a formal grammar, the syntax rules are defined by the compiler. Until there is a formal grammar, we can't really say the compiler is in error -- as much as we like to.
OK, I'll jump in here, and respond to the initial posted question.
I would like to see a "pauseMS", "pauseSec", and "pauseMin" implemented as a part of SPIN.
Back when I was a "Very New Noobe", trying to figure out how to do a proper simple "delay" was a problem. I found the answer after many hours of reading the Forums, and if I remember correctly, the answer was found at the end of a long chain of replies.
I (we all) have written similar methods many times as:
And yes, I know it is easy to "cut-n-paste" but why NOT make a "pause" a standard part of SPIN?
Also, I would like to see a type of "SYNC" Function that would allow a "waitcnt" to wait at a future point in the program, and falling through if the requested "Sync" has expired (and maybe with returned over time).
For example:
PUB Main | Timer
SyncInit(@Timer)
repeat
<do some stuff>
SyncMin(@Timer, 2) 'Wait until the next whole sync cycle
PRI SyncInit(pTimer)
Timer := cnt
PRI SyncMin(pTimer, _min)
<code as necessary>
PRI SyncSec(pTimer, _sec)
<code as necessary>
PRI SyncMs(pTimer, _ms)
<code as necessary>
Note: The "<code as necessary" is used in the example because I do not know how to make this work properly for long (>52 seconds) syncs.
Maybe both of these ideas could be done in the pre-compiler?
I do agree that such things should be available in Spin from the get go. However they need not be part of the language as such, they can be supplied as objects ready to use. Those objects are written in the language, like your example, but not actually a built in part of the language definition like for example "if" and "repeat" are.
Jeff and I have discussed a feature for the compiler that would essentially be "built in's". When your program would just have a keyword like PausMS, and the compiler would substitute in the appropriate spin code (or possible bytecodes).
It would be similar to having a "default object" that's always available and you don't have to put "objectname." in front of it's functions. I know Parallax is interested in this especially for the education stuff, because they could supply a set of built in keywords for all the things they have on the BS2 and more. I think it would be a nice way to basically include support of I2C, SPI, etc. right in the compiler.
FYI, I'm almost done integrating ersmith's patch for the preprocessor. Just need to make a function to translate UTF-8 to PASCII. Hopefully I'll be able to submit it up to google code Monday for you guys to get and try.
Jeff and I have discussed a feature for the compiler that would essentially be "built in's". When your program would just have a keyword like PausMS, and the compiler would substitute in the appropriate spin code (or possible bytecodes).
Nice idea! Would it be possible to do this in a "virtual object", so the same methods don't get repeated across multiple objects?
Phil,
Yeah that is a consideration. It's likely going to be done as a kind of virtual object when it comes down to it. I just have to figure out the details.
Something related to this, I do still have a "dead code elimination" task on my list, and kind of coupled with that could be a more granular form of duplicate code elimination.
Phil,
Yeah that is a consideration. It's likely going to be done as a kind of virtual object when it comes down to it. I just have to figure out the details.
Something related to this, I do still have a "dead code elimination" task on my list, and kind of coupled with that could be a more granular form of duplicate code elimination.
Roy
Why not just do the same sort of thing that C does and have a "standard library"? That seems better than building this stuff directly into the compiler. All you'd have to do is have some search path for "system" objects that looks in a system directory rather than the current directory.
If you do it this way it would be easy to add more standard objects. If it is part of the compiler, you need to release a new compiler every time you want to add something.
Well it wouldn't really be part of the compiler itself, but the wrapper around the compiler. I kind of call the whole thing the compiler, but anyway...
The downside to having it be your way is then you have to do the <objname>.<func> thing.
My current idea is essentially just an object that the compiler tries to find pubs in when it has a undefined symbol. It's kind of like the "using" thing in C++ or C#
I think what they are trying to tackle is the object name space issue.
So, for example, instead of writing "serial.tx(something)" you can just write tx(something). In many languages this is handled by having something like "using serial" at the top of the module, after that "tx" will be found in the "serial" name space an used. Never did like that idea.
Any way it's all going to go to hell when it's built into the compiler and then any method in any object can just call "tx" which as you know will screw up very badly if the serial driver is a regular FullDuplexSerial with no locks on access.
So yes, I agree, standard libraries are the way to go rather than building things into the language iteself.
The C guys figured all this out this all out 40 years ago and not much has improved on it since. (Has anything ever improved on it?)
Comments
Oh my God, I looked, now I'm going to have nightmares for a week.
Us mortals will never know when you have both reached nirvana if that is an example of what happens:)
For reasons which are beyond me , I don't think they get much use.
-Phil
Why wouldn't there be a Forth interpreter written in Perl?? (there's actually a few)
-Phil
Phil,
As you probably know, the obfuscated C contest is not about ASCII art but just being as obtuse as possible. For example, one of Larry's other entries: http://www.ioccc.org/1987/wall.c
True, but if we're talking about adding a macro facility to Spin. It just sounds like a syntax nightmare.
I put the "my" in quotes up there, because it's really not my compiler so much as it is Parallax's compiler that I ported and others helped with getting it to where it is now. I think calling it the Open Source Spin Compiler or something like that is better.
Roy
Do not fret, ratronic, there will be Spin on the Prop 2. Chip wants it, Jeff wants it, I want it, and we are the ones doing it. Parallax plans to have both Spin (2) and propgcc for the Prop 2. It's not one or the other, it's both!
Lean input. Every character or omission of it adds value. Line noise type stuff is OK, so long as it is really useful.
Lean structure. Things can get done in simple consistent ways. Structures are nice, but so is a simple block of RAM.
Reuse. Spin is meant to get lobbed together so people can quickly grab things and get to their task without reinventing the wheel.
Easy. In general this doesn't mean simple, just lean in terms of the number of things one needs to know about to write programs.
Honestly,I would love to get the list of things we all say we need and see how Chip would do them. To me, that is Spin. Sorry. I mean well, but I see a relative mess brewing.
At the least I would prefer to see at least one guiding pass at the language done that way.
SPIN is the most productive and fun programming I have done. I want that to carry forward, if that helps to convey my intent. It seems to me C and C++ have a place here and that place does not completely overlap with SPIN.
'Good to hear that Spin for the P2 is well on the way! Keep up the good work -- same to Chip and Jeff!
-Phil
Take strings. You get a string object from the obex and put it in your program and call it from the main program. That works fine. But let's say you have a main routine, and a sub object and a sub object of that and within that sub-sub object you want to do some string manipulation. You can create another copy of the string object but that takes memory. Or you can pass a request up the chain of command to the main object, then down into the string object, then pass an answer back to the calling routine. It gets complicated.
A simplistic solution is to add strings to spin. But I wonder if a more generic solution is to rewrite the spin pre-processor so all objects have access to all other objects? That way, you could add a string object, and a float object, rather than adding strings as part of the language.
That also side-steps the issue of forking because there is no forking. Spin stays as it is. But you can effectively add all those extra features like strings and floating point using the current obex code.
So my vote is for a smarter pre-processor that can allow any object to reference any other object, regardless of whether it was declared in the main object or in a sub object.
The ultimate cool spin feature would to be able to declare a string object once, and anywhere in the program or any object you write the word "string." and as soon as you hit the "." it brings up a drop down menu of all the methods available.
That is good news, Roy. If there is a Spin for the Prop 2 then there will be a Catalina as well.
Ross.
- When using a variable name that is present in both the method and a DAT block
- When using both spaces and tabs for indentation (not all of us have the markers!)
- All the BST warnings (the "No # on JMP" is most useful)
- Declaring variables in a DAT section without an initial value (this creates another reference for the following memory location).
I would also like to see conditional statements (#define, #ifdef, ...) and macros for substitution.
Also, what about the following: In most other languages, that would be considered a compile error (two extra '}' ), but in Spin (BST only?) it compiles just fine. Which shouldn't be the case, since a block comment is supposed to ignore everything between the starting and ending characters.
-Phil
Ok. And operators inside a comment should be ignored, except for the comment closing operator. The first {{ should be ignored, since it's in the comments and hence the }} would not match, and so the first } of the }} should be considered the closing operator.
Quickly, what sequence of bytes does that create?
I can't help thinking that it should create an error if it's not going to do what one might immediately expect.
On the other hand this should be OK
Better, warning text could be "Warning, mixed type expression evaluates to: [value]"
I have only ever done this once when trying out a ton of things in Spin while I was trying to write a PASM assembler that would accept Spin PASM syntax. It sort of worked but then BST came along and I had no need to continue with it any more.
When a quoted string is scanned during parsing, doubled double-quotes do not end the string, but result in a single double-quote character. Spin does not do this with quotes, though. I wish it did.
Anyway, since Spin does not have a formal grammar, the syntax rules are defined by the compiler. Until there is a formal grammar, we can't really say the compiler is in error -- as much as we like to.
-Phil
I would like to see a "pauseMS", "pauseSec", and "pauseMin" implemented as a part of SPIN.
Back when I was a "Very New Noobe", trying to figure out how to do a proper simple "delay" was a problem. I found the answer after many hours of reading the Forums, and if I remember correctly, the answer was found at the end of a long chain of replies.
I (we all) have written similar methods many times as:
And yes, I know it is easy to "cut-n-paste" but why NOT make a "pause" a standard part of SPIN?
Also, I would like to see a type of "SYNC" Function that would allow a "waitcnt" to wait at a future point in the program, and falling through if the requested "Sync" has expired (and maybe with returned over time).
For example:
Note: The "<code as necessary" is used in the example because I do not know how to make this work properly for long (>52 seconds) syncs.
Maybe both of these ideas could be done in the pre-compiler?
Thanks
Eldon
I do agree that such things should be available in Spin from the get go. However they need not be part of the language as such, they can be supplied as objects ready to use. Those objects are written in the language, like your example, but not actually a built in part of the language definition like for example "if" and "repeat" are.
It would be similar to having a "default object" that's always available and you don't have to put "objectname." in front of it's functions. I know Parallax is interested in this especially for the education stuff, because they could supply a set of built in keywords for all the things they have on the BS2 and more. I think it would be a nice way to basically include support of I2C, SPI, etc. right in the compiler.
FYI, I'm almost done integrating ersmith's patch for the preprocessor. Just need to make a function to translate UTF-8 to PASCII. Hopefully I'll be able to submit it up to google code Monday for you guys to get and try.
Roy
-Phil
Yeah that is a consideration. It's likely going to be done as a kind of virtual object when it comes down to it. I just have to figure out the details.
Something related to this, I do still have a "dead code elimination" task on my list, and kind of coupled with that could be a more granular form of duplicate code elimination.
Roy
Why not just do the same sort of thing that C does and have a "standard library"? That seems better than building this stuff directly into the compiler. All you'd have to do is have some search path for "system" objects that looks in a system directory rather than the current directory.
Maybe something like:
If you do it this way it would be easy to add more standard objects. If it is part of the compiler, you need to release a new compiler every time you want to add something.
The downside to having it be your way is then you have to do the <objname>.<func> thing.
My current idea is essentially just an object that the compiler tries to find pubs in when it has a undefined symbol. It's kind of like the "using" thing in C++ or C#
Roy
So, for example, instead of writing "serial.tx(something)" you can just write tx(something). In many languages this is handled by having something like "using serial" at the top of the module, after that "tx" will be found in the "serial" name space an used. Never did like that idea.
Any way it's all going to go to hell when it's built into the compiler and then any method in any object can just call "tx" which as you know will screw up very badly if the serial driver is a regular FullDuplexSerial with no locks on access.
So yes, I agree, standard libraries are the way to go rather than building things into the language iteself.
The C guys figured all this out this all out 40 years ago and not much has improved on it since. (Has anything ever improved on it?)