This is precisely not what Brooks meant by 'plan to throw one away'. Brooks point is, that you gather information while writing your prototype and incorporate the new-found knowledge into your second, hopefully sound, design. Rees never learned anything new from the first system (what could he learn anyway, what he described sounds like a nightmare), but proceeded to implement it from scratch. Funny thing, I'm readin…
Plan to throw one away
71–80 of 88 posts
Re: Plan to throw one away
#72Interestingly, Tcl was parsed the same way all the way up until Tcl 8.0 introduced a bytecode system in 1997. Each line was parsed right before execution with no separate parsing stage--your code could crash in the middle of executing from a syntax error. Tcl is now about as fast as a typical scripting language and its implementation is regarded as a model of high-quality readable code. I wonder if John Ousterhout (t…
Re: Plan to throw one away
#73This is precisely not what Brooks meant by 'plan to throw one away'. Brooks point is, that you gather information while writing your prototype and incorporate the new-found knowledge into your second, hopefully sound, design. Rees never learned anything new from the first system (what could he learn anyway, what he described sounds like a nightmare), but proceeded to implement it from scratch. Funny thing, I'm readin…
Re: Plan to throw one away
#74Earlier quoted context omitted.
For "twenty years", read "once upon a time". I feel that a bit of vagueness in dates is appropriate for a story like this. I have no contemporary written documentation, so it's based on my fallible memory, and I don't want to give a false impression of accuracy.
Yep, that's more or less what I did ("back in the mid to late 90s") to continue reading and not second guess it to much. Great story otherwise, thanks for sharing it!
Re: Plan to throw one away
#75Are Lex and Yacc still the state of the art 20 years later?
There are some things that they don't do so well. It takes hard work to get good error messages out of Yacc, and anything that you might prefer to solve using feedback between the parser and the lexer (such as JavaScript's use of newline to terminate a statement, but only if it makes syntactic sense) is awkward to do because of Lex's lookahead — the token you want to suppress has already been produced by the time you know whether you want to suppress it.
But its important not to get stuck worrying about minor issues like these when the critical task is to make something that works. You can always plan to throw away the Yacc-built parser and replace it with something better when you have time.
Re: Plan to throw one away
#76Are Lex and Yacc still the state of the art 20 years later?
But for something even more fun, I suggest you check out Marpa (https://jeffreykegler.github.io/Marpa-web-site/). It is, by far, the nicest parsing tool I have ever worked with. Being able to parse ANY BNF is huge. And the state tables for debugging! Knowing what possibilities you have makes things way easier. Especially for getting stuck in an ambiguous spot of your grammer. Finally, using ruby slippers to get out of a tight spot is hugely useful.
My one complaint is that the only implementation is in Perl. The core engine is written in C though, so someday I would like to convert the Perl into Python. I started several months ago, and haven't been able to get back to it. (https://github.com/srathbun/pyMarpa)
Re: Plan to throw one away
#77Earlier quoted context omitted.
Didn't PHP also used to use the position of a fileseek as the instruction pointer?
Shell script interpreters like bash do. You can change a bash script while it's running (append, or truncate and re-write) and it'll keep going from the same offset. But then again, shell script is in a different class of language I'd say. #!/bin/bash COUNTER=0 addmore() { echo hi $COUNTER ((COUNTER++)) echo "addmore" >>$0 sleep 1 } addmore
However, the stream pointer isn't its instruction pointer in the script. A backwards branch (such as the end of a while loop, or a call to a function defined earlier) does not rewind the stream to that piece of text.
> But then again, shell script is in a different class of language I'd say.
Not much different in this regard from how, say, Common Lisp (load "file.lisp") processes the top-level forms in the file.
(defvar *counter* 0)
(defun addmore ()
(format t "hi ~s~%" (incf *counter*))
(with-open-file (f "addmore.lisp" :direction :output :if-exists :append)
(write-line "(addmore)" f)))
$ clisp addmore.lisp
hi 1
WARNING: OPEN: #
already points to file "/home/kaz/test/addmore.lisp", opening the
file again for :OUTPUT may produce unexpected results
Open the file anyway
hi 2
WARNING: OPEN: #
already points to file "/home/kaz/test/addmore.lisp", opening the
file again for :OUTPUT may produce unexpected results
Open the file anyway
hi 3
WARNING: OPEN: #
already points to file "/home/kaz/test/addmore.lisp", opening the
file again for :OUTPUT may produce unexpected results
Open the file anyway
hi 4
WARNING: OPEN: #
already points to file "/home/kaz/test/addmore.lisp", opening the
file again for :OUTPUT may produce unexpected results
Open the file anyway
hi 5Re: Plan to throw one away
#78Interestingly, Tcl was parsed the same way all the way up until Tcl 8.0 introduced a bytecode system in 1997. Each line was parsed right before execution with no separate parsing stage--your code could crash in the middle of executing from a syntax error. Tcl is now about as fast as a typical scripting language and its implementation is regarded as a model of high-quality readable code. I wonder if John Ousterhout (t…
Fun fact: most modern JavaScript engines in browsers work this way today, though at a different level of granularity. Parsing slows down application startup, so many JS engines don't parse a function body until it's first called. This means you can have a syntax error in a function body and won't know if it's never used.
Re: Plan to throw one away
#79This is precisely not what Brooks meant by 'plan to throw one away'. Brooks point is, that you gather information while writing your prototype and incorporate the new-found knowledge into your second, hopefully sound, design. Rees never learned anything new from the first system (what could he learn anyway, what he described sounds like a nightmare), but proceeded to implement it from scratch. Funny thing, I'm readin…
Yes, you've spotted the irony in the title :)
Re: Plan to throw one away
#80Are Lex and Yacc still the state of the art 20 years later?
Parsing JavaScript efficiently is not the problem. Much more difficult is writing the garbage collector. Especially a concurrent one.
Since JS is single-threaded, you can write a simple stop-the-world mark-sweep collector as a first iteration. (Simple reference counting probably isn't a good idea since cycles are common in JS.) Then you can move to incremental and/or generational if that's giving you annoying hitches. Only after that do you need to put concurrent on the table.
I believe even world class JS engines have only relatively recently started doing GC in another thread.