|
|
Nope, can't do that. When I listen to music, it's a foreground task for me, and the more masterpiece it is, the more real time compute of my brain it needs. So no chance for Bach here. However any job that can itself be put into background, like driving or washing dishes, I have to have something for the foreground!
PS: Brandenburg Concerto is amazing
|
|
|
|
|
I wouldnβt say for speed, but for depth/focus/concentration, I tend to drumming (world drum, tribal, Native American, etc.) or trance/edm. As others have mentioned, lyrics get distracting.
I do have some classical (Bach Cello Suites, Beethoven (Walter Weller), and Paganini (Itzhak Perlman)). Will have to try some of that.
Time is the differentiation of eternity devised by man to measure the passage of human events.
- Manly P. Hall
Mark
Just another cog in the wheel
|
|
|
|
|
It depends on how intense my concentration has to be. For reasonably routine coding, I listen to my usual music playlist, which happens to include things like Switched On Bach. When it gets more intense, I'll switch to new age (e.g., Diane Arkenstone). But if it's really at the limit of what I can do, I need absolute silence.
That doesn't happen very often but it does happen.
|
|
|
|
|
Wordle 1,058 3/6
β¬π¨β¬β¬π¨
π¨π¨π¨π¨π¨
π©π©π©π©π©
|
|
|
|
|
Wordle 1,058 4/6*
β¬π¨π¨β¬π¨
β¬π¨β¬π©π©
π©π¨β¬π©π©
π©π©π©π©π©
"I have no idea what I did, but I'm taking full credit for it." - ThisOldTony
"Common sense is so rare these days, it should be classified as a super power" - Random T-shirt
AntiTwitter: @DalekDave is now a follower!
|
|
|
|
|
β¬π¨β¬β¬π¨
β¬β¬π¨π¨β¬
π©π©π©π©π©
In a closed society where everybody's guilty, the only crime is getting caught. In a world of thieves, the only final sin is stupidity. - Hunter S Thompson - RIP
|
|
|
|
|
Wordle 1,058 4/6
β¬β¬🟨β¬β¬
β¬🟨β¬β¬β¬
🟩🟨β¬🟩🟩
🟩🟩🟩🟩🟩
Ok, I have had my coffee, so you can all come out now!
|
|
|
|
|
Wordle 1,058 5/6
π¨π©β¬β¬β¬
β¬π©β¬β¬β¬
β¬β¬π¨β¬π¨
π¨π©π¨π¨β¬
π©π©π©π©π©
|
|
|
|
|
Wordle 1,058 6/6
β¬β¬β¬π©π¨
β¬π¨π¨π©β¬
β¬π©π¨π©π¨
β¬π©π©π©π©
β¬π©π©π©π©
π©π©π©π©π©
|
|
|
|
|
Wordle 1,058 4/6*
β¬🟨🟨β¬🟨
🟩🟨β¬🟩🟩
🟩β¬🟩🟩🟩
🟩🟩🟩🟩🟩
|
|
|
|
|
Gotos are frowned on. You should not use gotos. Long live gotos.
Until someone comes up with a better/faster/concise way of expressing the following DFA state machine (presented in part) I will continue to defend the use of gotos, even if their use cases have gotten significantly more narrow as progress has marched on.
When you need them, there is no better tool.
internal sealed partial class JsonStringRunner : FAStringRunner {
private FAMatch NextMatchImpl(string s) {
int ch;
int len;
int p;
int l;
int c;
ch = -1;
len = 0;
if ((this.position == -1)) {
this.position = 0;
}
p = this.position;
l = this.line;
c = this.column;
this.Advance(s, ref ch, ref len, true);
if (((((ch >= 9)
&& (ch <= 10))
|| (ch == 13))
|| (ch == 32))) {
this.Advance(s, ref ch, ref len, false);
goto q1;
}
if ((ch == 34)) {
this.Advance(s, ref ch, ref len, false);
goto q2;
}
if ((ch == 44)) {
this.Advance(s, ref ch, ref len, false);
goto q9;
}
if ((ch == 45)) {
this.Advance(s, ref ch, ref len, false);
goto q10;
}
if ((ch == 48)) {
this.Advance(s, ref ch, ref len, false);
goto q11;
}
if (((ch >= 49)
&& (ch <= 57))) {
this.Advance(s, ref ch, ref len, false);
goto q17;
}
if ((ch == 58)) {
this.Advance(s, ref ch, ref len, false);
goto q18;
}
if ((ch == 91)) {
this.Advance(s, ref ch, ref len, false);
goto q19;
}
if ((ch == 93)) {
this.Advance(s, ref ch, ref len, false);
goto q20;
}
if ((ch == 102)) {
this.Advance(s, ref ch, ref len, false);
goto q21;
}
if ((ch == 110)) {
this.Advance(s, ref ch, ref len, false);
goto q26;
}
if ((ch == 116)) {
this.Advance(s, ref ch, ref len, false);
goto q30;
}
if ((ch == 123)) {
this.Advance(s, ref ch, ref len, false);
goto q32;
}
if ((ch == 125)) {
this.Advance(s, ref ch, ref len, false);
goto q33;
}
goto errorout;
q1:
if (((((ch >= 9)
&& (ch <= 10))
|| (ch == 13))
|| (ch == 32))) {
this.Advance(s, ref ch, ref len, false);
goto q1;
}
return FAMatch.Create(10, s.Substring(p, len), p, l, c);
q2:
if ((((((ch >= 0)
&& (ch <= 9))
|| ((ch >= 11)
&& (ch <= 33)))
|| ((ch >= 35)
&& (ch <= 91)))
|| ((ch >= 93)
&& (ch <= 1114111)))) {
this.Advance(s, ref ch, ref len, false);
goto q2;
}
if ((ch == 34)) {
this.Advance(s, ref ch, ref len, false);
goto q3;
}
if ((ch == 92)) {
this.Advance(s, ref ch, ref len, false);
goto q4;
}
goto errorout;
q3:
return FAMatch.Create(9, s.Substring(p, len), p, l, c);
q4:
if (((((((((ch == 34)
|| (ch == 47))
|| (ch == 92))
|| (ch == 98))
|| (ch == 102))
|| (ch == 110))
|| (ch == 114))
|| (ch == 116))) {
this.Advance(s, ref ch, ref len, false);
goto q2;
}
if ((ch == 117)) {
this.Advance(s, ref ch, ref len, false);
goto q5;
}
goto errorout;
q5:
if (((((ch >= 48)
&& (ch <= 57))
|| ((ch >= 65)
&& (ch <= 70)))
|| ((ch >= 97)
&& (ch <= 102)))) {
this.Advance(s, ref ch, ref len, false);
goto q6;
}
goto errorout;
q6:
if (((((ch >= 48)
&& (ch <= 57))
|| ((ch >= 65)
&& (ch <= 70)))
|| ((ch >= 97)
&& (ch <= 102)))) {
this.Advance(s, ref ch, ref len, false);
goto q7;
}
goto errorout;
Check out my IoT graphics library here:
https://honeythecodewitch.com/gfx
And my IoT UI/User Experience library here:
https://honeythecodewitch.com/uix
|
|
|
|
|
Most developers know goto statements are "bad" but very few know why or have even read Dijkstra's letter in CACM. And I'm willing to bet most developers haven't heard of the ACM.
goto statements that target entry into a block (as you could do in older versions of Fortran and Basic) are frowned upon because they make automated program verification impossible - aka "I can't say with certainty how you got here". Well behaved goto statements are not only fine, you couldn't write code without them.
To make it harder for novice programmers to misuse the goto statement, many languages such as C, C++, Java and C# (and many others) have created statements that implement well behaved goto 's. They are:break - goto the end of a switch or terminate the closest enclosing iteration statement
continue - start a new iteration of the closest enclosing iteration statement
return - exit the function in which it appears and return to the caller
And most (I suspect all) modern compilers won't allow specifying the target of a goto into another block. So use goto 's, but use them the way nature intended.
/ravi
|
|
|
|
|
Ravi Bhavnani wrote: And most (I suspect all) modern compilers won't allow specifying the target of a goto into another block
Not exactly sure what you mean here, but C/C++ certainly allows you to goto into a contained block, or to a label in another code block within the same containing block e.g.
void f(int n)
{
if(n > 1)
goto foo;
if( ... )
{
if ( ... )
goto foo; }
if( ... )
{
foo:
}
} Will compile just fine. You can get a warnings if you have an initialization before label foo , with the right warning options (gcc/clang, at least), but a quick perusal of the warning options doesn't seem to suggest that there's a warning for a goto int a contained block.
But maybe you meant that you can't jump from one block to another, like
void foo()
{
foo_label:
}
void bar()
{
goto foo_label; } But for that you have setjmp/longjmp , which, of course, should be avoided like the plague.
"A little song, a little dance, a little seltzer down your pants"
Chuckles the clown
|
|
|
|
|
k5054 wrote: C/C++ certainly allows you to goto into a contained block, ... Thanks for the correction. The C# compiler doesn't permit that.
/ravi
|
|
|
|
|
C++ is painfully permissive at times, but not nearly so bad as C. C# brought a bit of sense to the mess, even if it sacrifices the ability to do some of the black magic.
Check out my IoT graphics library here:
https://honeythecodewitch.com/gfx
And my IoT UI/User Experience library here:
https://honeythecodewitch.com/uix
|
|
|
|
|
totally agree, Ravi. Well said.
"A little time, a little trouble, your better day"
Badfinger
|
|
|
|
|
Break, continue, and return are basically goto, when translated to low level machine codes
Also for-loop, if-else, while-do, switch, etc.
Gotos are frowned because some people used it badly. Maybe they caused infinite loop or something. Maybe they forgot to free the allocated memory. Also it shouldn't be used when your high level language provides more explanatory keywords above. The reason is obviously, for maintainability and readibility purpose.
|
|
|
|
|
One of my professors was the GOTO person for many of us students, in terms of resolving technical doubts and even giving career advice.
We need more such GOTOs, i feel.
|
|
|
|
|
If I were given the responsibility for a state machine implementation like that, I would immediately run to my boss asking for permission to rewrite the whole thing as a table driven machine.
There is no way, with code like that, that I could guarantee that all inputs/events are properly handled in all cases (or given the proper error treatment). I would have to make a huge effort if I were to report a complete set of normal (non-error) ways to go from a given state to another, and which inputs/events would lead to which error states.
I've never written any CP article, but code like this makes my fingers itch to compose an article about proper table driven state machine implementation! Maybe I some day get around to do it
Religious freedom is the freedom to say that two plus two make five.
|
|
|
|
|
Fair enough. I generated that code using Visual FA. It's slightly faster than the table driven variety, which Visual FA can also generate.
Check out my IoT graphics library here:
https://honeythecodewitch.com/gfx
And my IoT UI/User Experience library here:
https://honeythecodewitch.com/uix
|
|
|
|
|
Compilers will generate jump statements. I don't mind, as long as I don't have to trace them, and maintain the code at that level.
Other generators may generate source format goto statements. I don't mind, as long as I don't have to trace them, and maintain the code at that level.
If the gotos and labels you presented are created by a generator, and you never will have to trace them and maintain the code at that level, I do not consider them "your" gotos. Not any more than I consider the conditional and unconditional jumps generated from your source code to be "your" jmp instructions.
I'd be curious to also see your input to Visual FA to generate this code, as well as the table driven code generated by Visual FA!
If you have any reason at all to relate to the generated code: Trading readability and maintainability for "slightly faster code" is generally a bad move. Besides: From the snippet you presented, I am surprised that a table driven variety generated from the same input can be even "slightly" slower. I really wonder what that generator generates! (That is why I'd like to see it.)
I have never been using Visual FA, but from what I gather from a quick net search, it looks like you are not at all using SM as a development too. You are just generating code for different virtual machines, one with a state oriented execution model, one with a C/C++ oriented execution model. A comparison between them is like compiling some (arbitrary language) source code for x64 and for AArch64 and observing that the x64 is "slightly faster".
To me, the SM table is not the result delivered by a generator - it is a modeling tool for the human developer. The driver is typically a score code statements, independent of the model (a.k.a. transition table). I certainly agree that an editor tailored to transition table editing is a great thing to have. I have tried to maintain a compile time initialized C++ array for a transition table, using Np++. Even for trivial SMs, that is almost impossible (unless you just copy the table from e.g. a standard document and it will be carved in stone).
Religious freedom is the freedom to say that two plus two make five.
|
|
|
|
|
trΓΈnderen wrote: If you have any reason at all to relate to the generated code. Trading readability and maintainability for "slightly faster code" is generally a bad move. . I generally agree with you. However, as we both know there are exceptions, which is why you used the word "generally" I'm sure. This is one of those cases, as lexing is always in a critical code path, and a generalized lexer must be able to handle bulk input as efficiently as possible.
My input to visual fa is one or more regular expressions. Literally just that. Here is the full input for that generated lexer, in my .rl Rolex lexer format, but it should be easy enough to discern the grammar below without knowing the format.
Object = "{"
ObjectEnd = "}"
Array = "["
ArrayEnd = "]"
FieldSeparator = ":"
Comma = ","
Number = '-?(?:0|[1-9][0-9]*)(?:\.[0-9]+)?(?:[eE][+-]?[0-9]+)?'
Boolean = 'true|false'
Null = "null"
String = '"([^\n"\\]|\\([btrnf"\\/]|(u[0-9A-Fa-f]{4})))*"'
WhiteSpace = '[ \t\r\n]+'
The table driven code is run on a flat array of integers. It might be more efficient to unflatten it in this case - maybe? I used to run a more complicated array of structs for this, and I don't remember there being a performance difference. But anyway, there is also an array of int arrays for a feature called block ends, which simulate lazy matching on a DFA. (I have the details of all of it documented in my Visual FA series). It's also simpler in operation than it looks. I do actually use gotos in a couple of places here to restart the state machine. It was much less complicated than orchestrating a while with breaks. I should state that I didn't comment the code here because it wouldn't help me. It may help others, but I didn't really care about that. This pattern is burned into my brain after writing more than half a dozen lexers that follow the same. It honestly would just clutter it for me, as the code makes immediate sense to me despite how it looks, and I didn't write it for a team.
private FAMatch _NextImpl(
#if FALIB_SPANS
ReadOnlySpan<char> s
#else
string s
#endif
)
{
int tlen;
int tto;
int prlen;
int pmin;
int pmax;
int i;
int j;
int state = 0;
int acc;
if (position == -1)
{
++position;
}
int len = 0;
long cursor_pos = position;
int line = this.line;
int column = this.column;
int ch = -1;
Advance(s, ref ch, ref len, true);
start_dfa:
acc = _dfa[state];
++state;
tlen = _dfa[state];
++state;
for (i = 0; i < tlen; ++i)
{
tto = _dfa[state];
++state;
prlen = _dfa[state];
++state;
for (j = 0; j < prlen; ++j)
{
pmin = _dfa[state];
++state;
pmax = _dfa[state];
++state;
if (ch < pmin)
{
state += ((prlen - (j + 1)) * 2);
j = prlen;
}
else if (ch <= pmax)
{
Advance(s, ref ch, ref len, false);
state = tto;
goto start_dfa;
}
}
}
if (acc != -1)
{
int sym = acc;
int[] be = (_blockEnds != null && _blockEnds.Length > acc) ? _blockEnds[acc] : null;
if (be != null)
{
state = 0;
start_be_dfa:
acc = be[state];
++state;
tlen = be[state];
++state;
for (i = 0; i < tlen; ++i)
{
tto = be[state];
++state;
prlen = be[state];
++state;
for (j = 0; j < prlen; ++j)
{
pmin = be[state];
++state;
pmax = be[state];
++state;
if (ch < pmin)
{
state += ((prlen - (j + 1)) * 2);
j = prlen;
}
else if (ch <= pmax)
{
Advance(s, ref ch, ref len, false);
state = tto;
goto start_be_dfa;
}
}
}
if (acc != -1)
{
return FAMatch.Create(sym,
#if FALIB_SPANS
s.Slice(unchecked((int)cursor_pos), len).ToString()
#else
s.Substring(unchecked((int)cursor_pos), len)
#endif
, cursor_pos, line, column);
}
if (ch == -1)
{
return FAMatch.Create(-1,
#if FALIB_SPANS
s.Slice(unchecked((int)cursor_pos), len).ToString()
#else
s.Substring(unchecked((int)cursor_pos), len)
#endif
, cursor_pos, line, column);
}
Advance(s, ref ch, ref len, false);
state = 0;
goto start_be_dfa;
}
return FAMatch.Create(acc,
#if FALIB_SPANS
s.Slice(unchecked((int)cursor_pos), len).ToString()
#else
s.Substring(unchecked((int)cursor_pos), len)
#endif
, cursor_pos, line, column);
}
while (ch != -1)
{
var moved = false;
state = 1;
tlen = _dfa[state];
++state;
for (i = 0; i < tlen; ++i)
{
++state;
prlen = _dfa[state];
++state;
for (j = 0; j < prlen; ++j)
{
pmin = _dfa[state];
++state;
pmax = _dfa[state];
++state;
if (ch < pmin)
{
state += ((prlen - (j + 1)) * 2);
j = prlen;
}
else if (ch <= pmax)
{
moved = true;
}
}
}
if (moved)
{
break;
}
Advance(s, ref ch, ref len, false);
}
if (len == 0)
{
return FAMatch.Create(-2, null, 0, 0, 0);
}
return FAMatch.Create(-1,
#if FALIB_SPANS
s.Slice(unchecked((int)cursor_pos), len).ToString()
#else
s.Substring(unchecked((int)cursor_pos), len)
#endif
, cursor_pos, line, column);
}
Check out my IoT graphics library here:
https://honeythecodewitch.com/gfx
And my IoT UI/User Experience library here:
https://honeythecodewitch.com/uix
|
|
|
|
|
trΓΈnderen wrote: To me, the SM table is not the result delivered by a generator - it is a modeling tool for the human developer. The driver is typically a score code statements, independent of the model (a.k.a. transition table). I certainly agree that an editor tailored to transition table editing is a great thing to have. I have tried to maintain a compile time initialized C++ array for a transition table, using Np++. Even for trivial SMs, that is almost impossible (unless you just copy the table from e.g. a standard document and it will be carved in stone).
I didn't address this part of your post. I should. I don't expect transition tables to be especially readable.
Visual FA is called "Visual" because it can produce images - directed graphs of the state machines that match 1:1 with the generated tables and code. For example, q0 in the graph corresponds to the q0 : label in the goto table. It's perspicuous enough and yet concise enough that I've used the graphs as a guide to hand roll lexers when i needed the lexer to perform additional work beyond what a strict DFA could provide.
I've also used them to debug. Since the correlation is 1:1 between the graphs and the compiled code, it's easier to follow along with than the tables, but both can be followed with the graphs.
The graphs effectively become in part, documentation for the state machine, and for that they work pretty well.
Check out my IoT graphics library here:
https://honeythecodewitch.com/gfx
And my IoT UI/User Experience library here:
https://honeythecodewitch.com/uix
|
|
|
|
|
Generally you are right, usually the codewitch works on small embedded systems where performances and code footprint can be extremely stringent.
I found myself doing things I would have abhorred only a few scant years ago...
GCS/GE d--(d) s-/+ a C+++ U+++ P-- L+@ E-- W+++ N+ o+ K- w+++ O? M-- V? PS+ PE Y+ PGP t+ 5? X R+++ tv-- b+(+++) DI+++ D++ G e++ h--- r+++ y+++* Weapons extension: ma- k++ F+2 X
The shortest horror story: On Error Resume Next
|
|
|
|
|