
Foolproof HTML - voctor
https://pumpula.net/foolproof-html
======
lisper
> If you have a good strategy for validating your template files, I'd love to
> hear it!

Use S-expression syntax instead of SGML syntax, i.e. instead of:

<tag attr=value ...>content</attr>

write

((tag attr value ...) content)

and use Lisp to process it. It's actually quite straightforward. You can apply
it to XML as well. Everything actually ends up looking a lot prettier this
way.

See [http://weitz.de/cl-who/](http://weitz.de/cl-who/) for an example of an
implemented system that works this way. I've been using it in production for
years. It works like a charm.

~~~
tyingq
Interesting, but you would still have to account for the inconsistencies of
html, like:

\- Standalone, non-closed tags <!doctype>, <hr>, <br>, <link>, <meta>, <img>
etc.

\- Proper encoding or quoting of [< > " ' &] in html attributes

\- <script> tags and CDATA

Probably lots more as well. Not rocket science of course, but you would want a
tool where you have some confidence they've covered all of these things.

~~~
recursive
Last time I looked <textarea> and <pre> also worked kind of like <script>.

~~~
minitech
<pre> doesn’t at all. At a stretch, maybe you’re thinking of <xmp>?

------
Insanity
It was a nice read, and I like the way the idea was presented. But one thing
that stood out to me as kind of odd was the distinction between typing
lowercase and uppercase characters. Automatically assuming lowercase to be a
"keyword" does not seem like the right idea to me. Most sentences on the web
might start with a capital, but not all of them will do. (For example here on
HN, you have in the nav bar "new | threads | comments | .." None of them
starting with a capital.

~~~
netsharc
This irritated me too. I suppose a shortcut can be added to say "treat the
next thing entered as a text element", along with the uppercase shortcut. So
the user can type e.g. "!new" and the editor will make a text node with "new"
as its content.

------
andrei_says_
I found my foolproof HTML in slim-lang.

It produces standards-compliant HTML and prevents me from writing code that is
not well-formed.

The above is a nice side effect of its incredibly clean and terse syntax.

Now I feel cheated any time I need to write regular HTML.

[https://github.com/slim-
template/slim/blob/master/README.md](https://github.com/slim-
template/slim/blob/master/README.md)

I used emmet for a while but slim improves on writing _and_ reading code.

~~~
ungzd
Slim becomes painful when using Ruby function calls (i.e. Rails helpers).
Sometimes these functions have long list of parameters and wrapping to next
line sometimes becomes not so convenient. Moving, copying and pasting indented
blocks is also quite painful and it's much harder to see nested structure than
in, for example, Python code. Also it has complicated syntax for attributes
and text content, especially text content. I have to look up its docs again
and again. It reminds me of yaml which has the same problems (but much worse,
yaml's documentation has size of a book).

However I'm not a fan of ERB or Django/Jinja template markups either.
Indentation-based syntax has its advantages, it works well for Python and ML-
like languages. Just Slim can be improved further.

~~~
andrei_says_
Would you consider pasting a sample? I do work with rails and can't think of a
time when I have experienced this issue.

Maybe when passing multiple cars to a partial?

------
westoncb
Regarding the 'code without syntax' part: I wrote something that basically
does this for any language that you have an EBNF grammar for. It turns the
grammar into a graph; wherever your cursor is in the document at a given
moment corresponds to some node in the graph; the edges going out of that node
are the syntactically valid things you can insert from that point.

Unfortunately there is no UI for it atm—though there is UI for the editing
portion (which almost exactly matches the author's .gif at the end of the
document):
[https://www.youtube.com/watch?v=tztmgCcZaM4&feature=youtu.be...](https://www.youtube.com/watch?v=tztmgCcZaM4&feature=youtu.be&t=1m36s)

It's a concept that a lot of people have explored. My understanding is that
some academics were interested in it a while ago but never produced anything
that worked well and kind of wrote it off. Now some people are revisiting it
(e.g. Unison[1] and Jetbrains MPS[2]).

I think the core idea involved is a shift away from using text _as a model for
representing programs_ ; instead, interact with more abstract representations
of code, and _render_ those abstractions as text. This allows your editor to
have better understanding of the language you're using, so syntax becomes a
property of a language's visualization rather than something totally central
to it (and now you don't have to memorize it!).

[1]
[http://unisonweb.org/2015-05-07/about.html](http://unisonweb.org/2015-05-07/about.html)
[2] [https://www.jetbrains.com/mps/](https://www.jetbrains.com/mps/)

~~~
meredydd
The problem with these environments is that humans routinely want to write
syntactically incorrect code as they transition from one valid program to
another. An AST-based editor like this enforces that _every_ intermediate step
must parse as a valid program. This restriction makes making changes a massive
pain in the ass, because you can no longer take the shortest route from where
you are to where you want to be.

For example, imagine you're restructuring an if-else sequence into a switch
statement. You're probably going to change that first "if" to a "switch", then
go down changing all the "else"s into "case"s. This is eminently sensible, but
an AST-based editor will stop you dead if you try to do this, because the
intermediate states are not valid ASTs.

The only system slightly like this I've seen in widespread use is Paredit,
which prevents you typing anything that isn't a valid s-expression. This only
works because s-expression syntax is so minimal, and most of Lisp's actual
syntax is layered on top with macros. Even if you're using Paredit, your
spit/slurp/kill operations will produce invalid intermediate code that would
fail to compile.

~~~
westoncb
That's an interesting point. I've heard other people bring up this issue in a
vague way, but your example makes it clear why people would have a concern
about this.

At the same time, however, I'm not convinced it's a serious issue—it's more
important to save work and avoid re-typing the shell of a switch when you have
to type it one character at a time. If you're mapping language constructs to
single keys (this was the way I went), you can crank out a new multi-block
switch statement in a few keystrokes; then (in my editor anyway), you can just
drag the code blocks from the if statements into the new structure.

Even better, since the editor has easy access to info about language
structure, it could include automatic transformations to transition between
structurally similar language constructs.

I think it seems unnatural at first because we're so used to typing characters
out one at a time, and it seems like we're throwing that skill out the window
when considering an alternate form of editor. I still don't really see an
intrinsic limit though.

I'd appreciate any other counter-example you may have (a lot of why I don't
continue working on my own project at the moment is concern that these are
lurking and I'll only discover them after lots more wasted effort—so if I
could definitively rule out that this project is a good idea, that'd be
great.)

~~~
meredydd
I'd say the opposite - in your shoes, I'd just try it, doomed or not! (But
then again building an IDE is My Thing atm - check my profile.) Building one
of these systems is going to be really fun.

If you don't have the time/inclination to just do it cause it's a cool
project, one option is to "paper prototype" the feasibility of the transforms
you'd need.

Next time you're writing any code in the first language you want to support in
that AST editor, take a screen recording of at least half an hour's coding.
Watch it back later, and keep a count of how many times you:

* transition from one valid program to another in a simple way (eg just writing a line of code from scratch that's valid first time)

* transition in a way that would require abandoning your keyboard and reaching for your mouse in your editor (NB this is a _seriously_ slow operation, usually taking a couple of seconds or more).

* transition in a complex way your editor would support if it had that kind of transform built in (eg if/else-> switch), and work out exactly how clever that transform would have to be (would it work if the if/elses weren't simple equality checks? If they weren't, how would you make the transform if you weren't allowed any non-compiling code?) Then enumerate the distinct such transforms you'd need to cover that half-hour of typing. (You will probably discover a Pareto-type distribution - the question is how tight the head/long the tail is. My guess is you'd need a _huge_ number of special transforms to cover 95% of your edits, but data beats guessing)

* Jump around between statements (eg half-write something, leave it in an utterly broken state, then go actually define the variable/function you're using, then jump back and finish your thought). Your editor would have to permit this somehow or it will be really frustrating to use.

~~~
westoncb
Thanks for the reply meredydd. That does seem like a good approach.

Actually, I spent 1.5 years building an editor in this style (see link in my
original post here) while working at a grocery store :)

Unfortunately, while I can see now that I should have first been super focused
on validating the concept—I instead just kind of ran with it, assuming it was
going to work, and built this massive, probably over-engineered, framework for
generating editors for given grammars (with my starting point being: not even
knowing what a grammar was, thinking I'd have to invent some kind of
'linguistic constraint description' format ;) ).

As it stands the editing portion works well enough for a demo, but the program
never reached the point where I could write code with it, so a lot of these
questions are still un answered for me. I think doing the paper prototype on
these edit actions would be a good pre-coding validation step.

I did check out Anvil briefly. My two second, potentially incorrect summary
would be VB for web apps. Is that close? Are you guys doing anything special
for working with text itself?

~~~
meredydd
"VB for web apps" is a fair summary. We made a conscious decision against
anything AST-based (for the reasons I outlined above), and we're about to
deploy an Intellisense-style autocompleter instead. Our general philosophy is
that coding is fine - it's the web/Javascript ecosystem that's the problem. We
fix that, then get out of the way and let you write code :)

As for validating one's side projects before starting work - I personally
think the Lean Startup thing can be taken a bit far. An interesting leisure-
time technical project doesn't need the same level of prior justification as a
big commercial project (even if it might one day evolve into one), as long as
you're having fun. We do this stuff because we enjoy it!

~~~
westoncb
> it's the web/Javascript ecosystem that's the problem.

I agree—that's definitely the bigger issue. I think differences between
editors and languages tend to be overblown in general.

Unfortunately the project for me was not quite a fun thing: I ran into an
issue with mouse/keyboard overuse, so I was trying to build an editor that
could work efficiently with motion sensors. In the meantime, coding was
painful :/ I'm still looking for an alternative for that reason—but VR and
mobile also have needs for efficient editors that can be operated with fewer
unique symbols.

Also, another solution to the AST editor issue: just convert any non-parsing
nodes into plain text nodes until they're fixed.

------
lihaoyi
I made a Scalatags library that lets you write your HTML templates in-line in
your Scala code (or Scala.js), similar to React's JSX but without the XML
syntax:

    
    
        div(
          h1(id:="title", "This is a title"),
          p("This is a big paragraph of text")
        )
    

[http://www.lihaoyi.com/scalatags/#ScalaTags](http://www.lihaoyi.com/scalatags/#ScalaTags)

Although this ties it to the Scala _language_ , it does not tie you to a
particular platform: the templates can run on the JVM, in the browser with
Scala.js, and even in the new scala-native LLVM backend.

The fact that the chosen language is statically typed means you get "basic"
level validation right-off-the-bat thanks to the compiler:

[http://www.lihaoyi.com/scalatags/#WhyScalatags](http://www.lihaoyi.com/scalatags/#WhyScalatags)

Basic typo-detection, enforcing things are properly nested, anti-XSS-
enforcement, along with all the other "standard" IDE features: jump-to-
definition for your sub-templates (which are just functions), use of arbitrary
code within your templates (not unlike JS-X), etc.. Also, the fact that your
templates are compiled into bytecode/JS at build time rather than interpreted
and re-implementing scope management and variable-bindings and such in user-
land code at runtime, means the templates are really very fast.

All this comes "for free", since your templates are code like any of the other
code you write, and are handled by the IDE and optimized by the compiler in
the same way.

The downside, of course, is that templates are code and thus cannot be
provided safely by third parties, similar to React's JS-X

------
arca_vorago
The problems I mostly have run into regarding html are because we have started
shoving random javascript and javascript-esque things into it and over
complicating things, often needlessly. The author says it himself "That's fine
for plain HTML", referring to validation.

This is why back in 2014 I decided that I was going to focus on making as many
of the webpages I make pure html5/css3, and keep javascript completely out of
the picture if possible and now if I do break that rule I make it LibreJS
compatible.

For an editor, I am an avid emacs fan, but for templates, I have of late
become enamoured with asciidoc and asciidoctor, originally using them for
sysadmin documentation things, I am beginning to realize my method of writing
web pages (sshed into a box using emacs and updating with cron jobs calling
asciidoc and bash scripts) might actually be good for just normal web stuff
too.

Of course, there are some downsides, but I never really was a wysiwg sort of
person anyway, because every time I've gotten my hopes up about some wyswig,
it failed me in countless and unfathomable ways.

I feel like people have veered too far away from the core purposes of html and
css, html for content and structure, css for design and display control.

We've gotten to the point now where I can visit any random top 500 alexa sites
and anywhere from 10-50 javascripts are trying to load. It's ridiculous, and I
think a return to simplicity will be key for most websites, because lets face
it, you probably really don't need crud for $project.

------
Perixoog

        Code ??? WYSIWYG
        Could there be something unexplored in the middle?
    

WYSIWYM - What You See Is What You Mean.

Most famously used by the LaTeX powered document processor, LyX.

[https://en.wikipedia.org/wiki/WYSIWYM](https://en.wikipedia.org/wiki/WYSIWYM)

------
c-smile
"Could there be something unexplored in the middle?"

I believe so.

At the moment I am working on next version of my blocknote.net editor - the
editor for "Web writers" \- people who create textual content of the Web.

Check [http://sciter.com/new-blocknote-net-application-is-
getting-i...](http://sciter.com/new-blocknote-net-application-is-getting-its-
shape/)

In particular first screenshot. It has so called block outline bar that shows
structure of the HTML underneath WYSIWYG text.

IMO: For most of people WYSIWYG is still a preferable way of editing text.
Markdown and especially HTML source code editing is far from being humanistic.

------
methyl
One of the things I like about JSX is that it will always make sure you write
valid syntax.

Problem with things like slim is that you cannot copy-paste directly from
HTML.

------
jrapdx3
Interesting. Despite the many approaches to writing HTML more are invented all
the time. Currently I'm working on yet another way. My idea follows the Lisp
tradition based on its hierarchical list structures. It's surprisingly easy to
parse and generate HTML from basically simple lists.

    
    
        '(html
          (head
            head stuff ...)
          (body
            (h1 "My HTML")
            (div (@ class "main-div" ...)
              "main div stuff")))
    

Of course it gets a lot more complicated when generating complete web pages
and apps, but using paste operators, procedures and variables can make it
produce anything necessary.

A very similar approach is possible with Tcl, which I am using now for several
reasons including integration with legacy code. In Tcl the above looks like:

    
    
        {html
          {head
            head stuff ...}
          {body
            {h1 {! My HTML}}
            {div {@ class "main-div" ...}
              {! main div stuff}}}
    

In Tcl variables and procedures can be interpolated into the output by
wrapping the list in a "subst" command:

    
    
        [subst {html .... [my-proc $my_var] ....}]
    

The hierarchical nature of Lisp-like languages naturally resembles the GUI
outline form the author presents in the article. Using Tcl it's occurred to me
that it should be possible to write a "front end" to the parser/generator code
using Tk (via the text or canvas widgets) which could resemble the author's
illustrations.

Ultimately I think the difficulty lies in the need for constructing customized
templates to enable modular, easy-to-use GUIs for particular tasks. Real HTML
can quickly become very complex which is the reason for the thousands of
frameworks, generators and templating systems in existence. While I think the
author's approach or my own can potentially be helpful, neither is going to
magically eliminate the burden on the programmer.

~~~
rnhmjoj
There's also Blaze which is a nice haskell library to write templates or just
plain HTML using combinators:
[https://jaspervdj.be/blaze/tutorial.html](https://jaspervdj.be/blaze/tutorial.html)

------
microcolonel
I don't think this is all that helpful. If you use a moderately-decent text
editor, it probably has a closing feature, and an autoindent feature.

If you're writing a new tag in emacs, you just need to write the opening tag,
then press "C-c /", and it will close it for you. If you have a syntax error
of this magnitude, the autoindenter will also help you realize. Just select
the region (or the whole file) and press tab, see where the indentation stops
making sense, and follow back to the opening tag by column.

There are heavy-handed approaches to this, but I find that default-configured
emacs with these two tricks can reduce your error rate to effectively zero,
without requiring you to learn a new tool just for [X][H]TML. I say "just" for
HTML having spent about half of my working hours in HTML for two years full
time. I think this is enough.

~~~
sakamies
Hi! Article aithor here.

Emmet is a great plugin that has tag matching and all kinds of
navigation/editing shortcuts too. Like those emacs shortcuts, it does reduce
error rates and speed up editing signifigantly, at least for me, but I'm more
interested in exactly a heavy handed approach. I'd like an app/plugin/whatever
that makes it impossible to make many types of mistakes, even if it restricts
what I can do.

I code html every day (and I do love it), but I'm a terrible and lazy typist.
I make typos and mistakes constantly, so I'll take all the help I can get. So
I'm trying to make something that will solve my specific woes in html/css
development and I'm hoping someone else finds it useful too.

------
reikonomusha
Is hand-editing lots of HTML a common issue for web devs? I'd think more work
is done elsewhere.

~~~
zschuessler
I've never encountered this problem to the effect I needed a build step for
HTML. I wonder if frontenders who work only with HTML/CSS find it helpful?
Whereas they don't have the concept of breaking up code into templates or
partials with a server-side language.

No disprespect to the author, what you've done is cool and your presentation
is _awesome_. My biggest concerns are:

1\. Onboarding & rampup time that's now added to my team just to write HTML.

2\. Turning away potential hires who don't want to work with an over-
engineered tech stack. Much opinion can be formed just by adding to your job
requirements "we use a transpiled HTML processor"

3\. Technical debt & tech lock-in. Will this technology be a detriment in 5
years? Do we get enough from it right now that it's worth future legacy costs?

------
nishs
Syntax looks similar to Pug (previously called Jade, which was the default
templating language in Express).

[https://pugjs.org/language/tags.html](https://pugjs.org/language/tags.html)

------
escherize
About the gif at the bottom of the page, where a div is swapped in place with
an html sister node...

That's 100% possible to do in Emacs, while editing plain html, using
smartparens-strict-mode. Basically it treats the HTML like lisp code, so by
"autobalancing parens" the editor lets you swap-sexps, which would perform the
same transformation as the drag and drop in the editor, but much quicker and
easier (as long as u can invest in learning the keys.)!

Of course with Hiccup[0] or Reagent[1] code in Clojure/script, it's perfectly
possible too. The same keybindings even.

[0] [http://hiccup.space](http://hiccup.space) [1]
[http://cljsfiddle.com](http://cljsfiddle.com)

(I'm the author of those little projects)

------
c-smile
If to focus on something close to source code editing then why not to simplify
html itself a bit?

Sciter's HTML parser supports shortcut constructs like:

    
    
       <button|checkbox(first)> woo! </button>
    

which is

    
    
       <button type="checkbox" name="first"> woo! </button>
    

And

    
    
        <div#foo>  === <div id="foo">
        <div#bar.solid.main>  === <div id="foo" class="solid main">
    

Not too much but makes life a bit easier while keeping all other HTML features
intact.

------
rhencke
The author might find MPS interesting. It it another attempt at providing an
AST editor for coding.

[https://www.jetbrains.com/mps/](https://www.jetbrains.com/mps/)

------
hdhdhdbdbhdh
Use Hiccup - a Clojure library. You'll have a good syntax highlighting, see
only important stuff (eg. no closing tags because it's Lisp) and much less
place to make stupid errors. Many people complain about plethora of parents in
Lisp code but whatever the syntax is you'll get used to it in <20 hrs.

~~~
escherize
Exactly!

I already mentioned it in this thread but, check out
[http://hiccup.space](http://hiccup.space) to show people how great it works.

For more in depth examples see [http://cljsfiddle.com](http://cljsfiddle.com)

------
ams6110
We had XHTML, which didn't allow anything that wasn't properly formed XML. It
went nowhere.

------
therealmarv
Interesting effort. By the way: Does somebody know a good linter which works
on pure HTML, Vue templates (the HTML part), Jinja templates (the HTML part).
Searching for this, ideally for VSCode.

------
thangalin
The article describes Markdown[1], basically. In my opinion, content should be
written once and transformed to any format[2], including ConTeXt[3], docx,
HTML, EPUB, or plain text. But here's a puzzler.

Every software developer defines and uses variables. If variables are so
powerful, why do WYSIWYG word processors lack the ability to quickly and
easily insert variable definitions?[4] In the screenshot, the left-hand side
provides an editable variable definition hierarchy, the middle pane provides a
Markdown editor, and the right-hand side provides a real-time HTML preview of
the content with variables interpolated and substituted.

After variables, programming language integration--such as R[5]--comes
naturally. Consider the following syntax (that could be hidden through a UI):

    
    
        `r#csv2md('data.csv',totals=TRUE)`
    

The function imports data from an external data source and converts it to
Markdown. The HTML version can be styled, or piped through pandoc to create
beautiful PDF output[6]. In the screenshot, the left-hand side shows the
csv2md command (totals are calculated automatically for numeric columns), the
middle pane shows an HTML preview (real-time), and the right-hand side shows a
PDF produced from the same source document using pandoc and ConTeXt.

The CSV file could also be a JSON request over HTTP, or database query,
meaning that the document is always up-to-date with the most recent data: a
living document. This could be accomplished without having to change the
source document, as well:

    
    
        `r#import(v$data$source,totals=TRUE)`
    

Here, v$data$source is a variable that defines a data source. In this case,
the value might be 'data.csv', but could be 'protocol://host/app/api/json'.
The variables themselves could be sourced from a YAML file, JSON data stream,
or remote database.

This is what I've been working towards for the last several months.[7] There's
more that this editor can do, but it's still in early beta stages, should
anyone care to try it.

[1]:
[https://github.com/jgm/pandoc/issues/168](https://github.com/jgm/pandoc/issues/168)

[2]: [http://pandoc.org/](http://pandoc.org/)

[3]: [http://wiki.contextgarden.net/](http://wiki.contextgarden.net/)

[4]:
[https://raw.githubusercontent.com/DaveJarvis/scrivenvar/mast...](https://raw.githubusercontent.com/DaveJarvis/scrivenvar/master/images/screenshot.png)

[5]:
[https://github.com/bedatadriven/renjin/](https://github.com/bedatadriven/renjin/)

[6]: [http://i.imgur.com/Qe6mTpx.png](http://i.imgur.com/Qe6mTpx.png)

[7]:
[https://github.com/DaveJarvis/scrivenvar](https://github.com/DaveJarvis/scrivenvar)

~~~
skierscott
Hm... I think this post is trying to solve a different problem.

Markdown solves the problem of having content (paragraphs, lists) syntax free.

This post:

> What if you had to write a language where you can make mistakes, but there
> are no errors? Where your parser just silently accepts anything you give it.
> Where you'll have to carefully compare your intentions to the parsed output
> to figure out what went wrong.

> Do you write HTML?

> What I just described was how browsers handle HTML. They will happily accept
> anything you give them and try their best to make sense of it. They could
> swap out element places, change attributes, or do whatever if there's a typo
> in your code.

Looks like they're trying to make make an easy-to-write HTML for all HTML, not
just content.

~~~
thangalin
> Looks like they're trying to make make an easy-to-write HTML for all HTML,
> not just content.

Yes. I know it's a long thread, but pandoc issue 168 and the proposed
"foolproof" syntax are, in essence, addressing the same issue. They both
strive to shroud the nuances of HTML syntax in simpler clothing.

Computationally, there's insignificant difference between this (proposed
syntax):

    
    
        ; --- div {.foo}
        ; Ipsum dolor sit amet
    

And this (foolproof syntax):

    
    
        div class:foo
          Ipsum dolor sit amet
    

What Markdown doesn't have, as you allude to, are data bindings necessary to
drive an interactive experience. Although, with a little ingenuity, a
processor could provide data binding with a Markdown-compatible syntax, such
as:

    
    
        ; --- input {.email}
        ; Email
    
        ; --- shuttle {.from}
        ; Available List
        ; --- shuttle {.to}
        ; Selected List
    

From a high enough perch, they both look the same.

~~~
sakamies
Westoncb said it quite elegantly: "I think the core idea involved is a shift
away from using text as a model for representing programs; instead, interact
with more abstract representations of code, and render those abstractions as
text. This allows your editor to have better understanding of the language
you're using, so syntax becomes a property of a language's visualization
rather than something totally central to it (and now you don't have to
memorize it!)."

Foolproof HTML of course tries to do that only for HTML, but I do hope I can
expand it to CSS, JSON and maybe generalize it later on.

So I'm not advocating for any specific syntax, but rather a way to edit html
so you don't need to care about the syntax. The HTML syntax would still be
there in the .html (or .erb, .php or whatever your template language is) the
same as it has always been, but you could visualize it in a way that's most
comfortable to you and edit it as a structure, so it would be impossible to
produce syntax errors.

This could end up being a text editor plugin or a stand alone app, some sort
of library or kind of anything, but I'm prototyping interactions and ideas as
a standalone web app because that's what I'm good at.

------
SoonDead
I remember XHTML with the application/xhtml+xml mime type. Errors were pretty
visible. The world backed out of it.

------
jbverschoor
Isn't this haml without templating?

~~~
amingilani
This. I literally saw HAML. I love HAML. JSHAML would be awesome.

------
d13
So when are we going to ever get a replacement for for this deeply flawed
technology called HTML?

~~~
recursive
There are some replacements for different parts of it. Like PDF, and whatever
iphones' ui is called for instance.

------
bdcravens
That FrontPage screen shot gave me some flashbacks :-)

------
logicallee
This is one of the best write-ups of all time.

In a way, Python is foolproof C. (I am thinking about the syntactic stuff
around indentation, braces, semicolons, which is what I mean it about. I think
if you can code in both syntaxes, read the article carefully, and generousy
try to follow what I am talking about, you know what I mean.)

