|
Otherwise known as snake case.
|
|
|
|
|
Wonderful. What a perfect name!
|
|
|
|
|
Because it comes back to bite you...
I am so old that I remember when we made printouts of our source code. Several of the printers I used placed the underscore so low down - I guess that it shouldn't interfere with the descenders of lower case letters - that it visually certainly did not tie together the parts making up the identifier.
We even had zebra paper in my first years as a programmer, ane when the underscores from the white lines printed halfway into the top of the grey line, they were very easy to overlook, especially in identifiers starting or ending with an underscore.
So I came to hate underscores.
|
|
|
|
|
And for 2021 and you going back to "6 alphanumeric characters, must not start with a digit"?
"I have no idea what I did, but I'm taking full credit for it." - ThisOldTony
AntiTwitter: @DalekDave is now a follower!
|
|
|
|
|
Will give it a try
|
|
|
|
|
OriginalGriff wrote: And for 2021 and you going back to "6 alphanumeric characters, must not start with a digit"?
and must be uppercase with first letters in the range I to N being integers; A to H and O to Z being reals unless declared otherwise. Welcome to FORTRAN IV (aka FORTRAN 66).
Then in 2022 you can progress to only 52 identifiers: A to Z for numbers and A$ to Z$ for strings. I expect a lot of CPers will remember those.
|
|
|
|
|
Ah ... implicit typing. One of the delights of FORTRAN. Along with COMMON which allowed you to declare a single character variable and use it as a three dimensional array of integers. Handy for OS mods on GEC 4070's as I recall.
"I have no idea what I did, but I'm taking full credit for it." - ThisOldTony
AntiTwitter: @DalekDave is now a follower!
|
|
|
|
|
"GOD is real unless declared in an IMPLICIT or explicit declaration"
|
|
|
|
|
I think it's just a sign of how repetitive our jobs can be. We find joy from even the slightest change of practice just because it's something different.
I always look forward to having to use a constant, because then I get to use something other than camel for the naming
|
|
|
|
|
Yep, kinda.
|
|
|
|
|
And there I was going to congratulate you on your New Year's resolution to give up smoking.
I wanna be a eunuchs developer! Pass me a bread knife!
|
|
|
|
|
An extra keystroke... THE HORROR!
|
|
|
|
|
Nand32 wrote: I've found new love for all small case separated by underscores
Ewwwww!
|
|
|
|
|
Typing in underscores suck.
|
|
|
|
|
Why restrict yourself to an alternate restriction?
I do what I want to do when I want to do it because I can.
Ravings en masse^ |
---|
"The difference between genius and stupidity is that genius has its limits." - Albert Einstein | "If you are searching for perfection in others, then you seek disappointment. If you seek perfection in yourself, then you will find failure." - Balboos HaGadol Mar 2010 |
|
|
|
|
|
Okay, so I don't like to use goto, but it is sometimes if not necessary, then efficient.
I'm running into a problem right now that is very similar to the problem of supporting multiple optional parameters in a stored proc.
Basically for an LL(k) parse in a recursive descent parser, for every k>1 value the number of IFs grows exponentially.
if(firstSym==lparen)
{
if(secondSym==rbracket) {
} else if(secondSym==intLiteral || secondSym==floatLiteral || secondSym==identifier) {
} else if(secondSym==...) {
...
} else ...
} else if(firstSym==lbracket) {
else if(firstSym==...) {
....
} else ...
...
}
for each additional k value i need to add a thirdSym, fourthSym, and accompanying nested ifs.
Meanwhile, if I rewrite this as a state machine I can use gotos, and then recycle similar paths.
This is really hard to show you an example of because the result is spaghetti but it's easy to generate programmatically, or to graph visually. (i don't want to break out graphviz right now though - it's late)
However, being able to recycle those paths as they converge can dramatically reduce the amount of code you need, but you have to be able to bounce between the different branches, the way an if won't.
You can do similar using goto case albeit less efficiently than a goto based baked state machine overall.
When I was growin' up, I was the smartest kid I knew. Maybe that was just because I didn't know that many kids. All I know is now I feel the opposite.
|
|
|
|
|
One of the good things about becoming an experienced developer is that you know when it's OK to use a goto, as well as when it's not.
Goto has value - but only in circumstances where performance is critical, and commenting can help overcome the maintenance / readability / spaghettification issues they can easily bring.
Having said that, I've never needed one in C#, and the last time I used one was in assembler code ... (which is even more of a performance improvement and maintenance / readability / spaghettification issue that stuffing a goto into C# code would be).
"I have no idea what I did, but I'm taking full credit for it." - ThisOldTony
AntiTwitter: @DalekDave is now a follower!
|
|
|
|
|
The situation I laid out is applicable to every imperative programming language I've used.
It's applicable to all C/C++ family and C/C++-ish syntax languages, including the java and javascript beasts. It's applicable to Pascal. To Basic. To Perl. To Bash - you actually run into the problem i outlined a fair bit in shell scripts in both unix and windows cmd depending on what you're trying to do.
Goto in these situations - that is, in situations where you need a state machine and don't have ready access to tables. Batch files are a perfect example. Stored procedures are too but only IF you don't want to touch the DB in your logic path - obv once you go to the DB you have tabular data all day long.
But also in languages where you do have it just as often constructing an array to traverse your state machine is just as messy as traversing it with gotos.
So you're back to square one.
And this is in any case where you need a deterministic finite automata or something with its fundamental properties ( a basic stackless state machine)
When I was growin' up, I was the smartest kid I knew. Maybe that was just because I didn't know that many kids. All I know is now I feel the opposite.
|
|
|
|
|
My "Programming 101" course was Fortran based, and we did use gotos because that was the only alternative. Ever since I have been working with "structured" languages of the "Pascal class" (or C class, if you like). Whenever I had felt a need to skip out, there has been a reason for it, something related to the structured flow: I am through with the loop prematurely, and should break out of it. There is nothing more to do in this function, so I return. Etc.
Admittedly, not all languages provide all the facitlites I would like. So sometimes I resort to tricks, like in C type languages when I might write a "do { ... } while (false);" so that can handle alternatives in order: "if (so-and-so) { ...; break; }" This is an old habit from the CHILL programming language where you could give any statement a label (which denoted that block, not a location in the code), allowing you to EXIT out of any labeled statement, whether a function, a loop, an if statement or whatever.
I never had to make a jump for completely unspecified reasons! So I never used a completely unspecified goto. If the language does not directly provide what I want, I do thricks like that "do while (false)". It is not bad: The indentation indicates what I am breaking out of, and usually the break occurs in another indented statement, making it stand out (or in). I much prefer that to an arbitrary goto.
|
|
|
|
|
implement the canonical reduced DFA to match C# keywords without using gotos or a table driven approach. There are about 520 states, IIRC.
You'd be writing code until you were dead.
When I was growin' up, I was the smartest kid I knew. Maybe that was just because I didn't know that many kids. All I know is now I feel the opposite.
|
|
|
|
|
Now I have come to accept 520 states to be "within reason" - but of course it is large.
If you were familiar wiht X.225, with its mere 32 states, you would know that without the supplementary state variables and predicate mechanism, but each cases modeled as a separate state, there would have been hundreds of states - maybe exceeding 520. The state variables is a way to reduce the size of the FSM. By proper use of state variables to collapse "n" states into one, with substates representing those "n", you can make it far more managable. Obviously those "n" substates have largely the same behaviour; they are not arbitraritly chosen.
Also, events may carry data. Say, if you parse a number, you do not model 0 through 9, +, - and decimal point as thirteen different events: All digits are born equal, so you have digit event, a sign event and a decpt event. Handling of digits is different in the integer and the fractional part, so you could make that two different states - or you coud make a decpt event set a state variable indicating 'fraction part', that steers the handling of the subsequent digits. And you would have a prediacate on this fraction part variable: If it is set, another decpt or sign is a protocol/syntax error.
Starting out with 520 initial states before you start cleaning up and grouping them into "significant" states, and grouping those events that are treated equally in the FSM as single events carrying data, sounds like a task that can be managed with reasonable effort. The size in itself is not a reason for rejecting an FSM approach.
In the X.225 standard, the presentation of the FSM is split over several state tables, each with a subset of the states and events, so they look like quite small tables. But they are just subsets of that rectangle of the total state table covering only those states (columns) that define handling of some events (rows): If an event occurs in any other state, it is illegal, square empty. E.g. those events related to connection establishment and those states related to connection establishment are shown as subtable. I have included this into my framework editor: You may define any number of sets of events and states, and display only those rows and columns that cover the area you are currently working on. You can have a "blob-and-arrow" plot of this subset. When you are done with, say, the connection part of the protocol, and go on to another subset: In the B&A plot, the connect phase states may be appear as a single "super-state" where the intermediate states in that stage are hidden inside a single blob.
I would be writing far less code than in any other approach - once the table is in place. FSM is NOT for that super-"agile" approach where you start with typing into your code editor "int main(int argc, char** argv) {" before you turn to the customer: "Now we are going - please describe your problem to me!" An FSM approach certainly requires a significant problem analysis, and even solution design, before you can start building your transition table. (In that sense, it is not a "modern" method...)
With an FSM, I would be relieved of writing tons of flow control. With a generator, I would be relieved of writing tons of function headings etc. I would be focusing on the true actions only, not how to get to them. Porting to another language would require a fraction of the work, compared to porting the full code body. I am using this approach because it saves me a whole lot of code writing!
|
|
|
|
|
A) just so we're talking about the same thing: an FSM is finite state automata. It does not use a stack. If it does, it's no longer an FSM
B) a PDA is a state machine that drives a stack. Parsers require a PDA.
Fundamentally, mathematically, A and B behave very differently, and the principles you are outlining here aren't really addressing a PDA.
C) and finally, none of what you wrote addresses the need to eliminate gotos from the final state machine. You cannot jump from both state 2 to state 2 *and* from state 2 to state 5 using only while loops. It's not possible because of how a while loop works. It's simple. Because of this, you cannot recycle paths. Every branch potentially leads to more branches, not less.
When I was growin' up, I was the smartest kid I knew. Maybe that was just because I didn't know that many kids. All I know is now I feel the opposite.
|
|
|
|
|
I know for sure that I am not going to convince you about anythning...
The way OSI protocols, and my framework, use FSM implmentations is a pragmatic approach to make safe and managable code. They are useful adaptations of the mathematical, theoretical finite state automata idea.
If it breaks with your theory, stick to your nested else if sequences. I just do not see any advantage of that approach, compared to a table driven one. And that goes for a lot of aspects. You don't "need" switch statements either - in fact you do not need else clauses. But they are helpful. As are FSM, as a flow control construct. But if you don't want to use it, don't use it!
|
|
|
|
|
You wouldn't see it there. You'd see it in its ability to interoperate with other parsers, delegating parts of the parse to them and with the ability in Parsley to allow one to take over this entire procedure and parse themselves in code <--- this is where the table approach falls down. You cannot expect a human being to manually work with a compiled FSM table!
I should add, I've written several table driven parser generators. This one isn't. I can do things with it I can't with the others, like the above.
When I was growin' up, I was the smartest kid I knew. Maybe that was just because I didn't know that many kids. All I know is now I feel the opposite.
|
|
|
|
|
Very difficult not to use them in assembler - lots of implicit ones as well
"We can't stop here - this is bat country" - Hunter S Thompson - RIP
|
|
|
|
|