Live data from Hacker News

Plan to throw one away

garethrees.org

71–80 of 88 posts

Re: Plan to throw one away

#71
post #67

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…

Yes, you've spotted the irony in the title :)

Re: Plan to throw one away

#72
post #27

Interestingly, 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…

Most shell interpreter follow this model, perhaps he started Tcl has an improved shell scripting system and only later improved it? It would explain some of the syntax choices which is fairly reminescent of c-shell and some bourne thrown in.

Re: Plan to throw one away

#73
post #67

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…

Also, Brooks later said that if you can iterate your design over time, that's even better than "build one to throw away". This has been the focus of his more recent work like "The Design of Design".

Re: Plan to throw one away

#74

Earlier 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!

I do take your point, and so I've rewritten the opening to be even vaguer.

Re: Plan to throw one away

#75

Are Lex and Yacc still the state of the art 20 years later?

I don't think they were state of the art even back then, but they were widely available, well documented, and produced fast, robust lexers and parsers. They are still just the ticket if you need to quickly get a programming language implementation off the ground.

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

#76

Are Lex and Yacc still the state of the art 20 years later?

Yes, yes they are. I've used them successfully for various parsing projects. And in fact Bison recently picked up GLR parsing to deal with multiple options (https://www.gnu.org/software/bison/manual/bison.html#General...).

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

#77
post #21
post #15

Earlier 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

Bash reads code from a stream, and doesn't read the entire stream before executing the code.

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 5

Re: Plan to throw one away

#78
post #27

Interestingly, 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…

> Interestingly, 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.

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

#79
post #67

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…

Yes, you've spotted the irony in the title :)

Awesome read btw :>

Re: Plan to throw one away

#80
post #60

Are 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.

> 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.

Post reply on HN