Hi Ed,
The overwhelming majority of the ideas you've proposed for Factor are
great. I love the new-slots, bake, fry, 'cleavage' combinators,
new-style constructors, and the module system.
However, as far as default encodings go, I think you're missing a few
key points and need to reconsider your arguments.
Eduardo Cavazos wrote:
> 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.
>
Even before the code was quite repetitive. I would factor out 'utf8 [ .
] with-file-writer, and also wrap the whole thing in a ".."
with-directory so that each file name does not begin with "..".
The other problem with this code is that you duplicate the read/write
logic in two places. You have one word which writes this data to files,
and another word which reads them. If you want to add a new piece of
data, that's two places in two vocabs to change. That's too brittle, and
it could be factored better.
Create a global variable holding descriptions of your data -- a file
name, a quotation to generate it -- then write a pair of words which
iterate over this variable, reading and writing the data. Then you won't
even need to put the utf8 [ . ] file-writer in its own word because it
only appears once anyway. Adding a new piece of data (which you'll be
doing soon I imagine, with help-lint and the optimizer report) only
requires changing one thing.
Now you might say that now I'm telling you to make your code a bit more
abstract and factor it some more, and that this would be less pertinent
were it not for the extra parameters floating around. But I don't see
that as a problem. If I was implementing this code I would implement it
as I described above, regardless of whether we have encoding specifiers
or not.
> The code would've worked as is if we had default encodings.
>
See what Dan said:
"When I went through the Factor code base and put in "binary" and
"utf8" markings on opening streams when applicable, here's how often
each encoding was used: utf8 is used 36 times, ascii is used 28 times,
binary is used 29 times, utf16 is used 9 times and latin1 is used 6
times. (This count isn't perfect, though, as it includes the
definitions themselves and some unit tests.)"
So I repeat... What default encodings?
> "out.txt" <file-writer> utf16 set-encoding
>
> Now your stream is immune to the haze of dynamic scope.
>
So by the count above, two-thirds of all stream usages would need a
set-encoding. That doesn't sound like optimizing for the common case.
> One big point of the api I'm proposing is that you aren't forced to change
> your code,
Even if the API didn't force a change of code, someone would still have
needed to go through all existing usages of file streams, and set the
binary encoding where applicable. As you can see from Dan's count above,
that's a non-trivial number.
> 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.
>
I'm not so sure about that. I like thinking. :-)
Someone in the IRC channel compared encodings to static type
declarations; however the key difference is that a compiler could
theoretically ignore declarations and the program would have the same
behavior, but encodings change the meaning of the code. They're not just
there to please some ivory tower academic.
I don't speak for others, but for me...
Factor is a language for writing quality code!
I discourage bad habits from other languages (writing extremely long
functions, complex spaghetti dataflow, explicit resource disposal
instead of exception-safe with-* combinators, not thinking about
character encodings), and I won't make any concessions to people who
want to carry over these bad habits from other languages. People who
want to learn Factor but are accustomed to writing poor code should
either take the time to learn Factor properly, or they can just use Java
and Perl.
I love high level abstraction but I despise the Paul Graham-esque
perversion of the concept where the entire idea of abstraction is
trivialized down to just writing the shortest possible code with the
fewest syntax tokens. That's not my goal and that's not my vision for
where Factor needs to go. I guess you can blame that on my 10 years of
Java :-)
I try to write re-usable, composable, correct code, and more
importantly, I want it to remain correct in the face of future extension
and future re-use (modulo language changes ;-). I dislike fragile code.
I dislike code that breaks when some unstated assumption changes or when
some unrelated part of the codebase breaks. I want to write code that
tells me exactly what it's doing with as little implicit state as
possible, but also avoids redundancy. I don't want code to look like
"English" but I don't want it to be an opaque string of punctuation either.
I don't try to bum out a few tokens here and there as an end goal in
itself. Factor is not brainfuck, Factor is not Arc, and Factor is not
fibonacci monads fizzbizz.
> Sure, I can code my way around all these annoyances.
Or you spend an hour or so at most, and redo builder in the way I
described above. You've spent more time writing these emails than it
would take to refactor builder. :-)
While I might change my mind later -- I've changed my mind on many
issues -- at this point in time I strongly favor Dan's approach to
encodings.
Give the new encoding API a chance. When you start dealing with binary
files, you'll love the efficiency gain of using byte arrays instead of
strings. You can add Unicode window titlebar text support to Factory in
a couple of lines of code. One day you might write a web app that
transparently handles text in Chinese ;-)
Slava
-------------------------------------------------------------------------
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