[darcs-users] ANN: ru 0.1.1 -- CLI for Roundup BTS
Trent W. Buck
trentbuck at gmail.com
Tue Dec 30 02:38:03 UTC 2008
On Mon, Dec 29, 2008 at 02:25:21PM +0200, anatoly techtonik wrote:
> On Mon, Dec 29, 2008 at 2:15 PM, Petr Rockai <me at mornfall.net> wrote:
>>> Having a script to interface with bt written in Python will
>>> increase its adoption and chances for patches.
>>
>> Or in Haskell, given the crowd here. But that's besides the point.
I actually intend to rewrite it in Haskell eventually, but I got
bogged down while grokking Haskell's interface to the dup2(2) system
call. Since then I've been busy with other work.
(Petr, note that this thread is cross-posted to both Darcs and Roundup
user lists. Roundup is writen in Python.)
>> Windows users will be likely more comfortable with the web
>> interface anyway (much more windows-y) and other than that, there's
>> nothing wrong with shell for the task at hand.
Well, the Darcs developers know that shell scripts aren't portable to
Unix-like systems! You'll note I used fgrep instead of grep -F :-)
But I've made no effort to avoid GNUisms, which is why the
announcement contained an "only tested on Debian 5.0" caveat.
> The point is that toolchain for a crossplatform project must be
> crossplatform too.
Sorry, I don't agree that ru needs to be portable because Roundup is
portable. I might agree if ru was part of the Roundup project, but
currently it isn't and I don't expect it to be included in the near
future.
FWIW bash scripts *will* run on Windows; a stand-alone interpreter is
available from http://gnuwin32.sf.net. I think other dependencies for
ru(1) can be provided in a similar way, but I'm not really interested
in supporting Windows. As ESR put it, I'm "scratching my own itch."
> If we'll take Roundup as an example of such project - people would
> expect that these tools will be written in Python to be able to
> update and extend them.
Sorry, but I find Python's design counter-intuitive, confusing and
aggravating. (Attached is a form letter that goes into details. I
won't answer responses to it on-list, because I don't want to start a
flame war.) I don't think it's significantly harder for users to
extend a bash script than a Python script, but YMMV.
> More than that - CLI script in Python can directly use Roundup parts
> to do some tasks and its API can simplify unit testing.
The use case that ru(1) addresses is that of an ordinary user
interacting with a *remote* roundup server. In that case, the roundup
libraries are probably not installed on the user's machine, and I
didn't want the user to have to install them.
-------------- next part --------------
===========
Grumbling
===========
:Author: Trent W. Buck <trentbuck at gmail.com>
:Date: 2008-03-25
I have a bad habit of forming opinions and then forgetting my
rationales. The purpose of this document is to preserve and polish
those rationales, so my vitriolic ranting seem so unjustified.
Python
======
Forcer writes:
I think you can summarize your opinion better with "I prefer nesting
to sequencing, functional to imperative programming, and prefix to
infix expressions"
In descending order of evil:
- Conflates ``LET`` and ``SET``.
- Corollary: attempting to SET a binding which has never been LET
(i.e. its value is still the undefined value) is *not* a syntactic
error, so a class of typographical errors are not caught at read
time. For example misspelling "debugging" when attempting to
enable debugging in a library::
debuging = true
will not fail at read time with the error "debuging not bound in
scope <details>".
- Corollary: I have to remember rules about the extent of scoping
when LET/SETting a binding.
In Scheme and Haskell I can just look for the innermost form that
binds the name in question (i.e. a LAMBDA, LET or similar).
- Artificial distinction between expressions that return zero values
("statements") and expressions that return one value ("expressions").
- Corollary: icky new work-around for most common case, using the
value from if/then/else.
- Corollary: you need an explicit ``return`` statement at the end of
some code blocks (just procedures)?
Forcer writes:
The expression/statement distinction I disagree with. In
Lisp/Scheme, you use nested expressions a lot. Python discourages
nested expressions, preferring to use temporary variables. I guess
you are better off disagreeing with that style of programming more
than with the "artificial distinction" there.
- Methods "belong" to objects, rather than being CLOS-style GFs.
- Corollary: Python is single-dispatch.
- Unlike Erlang, the semantics of re-loading updated modules into a
running system are not well define (ot at least not useful).
Specifically, semantics like
I bind a name x in module M to a new value, then re-load M. Do
other names that refer indirectly to x inherit the new value?
For example, if another module N has a function y that calls x
(which is a function), does y use the new definition of x, or the
old (broken) one?
My understanding is that you can't get y to use the new x without
reloading N as well as M, so most people say "fuck it" and restart
the entire Python system, presumably pickling and un-pickling all
state.
- The semantics of default value for function parameters are broken
for non-functional default values, because they are evaluated once
(at define time) rather than every time the function is applied
(called). For example, this program prints 3 instead of 5::
x = 3
def f (xx = x):
print xx
x = 5
f ()
Forcer writes:
I'm not sure about your default value argument. I
can see both versions, I personally prefer the way
Python does it, but I guess that's a matter of
personal opinion.
I replied:
I have to find a compelling example rather than the current toy
example. It has definitely fucked me before.
- Lambda is crippled; for example its lambda list (i.e. parameter
definition) isn't as powerful as the def (DEFUN) lambda list. This
is probably a corollary of some other point.
::
<forcer> How is lambda crippled?
<twb> I can't remember offhand.
<twb> I wrote the first pass (which you're reading) in only
an hour, entirely from memory (because I couldn't find
my old notes).
<forcer> The only way how lambda is crippled in Python is
that it does not allow statements in the body, only
a single expression.
<forcer> Which you can circumwent by defining an inner
procedure and just using that.
<twb> That's kind of obtuse, though.
<forcer> It's related to the nested vs. sequential
programming thing
<forcer> Lambda is part of that nesting stuff
- Python inherently locks its users (that is, programmers) into the
class-based OO paradigm (or procedural, which doesn't really count).
I simply don't like this paradigm; I find it counter-intuitive and
difficult to understand. For example, the native version of
MAKE-ADDER uses ``yield``. Beta reduction just seems more natural
to me than trying to remember a huge heap of state (FSVO state =
objects).
I've put this point significantly lower than my personal preference,
because (apparently) lots of programmers are filthy deviants who
were raised improperly and thus find OO more "natural" than
FP. (FIXME: vitriol.)
- Mutable bindings are not opt-in.
Mutable bindings essentially mean that you aren't purely functional.
This makes it harder to reason about program correctness. It bloats
the core language, making it harder to teach that core (in its
entirety) to a non-programmer in a one-hour lecture. Finally, I'm
told it prevents some optimizations.
At a compilation unit level (e.g. per module), programmers that wish
to use mutable variables should have to say something like "include
mutable", i.e. opt-in.
I concede that Python's preferred paradigms ? class-based OO and
procedural programming ? pretty much require mutable bindings.
- Unlike Haskell, Python iexprs are not merely syntactic sugar for
whitespace-independent mexprs.
This is mentioned mainly for completeness, since I can accept
Haskell-style iexprs in a syntax-heavy language, although I still
prefer sexprs ? DEFINE-SYNTAX is so much nicer than Template
Haskell.
- Corollary: artificial distinction between infix "operators" and
prefix procedures ("functions"?).
- Current implementations don't optimize much.
- I hate opening a source file and seeing about a third of the lines
consisting of the ``self.x = x`` idiom.
And not a problem with Python itself, but the community:
- Ignorance. I get the impression that the vast majority of the
Python community has no exposure to other languages, or at best only
exposure to paradigmatically similar languages like Java, C++ and
PHP.
Nor do they seem to have any formal CS education. I can't even ask
#python a simple question like "are Python strings immutable?" or
"how do I create a dynamically-scoped binding in Python?" without
being obliged to spend an hour explaining the terminology.
- Arrogance. It is unusual to find a Python user who will admit that
any of the design choices I've mentioned above are annoying, let
alone wrong. Every time it has happened so far, that Python user
has turned out to be an ex-Schemer. By contrast, other language
users seem to be far more open: it would be unusual to find an
elisper who felt it was a good idea to dynamically scope bindings by
default, or a Scheme48 user who liked the FFI design.
More information about the darcs-users
mailing list