Here's some code from one of my vocabs:

: do-load ( -- )
  try-everything keys "../load-everything-vocabs" [ . ] with-file-writer ;

: do-tests ( -- )
  run-all-tests keys "../test-all-vocabs" [ . ] with-file-writer ;

: do-benchmarks ( -- ) run-benchmarks "../benchmarks" [ . ] with-file-writer ;

: do-all ( -- )
  bootstrap-time get   "../boot-time" [ . ] with-file-writer
  [ do-load  ] runtime "../load-time" [ . ] with-file-writer
  [ do-tests ] runtime "../test-time" [ . ] with-file-writer
  do-benchmarks ;

Someone could argue that I could factor out the "[ . ] with-file-writer". 
Sure, but you know what? In a pinch, this did the trick and it looks fine.

Enter forced encodings:

: do-load ( -- )
try-everything keys "../load-everything-vocabs" utf8 [ . ] with-file-writer ;

: do-tests ( -- )
run-all-tests keys "../test-all-vocabs" utf8 [ . ] with-file-writer ;

: do-benchmarks ( -- )
run-benchmarks "../benchmarks" utf8 [ . ] with-file-writer ;

: do-all ( -- )
  bootstrap-time get   "../boot-time" utf8 [ . ] with-file-writer
  [ do-load  ] runtime "../load-time" utf8 [ . ] with-file-writer
  [ do-tests ] runtime "../test-time" utf8 [ . ] with-file-writer
  do-benchmarks ;

That's pretty ridiculous. It's so silly that now I'm really compelled to 
factor out 'utf8 [ . ] with-file-writer', whereas before I found it 
tolerable.

The code would've worked as is if we had default encodings.

Now, lets suppose that one day I got in trouble for not explicitly specifying 
the encoding here. As you can see, 'do-all' calls all the other do-* words. 
If I had felt the need to set the encoding explicitly, dynamic scope would 
have saved the day:

: do-all ( -- )
  [
    utf8 set-default-encoding
    ...
  ]
  with-scope ;

Alright, let's say that dynamic scoping doesn't give you warm fuzzies. You 
want to explicity state the encoding of a particular stream. This is easy if 
you have created a stream and it's on the stack; you just call a word like 
set-encoding ( stream encoding -- stream ), e.g.:

        "out.txt" <file-writer> utf16 set-encoding

Now your stream is immune to the haze of dynamic scope.

So how do you set the encoding with stream combinators where you don't ever 
have the stream on the stack? An example of one of these combinators 
is 'with-file-writer'. Remember that in the quotation you can always get to 
the stream via the stdio variable. So you could set the encoding explicitly 
like so:

        "out.txt"
          [
            stdio get utf16 set-encoding
            ...
          ]
        with-file-writer

One big point of the api I'm proposing is that you aren't forced to change 
your code, but you can if you want to, in various ways which suit your needs. 
This sort of elegance is what I've come to expect from Factor.

Here's my bold claim:

        There are many cases where the programmer won't need to care about text
        encoding.

Therefore:

        The language shouldn't force the programmer to "think" about it.

It's like forcing your kids to pray; programmers are just going to murmur 
the 'utf8' incantations mindlessly. Better to just leave the good book nearby 
and someday, when they need it, it'll be there for them.

Sure, I can code my way around all these annoyances. I can probably even build 
up the whole api I want as a wrapper over the core api. But is it a good sign 
when coders start to do things like this?

Ed

-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2008.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
_______________________________________________
Factor-talk mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/factor-talk

Reply via email to