Re: What happened tp scipy.stsci?

2012-01-24 Thread Eelco
On Jan 23, 6:54 pm, Wanderer  wrote:
> Back in scipy 0.7 there was a package called stsci that had  function
> scipy.stsci.image.median that created a median image from a stack of
> images. The stsci package is dropped in v0.8. Has this functionality
> been moved to a different package?
>
> Thanks
>
> Apologies if this is a double post. I had problems with google groups.

Perhaps that package has been merged with scipy.ndimage?

Either way, if I understand correctly, what you are trying to do could
be done with numpy.median(imagestack, axis=stackaxis), no?
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: What happened tp scipy.stsci?

2012-01-26 Thread Eelco
On Jan 27, 12:04 am, Wanderer  wrote:
> On Jan 26, 2:56 pm, Wanderer  wrote:
>
> > On Jan 25, 1:12 pm, Wanderer  wrote:
>
> > > I found it it is in the stsci package.
>
> > > On Jan 24, 11:36 am, Eelco  wrote:
>
> > > > Either way, if I understand correctly, what you are trying to do could
> > > > be done with numpy.median(imagestack, axis=stackaxis), no?
>
> > > Yes, I guess so. I didn't realize numpy.median had an axis option.
> > > Thanks. That's one less import.
>
> > Actually numpy.median doesn't work. numpy.median does not accept axis
> > greater than 2.
>
> numpy.median does work. I had to use dstack to create my stacks.

Exactly what _stack function to use always confuses me as well :). I
prefer to use numpy.concatenate(axis=2), which does exactly the same
as dstack, but is much less confusing to me. Especially useful in
keeping hstack and vstack apart. 'horizontal' and 'vertical', what
does that even mean? One could look it up or try to think about it;
but in my opinion its much simpler to directly deal in terms of axis
numbers.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Numeric root-finding in Python

2012-02-12 Thread Eelco
On Feb 12, 7:41 am, Steven D'Aprano  wrote:
> This is only peripherally a Python problem, but in case anyone has any
> good ideas I'm going to ask it.
>
> I have a routine to calculate an approximation of Lambert's W function,
> and then apply a root-finding technique to improve the approximation.
> This mostly works well, but sometimes the root-finder gets stuck in a
> cycle.
>
> Here's my function:
>
> import math
> def improve(x, w, exp=math.exp):
>     """Use Halley's method to improve an estimate of W(x) given
>     an initial estimate w.
>     """
>     try:
>         for i in range(36):  # Max number of iterations.
>             ew = exp(w)
>             a = w*ew - x
>             b = ew*(w + 1)
>             err = -a/b  # Estimate of the error in the current w.
>             if abs(err) <= 1e-16:
>                 break
>             print '%d: w= %r err= %r' % (i, w, err)
>             # Make a better estimate.
>             c = (w + 2)*a/(2*w + 2)
>             delta = a/(b - c)
>             w -= delta
>         else:
>             raise RuntimeError('calculation failed to converge', err)
>     except ZeroDivisionError:
>         assert w == -1
>     return w
>
> Here's an example where improve() converges very quickly:
>
> py> improve(-0.36, -1.222769842388856)
> 0: w= -1.222769842388856 err= -2.9158979924038895e-07
> 1: w= -1.2227701339785069 err= 8.4638038491998997e-16
> -1.222770133978506
>
> That's what I expect: convergence in only a few iterations.
>
> Here's an example where it gets stuck in a cycle, bouncing back and forth
> between two values:
>
> py> improve(-0.36787344117144249, -1.0057222396915309)
> 0: w= -1.0057222396915309 err= 2.6521238905750239e-14
> 1: w= -1.0057222396915044 err= -2.6521238905872001e-14
> 2: w= -1.0057222396915309 err= 2.6521238905750239e-14
> 3: w= -1.0057222396915044 err= -2.6521238905872001e-14
> 4: w= -1.0057222396915309 err= 2.6521238905750239e-14
> 5: w= -1.0057222396915044 err= -2.6521238905872001e-14
> [...]
> 32: w= -1.0057222396915309 err= 2.6521238905750239e-14
> 33: w= -1.0057222396915044 err= -2.6521238905872001e-14
> 34: w= -1.0057222396915309 err= 2.6521238905750239e-14
> 35: w= -1.0057222396915044 err= -2.6521238905872001e-14
> Traceback (most recent call last):
>   File "", line 1, in 
>   File "", line 19, in improve
> RuntimeError: ('calculation failed to converge', -2.6521238905872001e-14)
>
> (The correct value for w is approximately -1.00572223991.)
>
> I know that Newton's method is subject to cycles, but I haven't found any
> discussion about Halley's method and cycles, nor do I know what the best
> approach for breaking them would be. None of the papers on calculating
> the Lambert W function that I have found mentions this.
>
> Does anyone have any advice for solving this?
>
> --
> Steven

Looks like floating point issues to me, rather than something
intrinsic to the iterative algorithm. Surely there is not complex
chaotic behavior to be found in this fairly smooth function in a +/-
1e-14 window. Otoh, there is a lot of floating point significant bit
loss issues to be suspected in the kind of operations you are
performing (exp(x) + something, always a tricky one).

I would start by asking: How accurate is good enough? If its not good
enough, play around the the ordering of your operations, try solving a
transformed problem less sensitive to loss of significance; and begin
by trying different numeric types to see if the problem is sensitive
thereto to begin with.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: functions which take functions

2012-04-10 Thread Eelco
On Apr 10, 3:36 am, Kiuhnm  wrote:
> On 4/10/2012 14:29, Ulrich Eckhardt wrote:
>
> > Am 09.04.2012 20:57, schrieb Kiuhnm:
> >> Do you have some real or realistic (but easy and self-contained)
> >> examples when you had to define a (multi-statement) function and pass it
> >> to another function?
>
> > Take a look at decorators, they not only take non-trivial functions but
> > also return them. That said, I wonder what your intention behind this
> > question is...
>
> > :)
>
> That won't do. A good example is when you pass a function to re.sub, for
> instance.
>
> Kiuhnm

Wont do for what? Seems like a perfect example of function-passing to
me.

If you have such a precise notion of what it is you are looking for,
why even ask?
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: numpy (matrix solver) - python vs. matlab

2012-05-01 Thread Eelco
There is linalg.pinv, which computes a pseudoinverse based on SVD that
works on all matrices, regardless of the rank of the matrix. It merely
approximates A*A.I = I as well as A permits though, rather than being
a true inverse, which may not exist.

Anyway, there are no general answers for this kind of thing. In all
non-textbook problems I can think of, the properties of your matrix
are highly constrained by the problem you are working on; which
additional tests are required to check for corner cases thus depends
on the problem. Often, if you have found an elegant solution to your
problem, no such corner cases exist. In that case, MATLAB is just
wasting your time with its automated checks.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Help needed with nested parsing of file into objects

2012-06-05 Thread Eelco
> thank you both for your replies. Unfortunately it is a pre-existing
> file format imposed by an external system that I can't
> change. Thank you for the code snippet.

Hi Richard,

Despite the fact that it is a preexisting format, it is very close
indeed to valid YAML code.

Writing your own whitespace-aware parser can be a bit of a pain, but
since YAML does this for you, I would argue the cleanest solution
would be to bootstrap that functionality, rather than roll your own
solution, or to resort to hard to maintain regex voodoo.

Here is my solution. As a bonus, it directly constructs a custom
object hierarchy (obviously you would want to expand on this, but the
essentials are there). One caveat: at the moment, the conversion to
YAML relies on the appparent convention that instances never directly
contain other instances, and lists never directly contain lists. This
means all instances are list entries and get a '-' appended, and this
just works. If this is not a general rule, youd have to keep track of
an enclosing scope stack an emit dashes based on that. Anyway, the
idea is there, and I believe it to be one worth looking at.


import yaml

class A(yaml.YAMLObject):
yaml_tag = u'!A'
def __init__(self, **kwargs):
self.__dict__.update(kwargs)
def __repr__(self):
return 'A' + str(self.__dict__)

class B(yaml.YAMLObject):
yaml_tag = u'!B'
def __init__(self, **kwargs):
self.__dict__.update(kwargs)
def __repr__(self):
return 'B' + str(self.__dict__)

class C(yaml.YAMLObject):
yaml_tag = u'!C'
def __init__(self, **kwargs):
self.__dict__.update(kwargs)
def __repr__(self):
return 'C' + str(self.__dict__)

class TestArray(yaml.YAMLObject):
yaml_tag = u'!TestArray'
def __init__(self, **kwargs):
self.__dict__.update(kwargs)
def __repr__(self):
return 'TestArray' + str(self.__dict__)

class myList(yaml.YAMLObject):
yaml_tag = u'!myList'
def __init__(self, **kwargs):
self.__dict__.update(kwargs)
def __repr__(self):
return 'myList' + str(self.__dict__)


data = \
"""
An instance of TestArray
 a=a
 b=b
 c=c
 List of 2 A elements:
  Instance of A element
   a=1
   b=2
   c=3
  Instance of A element
   d=1
   e=2
   f=3
 List of 1 B elements
  Instance of B element
   a=1
   b=2
   c=3
   List of 2 C elements
Instance of C element
 a=1
 b=2
 c=3
Instance of C element
 a=1
 b=2
 c=3
An instance of TestArray
 a=1
 b=2
 c=3
""".strip()

#remove trailing whitespace and seemingly erronous colon in line 5
lines = ['  '+line.rstrip().rstrip(':') for line in data.split('\n')]


def transform(lines):
"""transform text line by line"""
for line in lines:
#regular mapping lines
if line.find('=') > 0:
yield line.replace('=', ': ')
#instance lines
p = line.find('nstance of')
if p > 0:
s = p + 11
e = line[s:].find(' ')
if e == -1: e = len(line[s:])
tag = line[s:s+e]
whitespace= line.partition(line.lstrip())[0]
yield whitespace[:-2]+' -'+ ' !'+tag
#list lines
p = line.find('List of')
if p > 0:
whitespace= line.partition(line.lstrip())[0]
yield whitespace[:-2]+'  '+ 'myList:'

##transformed = (transform( lines))
##for i,t in enumerate(transformed):
##print '{:>3}{}'.format(i,t)

transformed = '\n'.join(transform( lines))
print transformed

res = yaml.load(transformed)
print res
print yaml.dump(res)

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Verbose and flexible args and kwargs syntax

2011-12-12 Thread Eelco
> The modulus is not the result but one of the arguments: when numbers x
> and y are congruent modulo n (stated in terms of the modulo operation:
> x mod n = y mod n), the modulus is n. A word for x mod n is remainder.
>
> I agree about the obscurity of using the percent sign as the operator.
>
> A quick google suggests that your use of 'modulus' is now popular
> among programmers. Past experience in mathematics newsgroups tells me
> that some mathematicians do not accept the existence of any remainder
> operator at all. Honest. (I see them but I cannot understand them.)

You are correct; the thing it computes is the remainder, not the
modulus. Nonetheless, 'x modulus y' is how it is put in natural
language, but I suppose math.remainder would be my preferred place to
put this.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Verbose and flexible args and kwargs syntax

2011-12-12 Thread Eelco

By the way...

Is there any particular reason why some of my replies do not show up
on groups.google, and some of them do not show up on mail.python.org?
Sorry to annoy people with reposting, but im going to be forced to do
some of that until this is cleared up
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Verbose and flexible args and kwargs syntax

2011-12-12 Thread Eelco
> No more, or less, explicit than the difference between "==" and "is".

== may be taken to mean identity comparison; 'equals' can only mean
one
thing. Of course 'formally' these symbols are well defined, but so is
brainf*ck

>  Modulo is hardly an obscure operation. "What's the remainder...?" is a
>  simple question that people learn about in primary school.


So is 'how much wood would a woodchucker chuck if a woodchucker could
chuck wood?'. But how often does that concept turn up in your code?

> And you can blame C for the use of % instead of mod or modulo.

I didnt know one of Python's design goals was backwards compatibility
with C.

>  I can't imagine what sort of Python code you have seen that you consider
>  90% attribute access "typical". I've just run the Python tokenizer over
>  my startup.py file, and I get these results:

Yes, that was a hyperbole; but quite an often used construct, is it
not?

>  If you can supply any function at all, what happens if I write this:


You cannot; only constructors modelling a sequence or a dict, and
only
in that order. Is that rule clear enough?

> I believe that your proposal leads to an over-generalisation "call
> arbitrary functions when handling parameter lists".

I hope the above clears that up. It is as much about calling
functions
as ** is about raising kwargs to the power of.

> I don't believe you
> need this added complication. If you want to your var args as a list,
> call list(args) inside your function.

We dont strictly 'need' any language construct. Real men use
assembler,
right?


>  >  head, tuple(tail) = iterable
>  In Python 3, that is spelled:
>  head, *tail = iterable
>  tail = tuple(tail)

Yes, I know. How is that not a lot more verbose and worse than what I
have proposed in all possible ways?

> head, tail = somestring[0], somestring[1:]

Well yes, splendid; we can do that with lists too since the dawn of
Python. What you are saying here in effect is that you think the
head/tail syntax is superfluous; that youd rather see it eliminated
than
generalized.

> head, tail = next(mygenerator), mygenerator

Which again of course works, but is yet again of entirely different
form
than any of the above solutions, while conceptually doing the same
thing. Certainly, there is room for improved elegance here?
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Verbose and flexible args and kwargs syntax

2011-12-12 Thread Eelco

> > I personally quite like them, but I would like them to be more general.
>
> It already is. The *target can be anywhere in the sequence.

Im not sure if this is a genuine understanding, or trollish
obtuseness.

Yes, the target can be anywhere in the sequence. And yes, the
resulting list can contain objects of any type, so its very flexible
in that regard too.

But to relate it to the topic of this thread: no, the syntax does not
allow one to select the type of the resulting sequence. It always
constructs a list.

Yes, we can cast the list to be whatever we want on the next line, but
the question is whether this language design can be improved upon. The
choice of a list feels arbitrary, adding another line to cast it to
something else would be even more verbose, and whats more, there would
be serious performance implications if one should seek to apply this
pattern to a deque/linkedlist; it would make taking off the head/tail
of the list from a constant to a linear operation.

That is:

>>> head, deque(tail) = somedeque

Is better in every way I can think of (readability, consistence,
performance) than:

>>> head, *tail = somedeque
>>> tail = deque(tail)
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Verbose and flexible args and kwargs syntax

2011-12-12 Thread Eelco
> They recognize modular arithmetic but for some reason insist that
> there is no such _binary operation_. But as I said, I don't understand
> their concern. (Except the related concern about some programming
> languages, not Python, where the remainder does not behave well with
> respect to division.)

They might not be willing to define it, but as soon as we programmers
do, well, we did.

Having studied the contemporary philosophy of mathematics, their
concern is probably that in their minds, mathematics is whatever some
dead guy said it was, and they dont know of any dead guy ever talking
about a modulus operation, so therefore it 'does not exist'.

Whatever you want to call the concept we are talking about, or whether
you care to talk about it at all, it is most certainly a binary
operation, since there are two arguments involved. There is no way
around that.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Verbose and flexible args and kwargs syntax

2011-12-12 Thread Eelco
On Dec 12, 7:09 pm, Ian Kelly  wrote:
> On Mon, Dec 12, 2011 at 5:21 AM, Eelco  wrote:
> > You cannot; only constructors modelling a sequence or a dict, and
> > only
> > in that order. Is that rule clear enough?
>
> The dict constructor can receive either a sequence or a mapping, so if
> I write this:
>
>         def func(a, b, dict(c)):
>
> what will I get?  Probably I would want the equivalent of:
>
>         def func(a, b, **c):
>
> but you seem to be saying that I would actually get the equivalent of this:
>
>         def func(a, b, *c):
>             c = dict(c)
>
> Cheers,
> Ian

Im not sure if I was clear on that, but I dont care what the
constructors accept; I meant to overload on the concept the underlying
type models. Dicts model a mapping, lists/tuples model a sequence. MI
deriving from both these models is illegal anyway, so one can
unambigiously overload on that trait.

The syntax only superficially resembles 'call the dict constructor
with the object passed into kwargs'. What its supposed to mean is
exactly the same as **kwargs, but with added flexibility.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Verbose and flexible args and kwargs syntax

2011-12-12 Thread Eelco
> False.

I stand corrected.

> Or are you saying that only classes specifically derived from list,
> tuple, or dict should be considered, and custom containers that are
> not derived from any of those but implement the correct protocols
> should be excluded?  If so, that sounds less than ideal.

That might be a desirable constraint from an implementational/
performance aspect anyway, but I agree, less than ideal.

Either way, its not hard to add some detail to the semantics to allow
all this. Even this function definition:

def func(Foo(args), Foo(kwargs))

...could even be defined unambigiously by overloading first on base
type, and if that does not uniquely determine the args and kwargs,
fall back on positionality, so that:

def func(Foo(args), dict(kwargs))
def func(list(args), Foo(kwargs))

would be uniquely defined as well.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Verbose and flexible args and kwargs syntax

2011-12-12 Thread Eelco
To get back on topic a little bit, lets get back to the syntax of all
this: I think we all agree that recycling the function call syntax is
less than ideal, since while it works in special contexts like a
function signature, its symmetric counterpart inside a function call
already has the meaning of a function call.

In general, we face the problem of specifying metadata about a
variable, or a limited form of type constraint.

What we want is similar to function annotations in python 3; in line
with that, we could have more general variable annotations. With an
important conceptual distinction; function annotations are meaningless
to python, but the annotations I have in mind should modify semantics
directly. However, its still conceptually close enough that we might
want to use the colon syntax here too. To distinguish it from function
annotations, we could use a double colon (double colon is an
annotation with non-void semantics; quite a simple rule); or to
maintain an historic link with the existing packing/unpacking syntax,
we could look at an augmented form of the asteriks notation.

For instance:

def func(list*args, dict*kwargs) <- list-of-args, dict-of-kwargs
def func(args::list, kwargs::dict) <- I like the readability of this
one even better; args-list and kwargs-dict

And:

head, deque*tail = somedeque
head, tail::deque = somedeque

Or some variants thereof
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Verbose and flexible args and kwargs syntax

2011-12-12 Thread Eelco
On Dec 12, 8:05 pm, Eelco  wrote:
> To get back on topic a little bit, lets get back to the syntax of all
> this: I think we all agree that recycling the function call syntax is
> less than ideal, since while it works in special contexts like a
> function signature, its symmetric counterpart inside a function call
> already has the meaning of a function call.
>
> In general, we face the problem of specifying metadata about a
> variable, or a limited form of type constraint.
>
> What we want is similar to function annotations in python 3; in line
> with that, we could have more general variable annotations. With an
> important conceptual distinction; function annotations are meaningless
> to python, but the annotations I have in mind should modify semantics
> directly. However, its still conceptually close enough that we might
> want to use the colon syntax here too. To distinguish it from function
> annotations, we could use a double colon (double colon is an
> annotation with non-void semantics; quite a simple rule); or to
> maintain an historic link with the existing packing/unpacking syntax,
> we could look at an augmented form of the asteriks notation.
>
> For instance:
>
> def func(list*args, dict*kwargs) <- list-of-args, dict-of-kwargs
> def func(args::list, kwargs::dict) <- I like the readability of this
> one even better; args-list and kwargs-dict
>
> And:
>
> head, deque*tail = somedeque
> head, tail::deque = somedeque
>
> Or some variants thereof

As for calling functions; calling a function with the content of a
collection type rather than the collection as an object itself is a
rather weird special case operation I suppose, but we can cover it
with the same syntax:

def func(args::tuple, kwargs::dict):
funccall(args::, kwargs::) <- void type constraint means
unpacking, for symmetry with args/kwargs aggregation
funccall(::args, ::kwargs) <- I like this better, to emphasize it
being 'the other side' of the same coin, and quite close to ** syntax

Sequence and Mapping unpacking dont need their own symbols, if things
are done like this, since in the function declaration the meaning is
clear from the type of the annotations used, plus their position, and
in the call the meaning is clear from the type of the object
undergoing to unpacking operation.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Verbose and flexible args and kwargs syntax

2011-12-12 Thread Eelco
> > Im not sure if this is a genuine understanding, or trollish
> > obtuseness.
>
> If you are referring to what I write, it is based on genuine
> understanding of Python.

This is getting 'interesting'. In a way. I meant to write
'misunderstanding', as I think the context made quite clear. So again
this adds another layer of doubt as to whether you are being obtuse
for its own sake, or if there is yet another layer of misunderstanding
stacked on top of the others. Either way, lets continue with the
benefit of the doubt.

> One use case of *target is to ignore the stuff collected in the target
> because one only wants a few end values from the iterable. Another is to
> pull stuff out because one wants to iterate through the rest. For both
> uses, a list is as good as anything.

So what is the point of having different sequence types, if a list can
do anything? I would argue that the different performance
characteristics and differences in semantics give each sequence type
ample reason for existence.

> Convert. For the very few cases one wants to do this, it is quite adequate.

Or so you opine. As you may recall, the original idea was motivated by
args/kwargs syntactic clarity and flexibility; I merely shifted focus
to this use case of collection unpacking since it is somewhat simpler
and easier to discuss. Keep that in mind, should you seek to build a
case for that assertion in the future.

>  > but the question is whether this language design can be improved upon.
>
> Not easily.

Again, so you opine. Care to give a refutation of my proposed double
colon syntax? Ignoring for a moment whether or not it is useful; does
it clash with anything? I havnt been able to think of anything in the
past few hours, but im not taking that to mean much; there are
probably some subtleties I am overlooking. I think it dos not clash
with slicing syntax for instance, but im not sure.

> For a linked list, no *target and no copying is needed:
>
> head, tail = llist

I have no idea what this means.

>  head, deque(tail) = somedeque
>
> > Is better in every way I can think of (readability, consistence,
> > performance) than:
>  head, *tail = somedeque
>  tail = deque(tail)
>
> But your suggestion is much worse in each way than
>
> head = somedeque.popleft()

No its not. First of all, its not semantically equivalent; popleft
mutates a collection type, and collection unpacking does not; it
creates a set of disjoint views of the collection's data. Whether its
worse in terms of readability is debatable, but in terms of the other
two stated metrics, your claim of it being any kind of worse is
objectively false.

Furthermore, this brings us back again to the point I raised several
times before. Yes, obviously you can already DO these things, but NOT
within the same uniform collection unpacking syntactic construct.
Again, you have failed to point out what is wrong with supplying a
type constrain to python and let it do the right thing based on that;
to reiterate:

head, tail::deque = deque

No need to mutate anything; python can create the view of the
linkedlist internally. A single unambigious syntax, and single
unambigious semantics, for all sequence types. Whats not to like?

If you dont like the extra characters you have to type; there is of
course such a thing as defaults. You can choose:
head, tail:: = deque; if the type constraint is omitted, we could make
tail a list by default, or my preferred solution, infer it from the
right hand side type. In case of the former, all you had to do was
type :: instead of *, and your python universe would otherwise be
completely unchanged. If thats 'not easily', I dont know what is.

> To repeat, there is no reason to copy even once. If one does not want to
> mutate the deque, then one mutates an iterator view of the deque.

And arrive at yet another construction to do the same thing.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Verbose and flexible args and kwargs syntax

2011-12-13 Thread Eelco
On Dec 13, 1:27 am, alex23  wrote:
> On Dec 13, 3:12 am, Eelco  wrote:
>
> > But to relate it to the topic of this thread: no, the syntax does not
> > allow one to select the type of the resulting sequence. It always
> > constructs a list.
>
> So by this argument, _every_ function that returns a list should take
> an optional argument to specify an alternative form of sequence.
>
> What, exactly, is so onerous about coercing your list to _whatever_
> type you want? You know, like everybody else has been.
>
> What does this _gain_ you other than one less line of code?

1) Turning two lines of code into a single more readable one is
nothing to scoff at
2) After-the-fact conversion is O(n), getting the view you want right
away is O(1)

Not every function needs this flexibility; many specialized functions
could not care less. But collection unpacking is quite a general
thing, and for the record; slicing a tuple returns a tuple. Would you
rather have that return a list too?
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Verbose and flexible args and kwargs syntax

2011-12-13 Thread Eelco
On Dec 13, 1:34 am, Ian Kelly  wrote:
> On Mon, Dec 12, 2011 at 11:51 AM, Eelco  wrote:
> > Either way, its not hard to add some detail to the semantics to allow
> > all this. Even this function definition:
>
> > def func(Foo(args), Foo(kwargs))
>
> > ...could even be defined unambigiously by overloading first on base
> > type, and if that does not uniquely determine the args and kwargs,
> > fall back on positionality, so that:
>
> > def func(Foo(args), dict(kwargs))
> > def func(list(args), Foo(kwargs))
>
> > would be uniquely defined as well.
>
> That solves some of the problems, but if I just have:
>
>         def func(SequenceOrMappingType(args)):
>
> That's going to unpack positionally.  If I want it to unpack keywords
> instead, how would I change the definition to indicate that?

That should raise an ambiguity error. But honestly, how often have you
worked with SequenceOrMappingType's? I think this is a rather
palatable constraint.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Verbose and flexible args and kwargs syntax

2011-12-13 Thread Eelco
On Dec 13, 2:41 am, Ian Kelly  wrote:
> On Mon, Dec 12, 2011 at 4:40 PM, Eelco  wrote:
> >> For a linked list, no *target and no copying is needed:
>
> >> head, tail = llist
>
> > I have no idea what this means.
>
> Each node of a linked list consists of a data member and a "next"
> member, that holds the next node in the list.  The natural container
> for this and the way it is usually implemented in Python is a
> 2-element tuple.  For example:
>
> llist = ('one', ('two', ('three', ('four', None
>
> would be a linked list as typically constructed in Python, and it can
> be used in pretty much the same way that lists are used in Lisp.  The
> result of the operation:
>
> head, tail = llist
>
> is:
>
> head = 'one'
> tail = ('two', ('three', ('four', None)))
>
> and as Terry pointed out, no copying is required to do this.  I
> believe deque is also implemented as a doubly-linked list, which is
> probably why you keep referring to it as such, but that is an
> implementation detail.  When you say "linked list" in relation to
> Python, the preceding is what comes to mind.

'for i in llist' is not quite going to fly is it? Thats probably the
reason noone ever uses that construct; its not a proper sequence type.


> >> >>>> head, deque(tail) = somedeque
>
> >> > Is better in every way I can think of (readability, consistence,
> >> > performance) than:
> >> >>>> head, *tail = somedeque
> >> >>>> tail = deque(tail)
>
> >> But your suggestion is much worse in each way than
>
> >> head = somedeque.popleft()
>
> > No its not. First of all, its not semantically equivalent; popleft
> > mutates a collection type, and collection unpacking does not; it
> > creates a set of disjoint views of the collection's data. Whether its
> > worse in terms of readability is debatable, but in terms of the other
> > two stated metrics, your claim of it being any kind of worse is
> > objectively false.
>
> I definitely disagree on readability.  Skimming this thread as I have
> been, it took me a while to get that your proposed syntax would create
> a second deque sharing internal state with the original, rather than
> creating a simple copy of the deque, which is what it looks like it
> should do.

Thats a matter of reading up on the semantics of collection unpacking.
To be honest I dont even know what they are for lists, since I dont
use python 3. But whatever is the case, the important thing is that
the semantics should be uniform regardless of the type to be unpacked.

> Incidentally, while that change is not really central to your syntax
> proposal, I think it would be very messy.  For example, how do you
> propose keeping the length elements in sync?  Inserting an item in one
> may or may not affect the length of the other.  If I append an item to
> the end of one deque, should the other automatically be extended as
> well?  What if the tail node of the second deque occurs after the tail
> node of the deque being appended?  Does the appended element then get
> inserted into the middle of the second deque (I think it would have to
> be)?  If I insert an element into the longer (second) deque that just
> happens to be immediately after the tail of the shorter deque, does
> *that* cause the shorter deque to be automatically extended?  And
> likewise for operations at the head of the deque.
>
> None of these questions have obvious answers as to the "right" way to
> it, and for that reason I think this is probably best left to the user
> to implement a custom deque view class with whatever semantics they
> prefer.

Good point. Copy-on-write semantics could be used, but really one
should have several linked list types reflecting the underlying
implementations. I would like to have an immutable singly linked list
builtin of the standard functional type, which you can only unpack
from one end and renders these issues moot, plus a builtin doubly
linked list with copy-on-write or copy-on-unpacking semantics.

> > Furthermore, this brings us back again to the point I raised several
> > times before. Yes, obviously you can already DO these things, but NOT
> > within the same uniform collection unpacking syntactic construct.
> > Again, you have failed to point out what is wrong with supplying a
> > type constrain to python and let it do the right thing based on that;
> > to reiterate:
>
> > head, tail::deque = deque
>
> Python users generally follow the rule "explicit is better than
> implicit".  Setting a general constraint and letti

Re: Verbose and flexible args and kwargs syntax

2011-12-13 Thread Eelco
On Dec 13, 3:43 am, Steven D'Aprano  wrote:
> On Mon, 12 Dec 2011 04:21:15 -0800, Eelco wrote:
> >> No more, or less, explicit than the difference between "==" and "is".
>
> > == may be taken to mean identity comparison; 'equals' can only mean one
> > thing.
>
> Nonsense. "Equals" can be taken to mean anything the language designer
> chooses, same as "==". There is no language police that enforces The One
> True Meaning Of Equals. In fact, there is no one true meaning of equals.
> Even my tiny Pocket Oxford dictionary lists five definitions.
>
> It is ironic that the example you give, that of identity, is the standard
> definition of equals in mathematics. 2*2 = 4 does not merely say that
> "there is a thing, 2*2, which has the same value as a different thing,
> 4", but that both sides are the same thing. Two times two *is* four. All
> numbers are, in some sense, singletons and equality implies identity.

We are not talking mathemathics, we are talking programming languages.
Identity versus value equality is a well established concept within
its jargon. Within this context, 'equals' and 'is' have clearly
defined meanings. Indeed within broader use, including everyday
language, the distinction is more subtle and therefore less useful,
but obeying a linguistic rule that holds within computer science is
better than making something up just for python, even though its not
the yet better rule that any five year old might grasp.

> > Of course 'formally' these symbols are well defined, but so is
> > brainf*ck
>
> I don't understand your point here.

Hence the above.

> >>  Modulo is hardly an obscure operation. "What's the remainder...?" is a
> >>  simple question that people learn about in primary school.
>
> > So is 'how much wood would a woodchucker chuck if a woodchucker could
> > chuck wood?'. But how often does that concept turn up in your code?
>
> You didn't make a statement about how often modulo turns up in code
> (which is actually quite frequently, and possibly more frequently than
> regular division), but about the obscurity of the operation. Taking the
> remainder is not an obscure operation. The names "modulo" and "modulus"
> may be obscure to those who haven't done a lot of mathematics, but the
> concept of remainder is not. "How many pieces are left over after
> dividing into equal portions" is something which even small children get.

So 'frequency of use' is no valid interpretation of 'obscurity'? Im
not a native speaker, but im pretty sure it is.

> >> And you can blame C for the use of % instead of mod or modulo.
>
> > I didnt know one of Python's design goals was backwards compatibility
> > with C.
>
> Don't be silly. You know full well Python is not backwards compatible
> with C, even if they do share some syntactical features.

Of course I was being silly; I know this use is following a historical
precedent; but id rather see it rectified in the previous version of
python rather than the next. My sillyness was prompted by the
percieved pointlessness of your remark. Of course python is not trying
to be backwards compatible with C; so why bring it up then?

> >>  If you can supply any function at all, what happens if I write this:
>
> > You cannot; only constructors modelling a sequence or a dict, and only
> > in that order. Is that rule clear enough?
>
> But why limit yourself to those restrictive rules?
>
> If I want to collect a sequence of arguments into a string, why shouldn't
> I be allowed to write this?
>
>     def func(parg, str(args)): ...
>
> If I want to sum a collection of arguments, why not write this?
>
>     def func(pargs, sum(args)): ...
>
> Isn't that better than this?
>
>     def func(pargs, *args):
>         args = sum(args)
>         ...
>
> But no. I don't mean those examples to be taken seriously: when you
> answer to your own satisfaction why they are bad ideas, you may be closer
> to understanding why I believe your idea is also a bad idea.

They are bad ideas because they truely do not lead to the execution of
different code, but are merely a reordering, mixing statements in with
a function declaration. I am proposing no such thing; again, the
type(arg) notation I have dropped, and never was meant to have
anything to do with function calling; it is a way of supplying an
optional type constraint, so in analogy with function annotations, I
changed that to arg::type. Again, this has nothing to do with calling
functions on arguments.

First off, type constraints must have some use; all those languages
cant 

Re: Verbose and flexible args and kwargs syntax

2011-12-13 Thread Eelco
> > Python users generally follow the rule "explicit is better than
> > implicit".  Setting a general constraint and letting the language "do
> > the right thing" is a kind of black magic that feels off because it
> > tends to break that rule.  But that's not to say that black magic
> > never wins -- just look at super() and the MRO.
>
> We are not talking black magic here; we are talking about an EXPLICIT
> type constraint provided on the very same line.

To hammer that point home: would you say the following C# code
performs 'black magic'?

float x = 3;

After all, exactly the same thing is going on; C# will 'do the right
thing'; convert the integer literal 3 to a floating point value, based
on the type constraint placed on x.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Verbose and flexible args and kwargs syntax

2011-12-13 Thread Eelco
> To answer that question: for the same reasons. The conversion is
> wasteful; allowing python to do the right thing based on a
> typeconstraint is not. Plus, it is less code, and more readable code;
> the only rule you have to learn is quite general, which is that :: is
> a type constraint annotation; no need to remember specifics, like
> 'unpacking always returns lists for some arbitrary reason'.

Oh my bad; actually, that should be:

'collecting the remainder of an unpacked iterable using * will always
yield a list. That is, unless the construct appears inside a function
definition; then somehow a tuple is always the right choice'
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Verbose and flexible args and kwargs syntax

2011-12-13 Thread Eelco
On 13 dec, 11:15, Arnaud Delobelle  wrote:
> On 13 December 2011 09:50, Eelco  wrote:
>
> >> To answer that question: for the same reasons. The conversion is
> >> wasteful; allowing python to do the right thing based on a
> >> typeconstraint is not. Plus, it is less code, and more readable code;
> >> the only rule you have to learn is quite general, which is that :: is
> >> a type constraint annotation; no need to remember specifics, like
> >> 'unpacking always returns lists for some arbitrary reason'.
>
> > Oh my bad; actually, that should be:
>
> > 'collecting the remainder of an unpacked iterable using * will always
> > yield a list. That is, unless the construct appears inside a function
> > definition; then somehow a tuple is always the right choice'
>
> When you quote somebody (even yourself), it would be helpful if you
> attributed your quote.
>
> --
> Arnaud

Ah yes; im more used to proper forums, still getting used to these
mailing-list things. But point taken.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Verbose and flexible args and kwargs syntax

2011-12-13 Thread Eelco
With all this being said, I must say that the notion of indtroducing
type constraints into Python is quite a radical one*, and one that
should not be taken lightly, so I understand the general conservative
vibe the notion is getting. It probably has implications beyond just
collection types, and if youd introduce such a feature, you would like
to introduce it only once, and correctly the first time around.

Ill probably start a new thread soon, recapping the accumulated
insight, and capping all the OT threads that have spawned.

*even though the asteriks syntax is infact a limited form of exactly
that
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Verbose and flexible args and kwargs syntax

2011-12-13 Thread Eelco
On 13 dec, 12:28, Steven D'Aprano  wrote:
> On Tue, 13 Dec 2011 02:46:13 -0800, Eelco wrote:
> > With all this being said, I must say that the notion of indtroducing
> > type constraints into Python is quite a radical one*,
>
> Not that radical. Here's the creator of Python musing about adding
> optional type checks to Python:
>
> http://www.artima.com/weblogs/viewpost.jsp?thread=85551http://www.artima.com/weblogs/viewpost.jsp?thread=86641http://www.artima.com/weblogs/viewpost.jsp?thread=87182

Good find; but still radical enough that it hasnt been implemented.
Note that these musing are trying to adress a yet far more general
problem of specifying arbitrary types constraints on anything; I am
primarily interested in specifying container types in the special case
of collection packing/unpacking syntax, with further extensions
nothing but a welcome addon. The fact that the former was judged
infeasible does not mean the more modest goal of the latter might not
be attainable.


> > *even though the asteriks syntax is infact a limited form of exactly
> > that
>
> It absolutely is not. def f(*args, **kwargs) constructs a tuple and a
> dict, it does not type-check that the function is passed a tuple and a
> dict as arguments. These are completely different things.

Which is of course not something I ever proposed; I never said
anything about checking types of existing data; im talking about
coercing types of newly created data, like the target of a collection
packing. That is exactly what *args and **kwargs also do.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Verbose and flexible args and kwargs syntax

2011-12-13 Thread Eelco
On 13 dec, 12:13, Steven D'Aprano  wrote:
> On Tue, 13 Dec 2011 01:15:46 -0800, Eelco wrote:
> > On Dec 13, 3:43 am, Steven D'Aprano  > +comp.lang.pyt...@pearwood.info> wrote:
> >> On Mon, 12 Dec 2011 04:21:15 -0800, Eelco wrote:
> >> >> No more, or less, explicit than the difference between "==" and
> >> >> "is".
>
> >> > == may be taken to mean identity comparison; 'equals' can only mean
> >> > one thing.
> [...]
> > We are not talking mathemathics, we are talking programming languages.
>
> What *I* am talking about is your assertion that there is only one
> possible meaning for "equals" in the context of a programing language.
> This is *simply not correct*.
>
> You don't have to believe me, just look at the facts. It's hard to find
> languages that use the word "equals" (or very close to it) rather than
> equals signs, but here are four languages which do:

That python is not the only language to not get this quite as right as
could be is known to me. But within computer science as a discipline,
equality and identity comparisons have a clear enough meaning. 'is'
has a narrower meaning than 'equals'. '==' has no meaning whatsoever
in computer science.

> Again, all this goes to demonstrate that the language designer is free to
> choose any behaviour they like, and give it any name they like.

Certainly you demonstrated as much. Programming languages are created
by people, and they have a tendency to make mistakes, and to have to
compromise (backwards compatibility, and so on). Thats a seperate
matter from 'what ought to be done', when discussing optimal language
design.

> > So 'frequency of use' is no valid interpretation of 'obscurity'? Im not
> > a native speaker, but im pretty sure it is.
>
> No. Things which are obscure are used in language infrequently, because
> if they were common they would not be obscure. But things which are used
> infrequently are not necessarily obscure.
>
> An example in common language: "Napoleon Bonaparte" does not come up in
> conversation very frequently, but he is not an obscure historical figure.
>
> An example from programming: very few people need to use the
> trigonometric functions sin, cos, tan in their code. But they are not
> obscure functions: most people remember them from school. People who have
> forgotten almost everything about mathematics except basic arithmetic
> probably remember sin, cos and tan. But they never use them.

I dont think its terribly interesting to debate whether the term
obscure applies to trigonometric functions or not: the important
matter is that they are where they should be; under math.cos, etc.
They dont have their own special character, and I hope you agree that
is as it should be.

I use trig far more often than modulus, so that argues in favor of
modulus being under math too; infact I used modulus quite recently,
but naturally it was in a piece of code that should be done in C
eventually anyway (evaluating subdivision surfaces)

> Because you asked why Python uses the % operator for remainder.

So you ARE implying python has backwards compatibility with C as a
design goal? Otherwise the given answer to this question is
nonsensical.

>
> [...]
>
> > They are bad ideas because they truely do not lead to the execution of
> > different code, but are merely a reordering, mixing statements in with a
> > function declaration. I am proposing no such thing; again, the type(arg)
> > notation I have dropped, and never was meant to have anything to do with
> > function calling; it is a way of supplying an optional type constraint,
> > so in analogy with function annotations, I changed that to arg::type.
> > Again, this has nothing to do with calling functions on arguments.
>
> You have not thought about this carefully enough. Consider what happens
> when this code gets called:
>
> def f(*args): pass
>
> f(a, b, c)
>
> The Python virtual machine (interpreter, if you prefer) must take three
> arguments a, b, c and create a tuple from them. This must happen at
> runtime, because the value of the objects is not known at compile time.
> So at some point between f(a, b, c) being called and the body of f being
> entered, a tuple must be created, and the values of a, b, c must be
> collated into a single tuple.
>
> Now extend this reasoning to your proposal:
>
> def f(args:FOO): pass
>
> At runtime, the supplied arguments must be collated into a FOO, whatever
> FOO happens to be. Hence, the function that creates FOO objects must be
> called before the body of f can be entered. This doesn't happen for free.
> Whethe

Re: Verbose and flexible args and kwargs syntax

2011-12-13 Thread Eelco
On 13 dec, 14:14, Chris Angelico  wrote:
> On Tue, Dec 13, 2011 at 11:47 PM, Eelco  wrote:
> >> def f(*args) *constructs* a tuple, it
> >> doesn't perform a type-check.
>
> > I am talking about type constraints... A type-check is something
> > along the lines of type(args)==list, a runtime thing and something
> > completely different. I havnt mentioned the latter at all, explicitly
> > or implicitly, as far as im aware.
>
> I'm not sure what you mean by a "type constraint". Here's how I understand 
> such:
>
> float|int foobar; //Declare that the variable 'foobar' is allowed to
> hold a float or an int
> foobar = 3.2; //Legal.
> foobar = 1<<200; //Also legal (a rather large integer value)
> foobar = "hello"; //Not legal
>
> Python doesn't have any such thing (at least, not in-built).

Agreed on what a type constraint is, and that python does not really
have any, unless one counts the current use of asterikses, which are
infact a limited form of type constrait (*tail is not just any object,
but one holding a list, which modifies the semantics of the assignment
statement 'head,*tail=sequence' from a regular tuple unpacking to a
specific form of the more general collection unpacking syntax);

The idea is to enrich this syntax; to add optional and limited type
constraints to python, specifically to enrich collection packing/
unpacking syntax, but perhaps the concept can be further generalized.


> So suppose you can have a user-defined object type instead of
> list/dict. How are you going to write that type's __init__ function?
> Somewhere along the way, you need to take a variable number of
> arguments and bundle them up into a single one... so somewhere, you
> need the interpreter to build it for you. This is going to end up
> exactly the same as just accepting the tuple and then passing that to
> a constructor, like the list example. Keep things transparent and you
> make debugging a LOT easier.

Agreed; for user defined collection types there would not be a
performance benefit over converting a tuple, since this is exactly
what will happen anyway, but for collection types derived from any of
the builtins, python could optimize away the intermediate and
construct the desired collection type directly from the available
information.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Verbose and flexible args and kwargs syntax

2011-12-13 Thread Eelco
On Dec 13, 8:11 pm, Cameron Simpson  wrote:
> On 13Dec2011 00:30, Eelco  wrote:
> | On Dec 13, 1:27 am, alex23  wrote:
> | > On Dec 13, 3:12 am, Eelco  wrote:
> | > > But to relate it to the topic of this thread: no, the syntax does not
> | > > allow one to select the type of the resulting sequence. It always
> | > > constructs a list.
> | >
> | > So by this argument, _every_ function that returns a list should take
> | > an optional argument to specify an alternative form of sequence.
> | >
> | > What, exactly, is so onerous about coercing your list to _whatever_
> | > type you want? You know, like everybody else has been.
> | >
> | > What does this _gain_ you other than one less line of code?
> |
> | 1) Turning two lines of code into a single more readable one is
> | nothing to scoff at
> | 2) After-the-fact conversion is O(n), getting the view you want right
> | away is O(1)
>
> Regarding (2), it has already cost you O(n) to get there. So your O(1)
> is a little ingenuous.

Well, yes, but if one takes a given sequence as input (at least O(n)
complexity to obtain it in the first place, indeed), and then wants
to, say, recursively unwind it, the cost of the total operation is
O(n) versus O(n^2)

And besides, O(n) < 2*O(n); perhaps of lesser concern than different
orders, but still.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Verbose and flexible args and kwargs syntax

2011-12-13 Thread Eelco
On Dec 13, 7:15 pm, Ian Kelly  wrote:
> On Tue, Dec 13, 2011 at 1:44 AM, Eelco  wrote:
> > 'for i in llist' is not quite going to fly is it? Thats probably the
> > reason noone ever uses that construct; its not a proper sequence type.
>
> Not really a problem, because fortunately Python makes it super-easy
> to create custom iterators.
>
> def listiter(llist):
>     while llist:
>         head, llist = llist
>         yield head
>
> And you're done.  If you like, you could also wrap this up in a class
> with all the sequence-related magic methods you want, although you
> lose the simplicity of the literal syntax by doing so.  If this is
> rarely used, it is more likely because custom containers are going to
> be less efficient than built-ins, but if you want to do functional
> programming and are not overly concerned with the speed of iteration,
> this is not a bad way to do it.

Fair enough. Still, I dont readily see myself using the construct, and
I do feel myself longing for something like that to be included as a
builtin collection type. Im not sure why python is so stingy with the
collections it provides.

> > Good point. Copy-on-write semantics could be used, but really one
> > should have several linked list types reflecting the underlying
> > implementations. I would like to have an immutable singly linked list
> > builtin of the standard functional type, which you can only unpack
> > from one end and renders these issues moot, plus a builtin doubly
> > linked list with copy-on-write or copy-on-unpacking semantics.
>
> Copy-on-write could be implemented with any type.  You don't need a
> doubly linked list for that.

True

> > We are not talking black magic here; we are talking about an EXPLICIT
> > type constraint provided on the very same line.
>
> An explicit type constraint with very different semantics depending on
> what particular type you specify and what particular type you're
> unpacking from, as I had understood it before.  Now you seem to be
> saying that it would always be a copy, but sharing state with
> copy-on-write possible, which is a different situation.

Yes, I think consistent semantics over all sequence types is very
important. Although, returning a view for immutable collections like
tuples and 'functional lists' (for lack of a better term), and always
returning a copy for mutable container types (lists and doubly-linked-
lists / deques) is not so bad either, imo. Just one extra simple rule
that is clear and obvious enough.

> > Well perhaps, but not always knowing the type of your objects at write-
> > time is inherent to weakly typed languages; this happens all the time.
> > Not knowing the type of the sequence to be unpacked is in a sense an
> > asset; I can use this construct in a function, and unpack any sequence
> > type in a manner appropriate for it. About the result of the unpacking
> > I will know just as much as about the input to it; that they are the
> > same type.
>
> Just because the issue is inherent doesn't mean we should contribute
> to it.

How are we contributing to it? If we dont know the type of the RHS, we
dont know the type of the LHS either, but its not like we lost any
information. If we do know the type of the RHS, then we do know the
type of the LHS as well; its conserved.

> Anyway, the more I think about it, that concern is really more of an
> issue for straight copying.  One of my pet peeves is that I prefer
> list(x) for copying sequences rather than the more common x[::].  The
> latter is fine if all I need is an immutable sequence of uncertain
> type to iterate and index over -- but then why did I need to make a
> copy?  Unpacking implies different use cases, though, and maybe a good
> argument can be made for it to match type.

Thanks for the constructive feedback; something to think about.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: % is not an operator [was Re: Verbose and flexible args and kwargs syntax]

2011-12-14 Thread Eelco
On Dec 14, 4:18 am, Steven D'Aprano  wrote:
> > They might not be willing to define it, but as soon as we programmers
> > do, well, we did.
>
> > Having studied the contemporary philosophy of mathematics, their concern
> > is probably that in their minds, mathematics is whatever some dead guy
> > said it was, and they dont know of any dead guy ever talking about a
> > modulus operation, so therefore it 'does not exist'.
>
> You've studied the contemporary philosophy of mathematics huh?
>
> How about studying some actual mathematics before making such absurd
> pronouncements on the psychology of mathematicians?

The philosophy was just a sidehobby to the study of actual
mathematics; and you are right, studying their works is the best way
to get to know them. Speaking from that vantage point, I can say with
certainty that the vast majority of mathematicians do not have a
coherent philosophy, and they adhere to some loosely defined form of
platonism. Indeed that is absurd in a way. Even though you may trust
these people to be perfectly functioning deduction machines, you
really shouldnt expect them to give sensible answers to the question
of which are sensible axioms to adopt. They dont have a reasoned
answer to this, they will by and large defer to authority.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: % is not an operator [was Re: Verbose and flexible args and kwargs syntax]

2011-12-14 Thread Eelco
On 14 dec, 09:56, Jussi Piitulainen  wrote:
> Steven D'Aprano writes:
> > On Mon, 12 Dec 2011 09:29:11 -0800, Eelco wrote:
>
> > [quoting Jussi Piitulainen ]
> > >> They recognize modular arithmetic but for some reason insist that
> > >> there is no such _binary operation_. But as I said, I don't
> > >> understand their concern. (Except the related concern about some
> > >> programming languages, not Python, where the remainder does not
> > >> behave well with respect to division.)
>
> > I've never come across this, and frankly I find it implausible that
> > *actual* mathematicians would say that. Likely you are
> > misunderstanding a technical argument about remainder being a
> > relation rather than a bijunction. The argument would go something
> > like this:
>
> (For 'bijunction', read 'function'.)
>
> I'm not misunderstanding any argument. There was no argument. There
> was a blanket pronouncement that _in mathematics_ mod is not a binary
> operator. I should learn to challenge such pronouncements and ask what
> the problem is. Maybe next time.
>
> But you are right that I don't know how actual mathematicians these
> people are. I'm not a mathematician. I don't know where to draw the
> line.
>
> A Finnish actual mathematician stated a similar prejudice towards mod
> as a binary operator in a Finnish group. I asked him what is wrong
> with Knuth's definition (remainder after flooring division), and I
> think he conceded that it's not wrong. Number theorists just choose to
> work with congruence relations. I have no problem with that.
>
> He had experience with students who confused congruences modulo some
> modulus with a binary operation, and mixed up their notations because
> of that. That is a reason to be suspicious, but it is a confusion on
> the part of the students. Graham, Knuth, Patashnik contrast the two
> concepts explicitly, no confusion there.
>
> And I know that there are many ways to define division and remainder
> so that x div y + x rem y = x. Boute's paper cited in [1] advocates a
> different one and discusses others.
>
> [1] <http://en.wikipedia.org/wiki/Modulo_operation>
>
> But I think the argument "there are several such functions, therefore,
> _in mathematics_, there is no such function" is its own caricature.

Indeed. Obtaining a well defined function is just a matter of picking
a convention and sticking with it.

Arguably, the most elegant thing to do is to define integer division
and remainder as a single operation; which is not only the logical
thing to do mathematically, but might work really well
programmatically too.

The semantics of python dont really allow for this though. One could
have:

d, r = a // b

But it wouldnt work that well in composite expressions; selecting the
right tuple index would be messy and a more verbose form would be
preferred. However, performance-wise its also clearly the best
solution, as one often needs both output arguments and computing them
simultaniously is most efficient.

At least numpy should have something like:
d, r = np.integer_division(a, b)

And something similar in the math module for scalars.


> > "Remainder is not uniquely defined. For example, the division of -42
> > by -5 can be written as either:
>
> >     9*-5 + 3 = -42
> >     8*-5 + -2 = -42
>
> > so the remainder is either 3 or -2. Hence remainder is not a bijection
> > (1:1 function)."
>
> Is someone saying that _division_ is not defined because -42 div -5 is
> somehow both 9 and 8? Hm, yes, I see that someone might. The two
> operations, div and rem, need to be defined together.
>
> (There is no way to make remainder a bijection. You mean it is not a
> function if it is looked at in a particular way.)

Surjection is the word you are looking for

That is, if one buys the philosophy of modernists like bourbaki in
believing there is much to be gained by such pedantry.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: % is not an operator [was Re: Verbose and flexible args and kwargs syntax]

2011-12-14 Thread Eelco
On 14 dec, 12:55, Arnaud Delobelle  wrote:
> On 14 December 2011 07:49, Eelco  wrote:
> > On Dec 14, 4:18 am, Steven D'Aprano  > +comp.lang.pyt...@pearwood.info> wrote:
> >> > They might not be willing to define it, but as soon as we programmers
> >> > do, well, we did.
>
> >> > Having studied the contemporary philosophy of mathematics, their concern
> >> > is probably that in their minds, mathematics is whatever some dead guy
> >> > said it was, and they dont know of any dead guy ever talking about a
> >> > modulus operation, so therefore it 'does not exist'.
>
> >> You've studied the contemporary philosophy of mathematics huh?
>
> >> How about studying some actual mathematics before making such absurd
> >> pronouncements on the psychology of mathematicians?
>
> > The philosophy was just a sidehobby to the study of actual
> > mathematics; and you are right, studying their works is the best way
> > to get to know them. Speaking from that vantage point, I can say with
> > certainty that the vast majority of mathematicians do not have a
> > coherent philosophy, and they adhere to some loosely defined form of
> > platonism. Indeed that is absurd in a way. Even though you may trust
> > these people to be perfectly functioning deduction machines, you
> > really shouldnt expect them to give sensible answers to the question
> > of which are sensible axioms to adopt. They dont have a reasoned
> > answer to this, they will by and large defer to authority.
>
> Please come down from your vantage point for a few moments and
> consider how insulting your remarks are to people who have devoted
> most of their intellectual energy to the study of mathematics.  So
> you've studied a bit of mathematics and a bit of philosophy?  Good
> start, keep working at it.

Thanks, I intend to.

> You think that every mathematician should be preoccupied with what
> axioms to adopt, and why?

Of course I dont. If you wish to restrict your attention to the
exploration of the consequences of axioms others throw at you, that is
a perfectly fine specialization. Most mathematicians do exactly that,
and thats fine. But that puts them in about as ill a position to
judged what is, or shouldnt be defined, as the average plumber.
Compounding the problem is not just that they do not wish to concern
themselves with the inductive aspect of mathematics, they would like
to pretend it does not exist at all. For instance, if you point out to
them a 19th century mathematician used very different axioms than a
20th century one, (and point out they were both fine mathematicians
that attained results universally celebrated), they will typically
respond emotionally; get angry or at least annoyed. According to their
pseudo-Platonist philosophy, mathematics should not have an inductive
side, axioms are set in stone and not a human affair, and the way they
answer the question as to where knowledge about the 'correct'
mathematical axioms comes from is by an implicit or explicit appeal to
authority. They dont explain how it is that they can see 'beyond the
platonic cave' to find the 'real underlying truth', they quietly
assume somebody else has figured it out in the past, and leave it at
that.

> You say that mathematicians defer to authority, but do you really
> think that thousands of years of evolution and refinement in
> mathematics are to be discarded lightly?  I think not.  It's good to
> have original ideas, to pursue them and to believe in them, but it
> would be foolish to think that they are superior to knowledge which
> has been accumulated over so many generations.

For what its worth; insofar as my views can be pidgeonholed, im with
the classicists (pre-20th century), which indeed has a long history.
Modernists in turn discard large swaths of that. Note that its largely
an academic debate though; everybody agrees that 1+1=2. But there are
some practical consequences; if I were the designated science-Tsar,
all transfinite-analysist would be out on the street together with the
homeopaths, for instance.

> You claim that mathematicians have a poor understanding of philosophy.
>  It may be so for many of them, but how is this a problem?  I doesn't
> prevent them from having a deep understanding of their field of
> mathematics.  Do philosophers have a good understanding of
> mathematics?

As a rule of thumb: absolutely not, no. I dont think I can think of
any philosopher who turned his attention to mathematics that ever
wrote anything interesting. All the interesting writers had their
boots on mathematical ground; Quine, Brouwer, Weyl and the earlier
renaissance men like Gauss and contemporaries.

The fragmentation of disciplines is infact a major p

Re: % is not an operator [was Re: Verbose and flexible args and kwargs syntax]

2011-12-14 Thread Eelco
On 14 dec, 13:22, Jussi Piitulainen  wrote:
> > > Is someone saying that _division_ is not defined because -42 div
> > > -5 is somehow both 9 and 8? Hm, yes, I see that someone might. The
> > > two operations, div and rem, need to be defined together.
>
> > > (There is no way to make remainder a bijection. You mean it is not
> > > a function if it is looked at in a particular way.)
>
> > Surjection is the word you are looking for
>
> Um, no, I mean function. The allegedly alleged problem is that there
> may be two (or more) different values for f(x,y), which makes f not a
> _function_ (and the notation f(x,y) maybe inappropriate).
>
> Surjectivity is as much beside the point as bijectivity, but I think
> we have surjectivity for rem: Z * Z -> Z if we use a definition that
> produces both positive and negative remainders, or rem: Z * Z -> N if
> we have non-negative remainders (and include 0 in N, which is another
> bone of contention). We may or may not want to exclude 0 as the
> modulus, or divisor if you like. It is at least a special case.
>
> It's injectivity that fails: 9 % 4 == 6 % 5 == 3 % 2, while Python
> quite sensibly has (9, 4) != (6, 5) != (3, 2). (How I love the
> chaining of the comparisons.)

My reply was more to the statement you quoted than to yours; sorry for
the confusion. Yes, we have surjectivity and not injectivity, thats
all I was trying to say.


> > That is, if one buys the philosophy of modernists like bourbaki in
> > believing there is much to be gained by such pedantry.
>
> I think something is gained. Not sure I would call it philosophy.

Agreed; its more the notion that one stands to gain much real
knowledge by writing volumnius books about these matters that irks me,
but I guess thats more a matter of taste than philosophy.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: % is not an operator [was Re: Verbose and flexible args and kwargs syntax]

2011-12-14 Thread Eelco
On Dec 14, 1:38 pm, Steven D'Aprano  wrote:
> On Wed, 14 Dec 2011 02:09:32 -0800, Eelco wrote:
> > Arguably, the most elegant thing to do is to define integer division and
> > remainder as a single operation; which is not only the logical thing to
> > do mathematically, but might work really well programmatically too.
>
> > The semantics of python dont really allow for this though. One could
> > have:
>
> > d, r = a // b
>
> That would be:
>
> >>> divmod(17, 5)
>
> (3, 2)

Cool; if only it were in the math module id be totally happy.


> > But it wouldnt work that well in composite expressions; selecting the
> > right tuple index would be messy and a more verbose form would be
> > preferred. However, performance-wise its also clearly the best solution,
> > as one often needs both output arguments and computing them
> > simultaniously is most efficient.
>
> Premature optimization.

We are talking language design here, not language use. Whether or not
this is premature is a decision that should be left to the user, if at
all possible, which in this case it very well is; just provide
multiple functions to cover all use cases (only return divisor, only
return remainder, or both)
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: % is not an operator [was Re: Verbose and flexible args and kwargs syntax]

2011-12-14 Thread Eelco
'Kindof' off-topic, but what the hell :).

On Dec 14, 5:13 pm, Arnaud Delobelle  wrote:
> On 14 December 2011 12:33, Eelco  wrote:
> > On 14 dec, 12:55, Arnaud Delobelle  wrote:
> >> On 14 December 2011 07:49, Eelco  wrote:
> >> > On Dec 14, 4:18 am, Steven D'Aprano  >> > +comp.lang.pyt...@pearwood.info> wrote:
> >> >> > They might not be willing to define it, but as soon as we programmers
> >> >> > do, well, we did.
>
> >> >> > Having studied the contemporary philosophy of mathematics, their 
> >> >> > concern
> >> >> > is probably that in their minds, mathematics is whatever some dead guy
> >> >> > said it was, and they dont know of any dead guy ever talking about a
> >> >> > modulus operation, so therefore it 'does not exist'.
>
> >> >> You've studied the contemporary philosophy of mathematics huh?
>
> >> >> How about studying some actual mathematics before making such absurd
> >> >> pronouncements on the psychology of mathematicians?
>
> >> > The philosophy was just a sidehobby to the study of actual
> >> > mathematics; and you are right, studying their works is the best way
> >> > to get to know them. Speaking from that vantage point, I can say with
> >> > certainty that the vast majority of mathematicians do not have a
> >> > coherent philosophy, and they adhere to some loosely defined form of
> >> > platonism. Indeed that is absurd in a way. Even though you may trust
> >> > these people to be perfectly functioning deduction machines, you
> >> > really shouldnt expect them to give sensible answers to the question
> >> > of which are sensible axioms to adopt. They dont have a reasoned
> >> > answer to this, they will by and large defer to authority.
>
> >> Please come down from your vantage point for a few moments and
> >> consider how insulting your remarks are to people who have devoted
> >> most of their intellectual energy to the study of mathematics.  So
> >> you've studied a bit of mathematics and a bit of philosophy?  Good
> >> start, keep working at it.
>
> > Thanks, I intend to.
>
> >> You think that every mathematician should be preoccupied with what
> >> axioms to adopt, and why?
>
> > Of course I dont. If you wish to restrict your attention to the
> > exploration of the consequences of axioms others throw at you, that is
> > a perfectly fine specialization. Most mathematicians do exactly that,
> > and thats fine. But that puts them in about as ill a position to
> > judged what is, or shouldnt be defined, as the average plumber.
>
> You are completely mistaken.  Whatever the axiomatisation of the
> mathematics that we do, we can still do the same mathematics.  We
> don't even need an axiomatic basis to do mathematics.  In fact, the
> formalisation of mathematics has always come after the mathematics
> were well established.    Euclid, Dedekind, Peano, Zermelo, Frankael,
> didn't create axiomatic systems out of nothing.  They axiomatised
> pre-existing theories.
>
> Axiomatising a theory is just one way of exploring it.

Yes, axiomization is to some extent a side-show. We know what it is
that we want mathematics to be, and we try to find the axioms that
lead to those conclusions. Not qualitatively different from any other
form of induction (of the epistemological rather than mathematical
kind). Still, different axioms or meta-mathematics give subtly
different results, not to mention are as different to work with as
assembler and haskell. There are no alephs if you start from a
constructive basis, for instance.

Im not sure what 'Axiomatising a theory is just one way of exploring
it' means. One does not axiomatize a single theory; that would be
trivial (A is true because thats what I define A to be). One
constructs a single set of axioms from which a nontrivial set of
theorems follow.

The way id put it, is that axiomazation is about being explicit in
what it is that you assume, trying to minimalize that, and being
systematic about what conclusions that forces you to embrace.

Could you be more precise as to how I am 'completely mistaken'? I
acknowledge that my views are outside the mainstream, so its no news
to me many would think so, but it would be nice to know what im
arguing against in this thread precisely.

> > Compounding the problem is not just that they do not wish to concern
> > themselves with the inductive aspect of mathematics, they would like
> > to pretend it does not exist at all. For instance, if you point out to

Re: % is not an operator [was Re: Verbose and flexible args and kwargs syntax]

2011-12-15 Thread Eelco
On Dec 15, 4:43 am, rusi  wrote:
> On Dec 14, 10:15 pm, Eelco  wrote:
>
> > 'Kindof' off-topic, but what the hell :).
>
> 
> We keep having these debates -- so I wonder how off-topic it is...
> And so do famous 
> CSists:http://research.microsoft.com/en-us/um/people/gurevich/opera/123.pdf
> 

Well, you are right, there are some deep links here. My view of what
is wrong with mainstream mathematics is its strange interpretation of
the semantics of classical logic. (And I dont think any other schools
get it quite right either; I think finitists may avoid the mistakes of
others, but are rightfully accussed of being needlessly restrictive,
for instance)

This is best illustrated by means of the principle of explosion. It
rests on assuming a contradiction, and then assigning rather peculiar
semantics to them. What is typically left unstated are the semantics
of symbol lookup, but apparently it is implicitly understood one can
pick whatever value upon encountering a contradicting symbol. There is
no well defined rule for the lookup of a twice-defined symbol. Of
course the sane thing to do, to a mind grown up around computer
languages, upon encountering a twice defined symbol, is not to
continue to generate deductions from both branches, but to throw an
exception and interrupt the specific line of reasoning that depends on
this contradicting symbol right then and there.

Conceptually, we can see something is wrong with these undefined
semantics right away. A logical system that allows you to draw
conclusions as to where the pope shits from assertions about natural
numbers could not more obviously be broken.

If you dont have this broken way of dealing with contradictions, one
does not have to do one of many silly and arbitrary things to make
infinity work, such as making a choice between one-to-one
correspondence and subset-relations for determining the cardinality of
a set; one can simply admit the concept of infinity, while useful, is
not consistent, keep the contradiction well handled instead of having
it explode in your face (or explode into the field of transfinite
analysis; a consequece of 'dealing' with these issues by rejecting the
intuitively obviously true relation between subset relations and
cardinality), and continue reasoning with the branches of your
argument that you are interested in.

In other words, what logic needs is a better exception-handling
system, which completes the circle with programming languages quite
nicely. :)
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: % is not an operator [was Re: Verbose and flexible args and kwargs syntax]

2011-12-15 Thread Eelco
On Dec 15, 11:47 am, Robert Kern  wrote:
> On 12/14/11 12:32 PM, Steven D'Aprano wrote:
>
> > On Wed, 14 Dec 2011 10:56:02 +0200, Jussi Piitulainen wrote:
> >> I'm not misunderstanding any argument. There was no argument. There was
> >> a blanket pronouncement that _in mathematics_ mod is not a binary
> >> operator. I should learn to challenge such pronouncements and ask what
> >> the problem is. Maybe next time.
>
> > So this was *one* person making that claim?
>
> > I understand that, in general, mathematicians don't have much need for a
> > remainder function in the same way programmers do -- modulo arithmetic is
> > far more important. But there's a world of difference between saying "In
> > mathematics, extracting the remainder is not important enough to be given
> > a special symbol and treated as an operator" and saying "remainder is not
> > a binary operator". The first is reasonable; the second is not.
>
> The professional mathematicians that I know personally don't say that 
> "remainder
> is not a binary operator". They *do* say that "modulo is not an operator" in
> mathematics just because they have reserved that word and the corresponding
> notation to define the congruence relations. So for example, the following two
> statements are equivalent:
>
>    42 = 2 mod 5
>    2 = 42 mod 5
>
> The "mod 5" notation modifies the entire equation (or perhaps the = sign if 
> you
> like to think about it like that), not the term it is immediately next to.
> Python's % operator is a binary operator that binds to a particular term, not
> the whole equation. The following two are not equivalent statements:
>
>    42 == 2 % 5
>    2 == 42 % 5
>
> It's mostly kvetching on their part that programming language designers
> misunderstood the notation and applied the name to something that is 
> confusingly
> almost, but not quite, the same thing. They aren't saying that you couldn't
> *define* such an operator; they would just prefer that we didn't abuse the 
> name.
> But really, it's their fault for using notation that looks like an operator.
>
> --
> Robert Kern
>
> "I have come to believe that the whole world is an enigma, a harmless enigma
>   that is made terrible by our own mad attempt to interpret it as though it 
> had
>   an underlying truth."
>    -- Umberto Eco

Thanks Robert, I think you cut right through the confusion there.

To tie it back in with python language design; all the more reason not
to opt for pseudo-backwards compatibility. If python wants a remainder
function, call it 'remainder'. Not 'rem', not 'mod', and certainly not
'%'. Its the more pythonic way; a self-describing name, rather than
poorly defined or poorly understood cryptology.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: % is not an operator [was Re: Verbose and flexible args and kwargs syntax]

2011-12-15 Thread Eelco
On Dec 15, 11:56 am, rusi  wrote:
> On Dec 15, 2:44 pm, Eelco  wrote:
>
> > In other words, what logic needs is a better exception-handling
> > system, which completes the circle with programming languages quite
> > nicely. :)
>
> Cute... but dangerously recursive (if taken literally)
> Remember that logic is the foundation of programming language
> semantics.
> And your idea (suggests) that programming language semantics be made
> (part of) the foundation of logic.
>
> Of course I assume you are not being very literal.
> Still the dangers of unnoticed circularity are often... well
> unnoticed :-)

Well, logic as a language has semantics, one way or the other. This
circularity is a general theme in epistemology, and one that fits well
with the view of deduction-induction as a closed loop cycle. Knowledge
does not flow from axioms to theorems; axioms without an encompassing
context are meaningless symbols. Its a body of knowledge as a whole
that should be put to the test; the language and the things we express
in it are inseperable. (the not-quite-famous-enough Quine in a
nutshell)

The thing is that our semantics of logic are quite primitive; cooked
up in a time where people spent far less time thinking about these
things, and having a far narrower base of experience to draw ideas
from. They didnt have the luxury of already having grown up studying a
dozen formal languages before embarking on creating their own. It
other words, the semantics of logic is a legacy piece of crap, but an
insanely firmly entrenched one.

I mean, there are many sensible ways of defining semantics of
conflicting symbols, but you'll find on studying these things that the
guys who (often implicitly) laid down these rules didnt even seemed to
have consciously thought about them. Not because they were stupid; far
from it, but for similar reasons as to why the x86 architecture wasnt
concieved of the day after the invention of the transistor.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: % is not an operator [was Re: Verbose and flexible args and kwargs syntax]

2011-12-16 Thread Eelco
On Dec 16, 3:58 am, MRAB  wrote:
> On 16/12/2011 02:14, alex23 wrote:
>
> > Eelco  wrote:
> >> To tie it back in with python language design; all the more reason
> >> not to opt for pseudo-backwards compatibility. If python wants a
> >> remainder function, call it 'remainder'. Not 'rem', not 'mod', and
> >> certainly not '%'.
>
> Python has "def", "del", "int", "str", "len", and so on. "rem" or "mod"
> (Ada has both, I believe) would be in keeping with the language.

def and del are keywords, and thus in another league. Having shorthand
notation for types is somewhat defensible, though I believe I would
prefer a more verbose form there too; how often to you encounter these
in python anyway? len is a bit of an eeysore to me too; I understand
having it as a builtin is a matter of optimization or something, but I
do wish we would be given the option of just saying list.length

> > Good luck with the PEP.
>
> >> Its the more pythonic way; a self-describing name, rather than
> >> poorly defined or poorly understood cryptology.
>
> > "Although practicality beats purity."
>
> > I'm still utterly agog that anyone finds the operator % confusing.
>
> In financial circles it could be an operator for calculating
> percentages, eg. "5 % x" would be 5 percent of x.
>
> It's an oddity, but an established one. :-)

Well yes, thats the only argument ive heard so far that resonated with
me. These syntax details are not a very big deal, and backwards
compatibility with yourself is quite a big deal. Its nice to keep
'what ought to have been done' and 'what ought we to do' seperate in
such discussions. Im not sure we ought to change these syntax details
(I mean relating to mod and such), but I am quite sure of what I would
have done if I could go back in time.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: % is not an operator [was Re: Verbose and flexible args and kwargs syntax]

2011-12-16 Thread Eelco
On Dec 16, 6:30 am, alex23  wrote:
> On Dec 16, 3:01 pm, Chris Angelico  wrote:
>
> > And I would be most sorry to see % renamed to mod in Python.
>
> > "Hello, %s! My favourite number is %d." mod ("Fred",42)   # This just
> > looks wrong.
>
> Finally we can give this operator a more fitting name - I propose
> 'inject' - and put an end to this insane desire to leverage off pre-
> existing knowledge of other languages.
>
> Furthermore, I suggest that no two languages should ever have
> identical semantics, just to avoid potential confusion.
>
> New concepts for all!

Dont get me started on that one. Its that I never work with strings...

'leverage of pre-existing knowledge'... I would hardly call the
particular names of functions the knowledge about a language.

The only argument that bears any weight with me is backwards
compatibility with itself. Pseudo-backwards compatibility with other
languages, I couldnt not care less for.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: % is not an operator [was Re: Verbose and flexible args and kwargs syntax]

2011-12-16 Thread Eelco
On 16 dec, 18:38, rusi  wrote:
> On Dec 16, 3:25 pm, Eelco  wrote:
>
> > Pseudo-backwards compatibility with other
> > languages, I couldnt not care less for.
>
> Double negations n Goedelian situations have interesting implications
> (tho here its triple)

Heh. Well at least my extra (unintended) negation is semantically
consistent with the actual english usage of the phrase, which omits
the negation completely :). (I could care less)

But ill stick with trying to change one language at a time :).
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: % is not an operator [was Re: Verbose and flexible args and kwargs syntax]

2011-12-16 Thread Eelco
On Dec 17, 12:49 am, Gregory Ewing 
wrote:
> Eelco wrote:
> > the actual english usage of the phrase, which omits
> > the negation completely :). (I could care less)
>
> No, that's the American usage. The English usage is
> "I couldn't care less", which has the advantage of
> actually making sense.
>
> --
> Greg

Oh thanks for clearing that up, never noticed a division along these
lines.

And yes, I agree; 'I couldnt care less' makes much more sense. 'I
could care less' can only make sense if you interpret it
sarcastically, as if omitting an 'oh wait, I cant', but that does not
seem congruent with how its typically pronounced. Just another case of
suboptimal language design; but where can you submit EEP's?
-- 
http://mail.python.org/mailman/listinfo/python-list


Pythonification of the asterisk-based collection packing/unpacking syntax

2011-12-17 Thread Eelco

This is a follow-up discussion on my earlier PEP-suggestion. Ive
integrated the insights collected during the previous discussion, and
tried to regroup my arguments for a second round of feedback. Thanks
to everybody who gave useful feedback the last time.

PEP Proposal: Pythonification of the asterisk-based collection packing/
unpacking syntax.

This proposal intends to expand upon the currently existing collection
packing and unpacking syntax. Thereby we mean the following related
python constructs:
head, *tail = somesequence
#pack the remainder of the unpacking of somesequence into a list
called tail
def foo(*args): pass
#pack the unbound positional arguments into a tuple calls args
def foo(**kwargs): pass
#pack the unbound keyword arguments into a dict calls kwargs
foo(*args)
#unpack the sequence args into positional arguments
foo(**kwargs)
#unpack the mapping kwargs into keyword arguments

We suggest that these constructs have the following shortcomings that
could be remedied.
It is unnecessarily cryptic, and out of line with Pythons preference
for an explicit syntax. One can not state in a single line what the
asterisk operator does; this is highly context dependent, and is
devoid of that ‘for line in file’ pythonic obviousness. From the
perspective of a Python outsider, the only hint as to what *args means
is by loose analogy with the C-way of handling variable arguments.
The current syntax, in its terseness, leaves to be desired in terms of
flexibility. While a tuple might be the logical choice to pack
positional arguments in the vast majority of cases, it need not be
true that a list is always the preferred choice to repack an unpacked
sequence, for instance.


Type constraints:

In case the asterisk is not used to signal unpacking, but rather to
signal packing, its semantics is essentially that of a type
constraint. The statement:

head, tail = sequence

Signifies regular unpacking. However, if we add an asterisk, as in:

head, *tail = sequence

We demand that tail not be just any python object, but rather a list.
This changes the semantics from normal unpacking, to unpacking and
then repacking all but the head into a list.

It may be somewhat counter-intuitive to think of this as a type
constraint, since python is after all a weakly-typed language. But the
current usage of askeriskes is an exception to that rule. For those
who are unconvinced, please consider the analogy to the following
simple C# code:

var foo = 3;

An ‘untyped‘ object foo is created (actually, its type will be
inferred from its rhs as an integer).

float foo = 3;

By giving foo a type-constraint of float instead, the semantics are
modified; foo is no longer the integer 3, but gets silently cast to
3.0. This is a simple example, but conceptually entirely analogous to
what happens when one places an asterisk before an lvalue in Python.
It means ‘be a list, and adjust your behavior accordingly’, versus ‘be
a float, and adjust your behavior accordingly’.

The aim of this PEP, is that this type-constraint syntax is expanded
upon. We should be careful here to distinguish with providing optional
type constraints throughout python as a whole; this is not our aim.
This concept has been considered before, but the costs have not been
found to out-weight the benefits. 
http://www.artima.com/weblogs/viewpost.jsp?thread=86641
Our primary aim is the niche of collection packing/unpacking, but if
further generalizations can be made without increasing the cost, those
are most welcome. To reiterate: what is proposed is nothing radical;
merely to replace the asterisk-based type constraints with a more
explicit type constraint.

Currently favored alternative syntax:

Both for the sake of explicitness and flexibility, we consider it
desirable that the name of the collection type is used directly in any
collection packing statement. Annotating a variable declaration with a
collection type name should signal collection packing. This
association between a collection type name and a variable declaration
can be accomplished in many ways; for now, we suggest
collectionname::collectiontype for packing, and ::collectionname for
unpacking.

Examples of use:
head, tail::tuple = ::sequence
def foo(args::list, kwargs::dict): pass
foo(::args, ::kwargs)

The central idea is to replace annotations with asteriskes by
annotations with collection type names, but note that we have opted
for several other minor alterations of the existing syntax that seem
natural given the proposed changes.

First of all, explicitly mentioning the type of the collection
involved eliminates the need to have two symbols, * and **. Which
variable captures the positional arguments and which captures the
keyword arguments can be inferred from the collection type they model,
mapping or sequence. The rare case of collections that both model a
sequence and a mapping can either be excluded or handled by assigning
precedence 

Re: Pythonification of the asterisk-based collection packing/unpacking syntax

2011-12-17 Thread Eelco
On Dec 17, 6:18 pm, Chris Angelico  wrote:
> On Sun, Dec 18, 2011 at 4:14 AM, Roy Smith  wrote:
> > Import wildcarding?
>
> That's not an operator, any more than it is when used in filename
> globbing. The asterisk _character_ has many meanings beyond those of
> the operators * and **.
>
> ChrisA

To cut short this line of discussion; I meant the asterisk symbol
purely in the context of collection packing/unpacking. Of course it
has other uses too.

Even that single use requires a whole paragraph to explain completely;
when does it result in a tuple or a list, when is unpacking implicit
and when not, why * versus **, and so on.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Pythonification of the asterisk-based collection packing/unpacking syntax

2011-12-18 Thread Eelco
On Dec 18, 1:59 am, Steven D'Aprano  wrote:
> On Sat, 17 Dec 2011 06:38:22 -0800, Eelco wrote:
> > Type constraints:
>
> > In case the asterisk is not used to signal unpacking, but rather to
> > signal packing, its semantics is essentially that of a type constraint.
>
> "Type constraint" normally refers to type restrictions on *input*: it is
> a restriction on what types are accepted. When it refers to output, it is
> not normally a restriction, therefore "constraint" is inappropriate.
> Instead it is normally described as a coercion, cast or conversion.
> Automatic type conversions are the opposite of a constraint: it is a
> loosening of restrictions. "I don't have to use a list, I can use any
> sequence or iterator".

Casts or conversions are a runtime concept; im talking about
declarations. That seems to be the source of your confusion.

> In iterator unpacking, it is the *output* which is a list, not a
> restriction on input: in the statement:
>
> head, *tail = sequence
>
> tail may not exist before the assignment, and so describing this as a
> constraint on the type of tail is completely inappropriate.

Yes, the variable tail is being (re)declared here. Thats exactly why I
call it a type constraint. Im not sure what the CS books have to say
on the matter, I guess this use of the term entered my lexicon through
the C# developer team. Either way, you seem to be the only one who
does not grok my intended meaning, so I suggest you try reading it
again.

> > The statement:
>
> >     head, tail = sequence
>
> > Signifies regular unpacking. However, if we add an asterisk, as in:
>
> >     head, *tail = sequence
>
> > We demand that tail not be just any python object, but rather a list.
>
> We don't demand anything, any more than when we say:
>
> for x in range(1, 100):
>
> we "demand" that x is not just any python object, but rather an int.
>
> Rather, we accept what we're given: in case of range and the for loop, we
> are given an int. In the case of extended tuple unpacking, we are given a
> list.

for x in range is syntactic sugar for a series of assignments to x; x
is an unconstrained variable that will indeed take anything it gets;
the semantics of what comes after 'x' does in no way depend on x
itself. head, tail = l and head, *tail = l mean something completely
different, and the only difference is a constraint placed on tail,
which forces the semantics to be different; the righthand side, or
what is to be assigned, is identical. Of course one can just regard it
as syntactic sugar for head, tail = unpackheadandtailaslist(l); but
the syntactic sugar achieves that same end through a type constraint
on tail. Really.

> You are jumping to conclusions about implementation details which aren't
> supported by the visible behaviour. What evidence do you have that
> iterator unpacking creates a tuple first and then converts it to a list?

You are jumping to conclusions about my opinion which aren't supported
by my visible behaviour. What evidence do you have that I ever even
said any such thing?

> > The aim of this PEP, is that this type-constraint syntax is expanded
> > upon. We should be careful here to distinguish with providing optional
> > type constraints throughout python as a whole; this is not our aim.
>
> Iterator unpacking is no more about type constraints than is len().

Because you wish to keep nitpicking about my usage of the term 'type
constraint' (even though you have not introduced an alternative term
yourself), or because you actually disagree with the content of my
message?
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Pythonification of the asterisk-based collection packing/unpacking syntax

2011-12-18 Thread Eelco
On Dec 18, 5:52 am, buck  wrote:
> I like the spirit of this. Let's look at your examples.

Glad to see an actual on-topic reply; thanks.

> > Examples of use:
> >     head, tail::tuple = ::sequence
> >     def foo(args::list, kwargs::dict): pass
> >     foo(::args, ::kwargs)
>
> My initial reaction was "nonono!", but this is simply because of the 
> ugliness. The double-colon is very visually busy.

I would have preferred the single colon, but its taken. But exactly
this syntax is used in other languages (for what that is worth...)

> I find that your second example is inconsistent with the others. If we say 
> that the variable-name is always on the right-hand-side, we get:
>
> >     def foo(list::args, dict::kwargs): pass
>
> This nicely mirrors other languages (such as in your C# example:  "float 
> foo") as well as the old python behavior (prefixing variables with */** to 
> modify the assignment).

The link in my OP has the BDFL discussing type constraints; he also
prefers identifier:type. Many modern languages have something similar.
How is my second example inconsistent?

> As for the separator, let's examine the available ascii punctuation. 
> Excluding valid variable characters, whitespace, and operators, we have:
>
> ! -- ok.
> " -- can't use this. Would look like a string.
> # -- no. Would looks like a comment.
> $ -- ok.
> ' -- no. Would look like a string.
> ( -- no. Would look like a function.
> ) -- no. Would look like ... bad syntax.
> , -- no. Would indicate a separate item in the variable list.
> . -- no. Would look like an attribute.
> : -- ok, maybe. Seems confusing in a colon-terminated statement.
> ; -- no, just no.
> ? -- ok.
> @ -- ok.
> [ -- no. Would look like indexing.
> ] -- no.
> ` -- no. Would look like a string?
> { -- too strange} -- too strange
>
> ~ -- ok.
>
> That leaves these. Which one looks least strange?
>
> float ! x = 1
> float $ x = 1
> float ? x = 1
> float @ x = 1
>
> The last one looks decorator-ish, but maybe that's proper. The implementation 
> of this would be quite decorator-like: take the "normal" value of x, pass it 
> through the indicated function, assign that value back to x.

I dont think thats too proper an analogy. The type constraint does not
just coerce the content that is bound to the variable, it influences
the semantics of the whole statement; so insofar there is a suggested
relation with decorators, id rather not have it.


>
> Try these on for size.
>
>      head, @tuple tail = sequence
>      def foo(@list args, @dict kwargs): pass
>      foo(@args, @kwargs)
>
> For backward compatibility, we could say that the unary * is identical to 
> @list and unary ** is identical to @dict.

Yes, maximum backwards compatibility would be great.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Pythonification of the asterisk-based collection packing/unpacking syntax

2011-12-18 Thread Eelco
On Dec 18, 6:33 am, Evan Driscoll  wrote:
> On 12/17/2011 22:52, buck wrote:> Try these on for size.
>
> >      head, @tuple tail = sequence
> >      def foo(@list args, @dict kwargs): pass
> >      foo(@args, @kwargs)
>
> > For backward compatibility, we could say that the unary * is identical to 
> > @list and unary ** is identical to @dict.
>
> I like this idea much more than the original one. In addition to the
> arguments buck puts forth, which I find compelling, I have one more: you
> go to great length to say "this isn't really type checking in any sense"
> (which is true)... but then you go forth and pick a syntax that looks
> almost exactly like how you name types in many languages! (In fact,
> except for the fact that it's inline, the 'object :: type' syntax is
> *exactly* how you name types in Haskell.)

No, its not type *checking*, its type *declaration*. I tried to go to
great lengths to point that out, but it appears I did not do a very
good job :). Type declaration is exactly what I want, and insofar this
syntax has already found adoptation elsewhere, ill consider that a
plus.

> I have a bigger objection with the general idea, however.It seems very
> strange that you should have to specify types to use it. If the */**
> syntax were removed, that would make the proposed syntax very very
> unusual for Python. I could be missing something, but I can think of any
> other place where you have to name a type except where the type is an
> integral part of what you're trying to do. (I would not say that
> choosing between tuples and lists are an integral part of dealing with
> vararg functions.) If */** were to stick around, I could see 99% of
> users continuing to use them. And then what has the new syntax achieved?

Good point; technically the askeriskes could be kept for backwards
compatibility, but that would break 'there should only be one way to
do it'. Indeed it would be unusual for python to have to explicitly
name a type, but implicitly ** does very much the same. Its just a
cryptic way of saying 'dict please'.

> You can fix this if you don't require the types and just allow the user
> to say "def foo(@args)" and "foo(@args)". Except... that's starting to
> look pretty familiar... (Not to mention if you just omit the type from
> the examples above you need another way to distinguish between args and
> kwargs.)

Yes, one could opt for a syntax where the collection type is optional
and a sensible default is chosen, But to me that would largely defeat
the point; I very much like the added verbosity and explicitness. args-
tuple and kwargs-dict; that just has a much better ring to it than
star-star-kwargs, or whatever other cryptic symbol you use.

> I have one more suggestion.
>
> I do have one more thing to point out, which is that currently the
> Python vararg syntax is very difficult to Google for. In the first pages
> of the four searches matching "python (function)? (star | asterisk)",
> there was just one relevant hit on python.org which wasn't a bug report.
> I certainly remember having a small amount of difficulty figuring out
> what the heck * and ** did the first time I encountered them.
>
> This would suggest perhaps some keywords might be called for instead of
> operators. In the grand scheme of things the argument packing and
> unpacking are not *all* that common, so I don't think the syntactic
> burden would be immense. The bigger issue, of course, would be picking
> good words.
>
> This also helps with the issue above. Let's say we'll use 'varargs' and
> 'kwargs', though the latter too well-ingrained in code to steal. (I
> don't want to get too much into the debate over *what* word to choose.
> Also these don't match the 'head, *tail = l' syntax very well.) Then we
> could say:
>   def foo(varargs l, kwargs d):
>       bar(varargs l, kwargs d)
> and varargs would be equivalent to * and kwargs would be equivalent to
> **. But then you could also say
>   def foo(varargs(list) l, kwargs(dict) d)

I agree; I had the same experience. But according to others our
opinion is wrong, and we should just become better at using google.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Pythonification of the asterisk-based collection packing/unpacking syntax

2011-12-18 Thread Eelco
On 18 dec, 18:03, Steven D'Aprano  wrote:
> On Sun, 18 Dec 2011 06:13:37 -0800, Eelco wrote:
> > Casts or conversions are a runtime concept; im talking about
> > declarations. That seems to be the source of your confusion.
>
> Everything in Python happens at runtime, apart from compilation of source
> code into byte code. Python doesn't have declarations. Even class and def
> are statements which happen at runtime, not declarations which happen at
> compile time.


Of course it will have runtime effects; and compile/interpret-time
effects too. You said as much yourself: 'Everything in Python happens
at runtime, apart from compilation of source'.

Python *does* have declarations. Even though they may not be called
such in the documentation (dunno, havnt checked) the current use of *
and ** when not signifying collectiong UNpacking, is an annotation to
the declaration of the symbol that comes after it. In this case, a
constraint-on / specification-of the type of the object that the
variable symbol may bind; a list or tuple, depending on the context.

> Your proposal will be no different: if it happens, it will happen at
> runtime.

At least something we agree upon; all im proposing is an alternative
syntax for something thats already there. Lets be pragmatic and agree
to disagree on what it is that is already there, or what it ought to
be called. Because frankly, this has detracted enough already from
what it is I do want to discuss.

> [snipped staements of the obvious]
>
> and the second as shown earlier. Clearly they are quite similar: the only
> difference is that in the first case, the right hand side must have
> exactly two items, while in the second case, the right hand side can have
> an arbitrary number of items.

Oh great, you found another semantic hair to split. Yes, they are
quite similar. Nonetheless, any python implementation that would
confuse the two behaviors would be considered badly bugged.


> > and the only difference is a constraint placed on tail, which forces the
> > semantics to be different; the righthand side, or what is to be
> > assigned, is identical. Of course one can just regard it as syntactic
> > sugar for head, tail = unpackheadandtailaslist(l); but the syntactic
> > sugar achieves that same end through a type constraint on tail. Really.
>
> All the words are in English, but I have no understanding of what you are
> trying to say here. What is unpackheadandtailaslist and how does it
> differ from actual unpacking in Python?

I have the impression you are not even trying then. Google 'syntactic
sugar'. It means 'semantically identical way of putting things', in
short. That tells you everything you need to know about
unpackheadandtailaslist: nothing.

> >> You are jumping to conclusions about implementation details which
> >> aren't supported by the visible behaviour. What evidence do you have
> >> that iterator unpacking creates a tuple first and then converts it to a
> >> list?
>
> > You are jumping to conclusions about my opinion which aren't supported
> > by my visible behaviour. What evidence do you have that I ever even said
> > any such thing?
>
> My evidence was your actual words, quoted in my post, which you deleted
> in your response.
>
> Here they are again:
>
>     [quote]
>     This changes the semantics from normal unpacking, to unpacking
>     and then repacking all but the head into a list.
>     [end quote]
>
> In context, "this changes..." refers to extended iterator unpacking in
> the form "head, *tail" contrasted with "head, tail =...", and that it
> generates a list.
>
> It may very well be that I have misunderstood you. If you do not intend
> the meaning that extended tuple unpacking first unpacks to a tuple and
> then re-packs to a list, then please explain what you did mean.

Again, where did I say it first unpacks to a tuple? As far as im aware
that only happens in the context of a function call.

> >> > The aim of this PEP, is that this type-constraint syntax is expanded
> >> > upon. We should be careful here to distinguish with providing
> >> > optional type constraints throughout python as a whole; this is not
> >> > our aim.
>
> >> Iterator unpacking is no more about type constraints than is len().
>
> > Because you wish to keep nitpicking about my usage of the term 'type
> > constraint' (even though you have not introduced an alternative term
> > yourself), or because you actually disagree with the content of my
> > message?
>
> I don't think much about your proposal. I think it is unnecessary, based
> on a profound misunderstanding of how Python actually operates, badly
> explained using inappropriate terms, and the syntax you propose is ugly.

Which is not an aswer to the question I posed; just an expression of
frustration.

Its mutual.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Pythonification of the asterisk-based collection packing/unpacking syntax

2011-12-19 Thread Eelco
On Dec 19, 3:23 am, alex23  wrote:
> Evan Driscoll  wrote:
> > My problem with it is that it in some sense is forcing me to make a
> > decision I don't care about. Yes, what we have now is less flexible, but
> > I have *never* said "man, I wish this *args parameter were a list
> > instead of a tuple".
>
> And if you _did_, then one of the first lines in your function would
> be:
>
>     args = list(args)
>
> Which is obvious to everyone, doesn't modify existing behaviour,
> doesn't force everyone without a fetish for change to add unnecessary
> cruft to their function signature...

Its obvious you end up with a list (assuming args is an iterable);
knowing what args was to begin with suffers from the same problems.

> Except, OMG, list() is RETURNING A LIST, which is an OBVIOUS type
> constraint. I propose that:
>
>     args = @set list(args)
>
> Will coerce args into a list and then give me a set in return.

?
What does that have to do with collection packing/unpacking?
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Pythonification of the asterisk-based collection packing/unpacking syntax

2011-12-19 Thread Eelco
On Dec 19, 1:59 am, Rick Johnson  wrote:
> On Dec 17, 11:33 pm, Evan Driscoll  wrote:
>
> > On 12/17/2011 22:52, buck wrote:> Try these on for size.
>
> > >      head, @tuple tail = sequence
> > >      def foo(@list args, @dict kwargs): pass
> > >      foo(@args, @kwargs)
>
> > > For backward compatibility, we could say that the unary * is identical to 
> > > @list and unary ** is identical to @dict.
>
> > I like this idea much more than the original one.
>
> +1. I will second that! Eelco has the CORRECT idea, but the WRONG
> syntax!

Thanks, your opinion is noted.

Personally im impartial between identifier::collectiontype and
identifier@collectiontype, but that order is something I think is
rather important.

Having two seperate symbols seperated by whitespace, as in @list args
strikes me as a terrible break of normal python lexical rules. Plus,
identifier@collectiontype as a collection-type annotation would be
consistent with the existing general function annotation syntax. Many
non-C-family languages postfix the type declaration.

Also, we want to use the same symbol for collection unpacking as we
use for collection packing. Saying foo(@argslist) really does look a
tad much like a decorator, even though it can be unambigiously
distinguished from it by context.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Python education survey

2011-12-20 Thread Eelco

I taught a Python class just recently, and thought long and hard about
this problem. I settled on PyCharm and was happy with that.

My reasons:
 - available on all main platoforms
 - not entirely broken code completion (ive tried literally every
python editor, and pycharm is the only one that meets this requirement
on all platforms. Try import numpy; numpy.array. 90% of editors with
'code completion' will fail that simple benchmark. The only thing
worse than no completion list is an incomplete list of completions.
Only pyscripter is better in this regard, but win-only.)
 - easy installation
 - integrated console
 - integrated debugger
 - free (for classroom use)
 - fairly uncluttered

> I recently started using PyCharm personally, but not for my courses.
> There's a free OSS developers licence and it's a really nice (although
> young and somewhat resource hungry) IDE, but you can't really advocate a
> non-free IDE for teaching. "Buy me as a teacher, and, BTW, buy this IDE for
> everyone as well or I won't teach you"? Doesn't quite work.

PyCharm provides a free 1 year classroom license.

> For teaching, I think it's better to come around with something simpler
> than a full-blown IDE, so that you can show off interactive development,
> help() and other introspection features. IMHO much better than hiding all
> that behind an IDE, especially behind the additional complexity of an IDE.
> IPython is much better suited to present an interactive language like Python.

PyCharm has an integrated interpreter (a wrapper around Ipython that
superimposes the pycharm based code completion stuff).
Plus, it does not start by default into a clutter-overload mode, and
if you click away a pane or two, you have a rather clean editor.

Aside from worrying about your editor, worry about how to install
python. As a windows user, I had scarcely imagined the nightmares of
installing everything on all platforms, different OS versions, and so
forth. DONT install/compile via the command line, and DO use a
precompiled distro like enthought. Macosx does not come with a C
compiler, and your only recourse is the 4-gig xcode download. That is,
if *friggin ITunes* lets you install it, and does not silently screw
up your installation. I could go on, but anyway you get the point.
Unless its your own computer, anything more complex than double
clicking an installer WILL GO WRONG, and spending hours debugging
other peoples computers is not how you want to spend your time.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Need advice on the design of my application

2011-12-23 Thread Eelco
My first suggestion would be to keep the rendering in Python, if at
all feasible, and do only the actual simulation/computation in C.
Rasterizing a heightfield and rigid body plus some plash effects is
nothing that couldnt be done in PyOpenGL, or even something higher-
level like visvis or mayavi. (visvis would be my first suggestion)

I would run the simulation in a python subprocess that calls into the
C dll; that should give you at least one core fully focussed on your
computations, without competition/blocking from any other modules.

Marshalling the simulation data between subprocesses should be a small
performance hurdle relative to getting it on your GPU; either way, the
python subprocessing module makes it entirely painless.

And I would start with an implementation in numpy; probably, you will
be doing some fft's and/or boundary element stuff. This can all be
done fairly efficiently in numpy; at minimum it will give you a
reference implementation, and its not unlikely it will work well
enough that you dont even want to bother with the C implementation
anymore.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Pythonification of the asterisk-based collection packing/unpacking syntax

2011-12-24 Thread Eelco
On Dec 20, 4:30 am, alex23  wrote:
> On Dec 19, 8:15 pm, Eelco  wrote:
>
> > What does that have to do with collection packing/unpacking?
>
> It's mocking your insistance that collection unpacking is a type
> constraint.

This is really going to be the last time I waste any words on this:

The sentence 'collection unpacking is a type constraint' is entirely
nonsensical. A type constraint is a linguistical construct that can be
applied in many ways; typically, to narrow down the semantics of use
of the symbol to which the type constraint is applied.

In case of python, collection PACKING (not unpacking) is signaled by a
construct that can be viewed as a type constraint. But if you dont
want to fortify your view of the syntax by looking at what it is
actually going on, ill repeat again; lets keep things simple, and not
analyze it in detail.

So here it is again, in terms every 5 year old can understand. Id like
to do the exact same thing python is already doing. Except with a few
more, and different symbols, to enable one to express a few different
variants of behavior. Clear enough?
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Pythonification of the asterisk-based collection packing/unpacking syntax

2011-12-24 Thread Eelco
On Dec 21, 4:48 pm, Neal Becker  wrote:
> Clarification: where can packing/unpacking syntax be used?
>
> It would be great if it were valid essentially anywhere (not limited to
> parameter passing).
>
> What about constructs like:
>
> a, @tuple tail, b = sequence?

This has come up many times in the thread, including in my OP. More
closely unifying collection packing/unpacking is part of my goal, so
indeed, I would like to be able to write something like:

a, middle::tuple, b = ::sequence

Where I would like the extra :: before the sequence to explicitly
signal collection unpacking on the rhs, to maintain the symmetry with
collection unpacking within a function call.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Pythonification of the asterisk-based collection packing/unpacking syntax

2011-12-24 Thread Eelco
On Dec 20, 4:35 am, alex23  wrote:
> Eelco  wrote:
> > Having two seperate symbols seperated by whitespace, as in @list args
> > strikes me as a terrible break of normal python lexical rules.
>
> You mean like 'is not'? And the upcoming 'yield from'?

Im not sure why, but this feels like something entirely different to
me.

I suppose because these are compositions of keywords. Can you give an
example of a whitespaced composition of identifiers being a valid
construct anywhere else in Python?
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Pythonification of the asterisk-based collection packing/unpacking syntax

2011-12-24 Thread Eelco
On Dec 20, 6:47 am, Steven D'Aprano  wrote:
> On Mon, 19 Dec 2011 19:35:20 -0800, alex23 wrote:
> > Eelco  wrote:
> >> Having two seperate symbols seperated by whitespace, as in @list args
> >> strikes me as a terrible break of normal python lexical rules.
>
> > You mean like 'is not'? And the upcoming 'yield from'?
>
> Also "not in".
>
> Space-delimited tokens are hardly rare in Python, e.g.:
>
> import module as name
> for x in sequence
> if flag
> elif condition
> while condition
> with obj
> del name
>
> Nevertheless, I think the suggested syntax "@list args" is awful.
>
> --
> Steven

Can you give an example of a construct in python where two whitespace
delimited identifiers are legal?
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Pythonification of the asterisk-based collection packing/unpacking syntax

2011-12-24 Thread Eelco
On Dec 22, 2:12 pm, Steven D'Aprano  wrote:
> On Thu, 22 Dec 2011 06:49:16 -0500, Neal Becker wrote:
> > I agree with the OP that the current syntax is confusing.  The issue is,
> > the meaning of * is context-dependent.
>
> Here you are complaining about an operator being "confusing" because it
> is context-dependent, in a post where you strip all context except the
> subject line and expect us to still understand what you're talking about.
> There's a lesson there, I'm sure.
>
> * is context dependent. You know what else is context dependent? Well,
> most things. But in particular, parentheses. Clearly they must be
> "confusing" too. So how about we say:
>
> class MyClass superclasslist A, B C:
>     def method argumentlist self, x, y:
>         t = tuple 1, 2 tuple 3, 4 endtuple endtuple
>         return group x + y endgroup * group x - y endgroup
>
> Much less confusing!
>
> --
> Steven

Context dependence is not something to be avoided at all costs, but
all else being equal, less is certainly more. The general concept of
grouping thing together which parenthesis is an extremely pervasive
one in programming, and thus deserves its own set of context-dependent
rules. Packing and unpacking collections is far, far more rare, and
thus a form that requires you to write more but remember less is
certainly relatively favorable.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Pythonification of the asterisk-based collection packing/unpacking syntax

2011-12-24 Thread Eelco
On Dec 24, 3:57 pm, Chris Angelico  wrote:
> On Sun, Dec 25, 2011 at 1:47 AM, Eelco  wrote:
> > a, middle::tuple, b = ::sequence
>
> Then it ought to be
>
> ::(a, middle::tuple, b) = ::sequence
>
> or something, because you're doing the same thing on both sides.
>
> ChrisA

Thats a fair point; something to think about. It all depends on how
you define the rules of course; im trying to stay as close as possible
to the original python rules, where the (un)packing of comma-seperated
identifiers is implicit. Probably best to keep it that way, from the
looks of it :).
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Pythonification of the asterisk-based collection packing/unpacking syntax

2011-12-24 Thread Eelco
On Dec 24, 4:01 pm, Chris Angelico  wrote:
> On Sun, Dec 25, 2011 at 1:45 AM, Eelco  wrote:
> > Can you give an example of a construct in python where two whitespace
> > delimited identifiers are legal?
>
> What do you mean? Two identifiers, separated only by whitespace and no
> keyword or operator?
>
> def foo():
>     asdf
>     qwer
>
> Perfectly legal, two statements that probably don't do anything useful though.
>
> ChrisA

Thats not a fair point, but more nitpicking. Yes, I should have been
more precise: in python, 'whitespace' is not a single beast like in
most languages, but newlines have a special meaning. I was obviously
not talking about those. Want to try again?
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Pythonification of the asterisk-based collection packing/unpacking syntax

2011-12-25 Thread Eelco
On Dec 25, 2:01 am, Rick Johnson  wrote:
> On Dec 24, 6:24 pm, alex23  wrote:
>
> > That you're a condescending douchebag with nothing of value to
> > contribute?
>
> > Crystal.
>
> Take it from me Eelco. Once Alex drops into your thread and starts
> name calling, it's over my friend.

Yes, he has quite worn out my patience; whats over is our (attempts
at) two sided communication, but I hope to continue the constructive
lines of argument in this thread.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Pythonification of the asterisk-based collection packing/unpacking syntax

2011-12-25 Thread Eelco
On Dec 25, 1:45 pm, Steven D'Aprano  wrote:
> On Sat, 24 Dec 2011 06:54:07 -0800, Eelco wrote:
> > Context dependence is not something to be avoided at all costs, but all
> > else being equal, less is certainly more. The general concept of
> > grouping thing together which parenthesis is an extremely pervasive one
> > in programming, and thus deserves its own set of context-dependent
> > rules. Packing and unpacking collections is far, far more rare,
>
> Not in Python, where it is a very common idiom.

I know we are talking about python; it was me that put that in the
title, after all. I know python makes more use of this than some
languages (and less than others; I wouldnt suggest such a verbose
syntax for a functional language for instance). Anyway,  braces are
used at least an order of magnitude more than collection packing/
unpacking in typical code.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Pythonification of the asterisk-based collection packing/unpacking syntax

2011-12-25 Thread Eelco
On Dec 25, 2:12 pm, Steven D'Aprano  wrote:
> On Sat, 24 Dec 2011 06:39:39 -0800, Eelco wrote:
> > On Dec 20, 4:30 am, alex23  wrote:
> >> On Dec 19, 8:15 pm, Eelco  wrote:
>
> >> > What does that have to do with collection packing/unpacking?
>
> >> It's mocking your insistance that collection unpacking is a type
> >> constraint.
>
> > This is really going to be the last time I waste any words on this:
>
> If only that were true, but after sending this post, you immediately
> followed up with FIVE more posts on this subject in less than half an
> hour.

Did I waste any more words on collection packing and type constraints?
No, I did not. (though I am about to, and am willing to do so for
every question that seems genuinely aimed at engaging me on the
matter)

Did I intend to say that I was going to let a single troll shut down
my entire topic? No, I did not.

> > In case of python, collection PACKING (not unpacking) is signaled by a
> > construct that can be viewed as a type constraint.
>
> Only by doing sufficient violence to the concept of type constraint that
> it could mean *anything*.
>
> Earlier, I insisted that a constraint is a rule that applies to input,
> not output. I haven't seen anyone, including yourself, dispute that.
>
> Normally we would say that in the statement:
>
>     y = list(x)
>
> there is a constraint on x, namely that it is some sort of iterable
> object (otherwise an exception will be raised), but it would be an abuse
> of language to say that there is a type constraint on y. y ends up being
> a list, true, but that isn't a constraint on y, it is an outcome.
>
> In normal usage, "constraint" refers to pre-conditions, not post-
> conditions. There are no pre-conditions on y in the above. It may not
> even exist. Contrast it with this example:
>
>     y += list(x)
>
> where there are constraints on y: it must exist, and it must be a list,
> or something which can be added to a list.

Yes, indeed it would be abuse of language to call this a type
constraint, since the fact that y is a list is indeed an outcome of
whatever happens to pop out at the right hand side. One could redefine
the identifier list to return any kind of object.

How is 'head, *tail = sequence' or semantically entirely equivalently,
'head, tail::list = sequence' any different then? Of course after
interpretation/compilation, what it boils down to is that we are
constructing a list and binding it to the identifier tail, but that is
not how it is formulated in python as a language (all talk of types is
meaningless after compilation; machine code is untyped). We dont have
something of the form 'tail = list_tail(sequence)'. Rather, we
annotate the identifier 'tail' with an attribute that unquestionably
destinates it to become a list*. It is no longer that 'tail' will just
take anything that pops out of the expression on the right hand side;
rather, the semantics of what will go on at right hand side is coerced
by the constraint placed on 'tail'.

But again, if you dont wish to view this as a type constraint, I wont
lose any sleep over that. In that case this line of argument was
simply never directed at you. It was directed at people who would
reasonably argue that 'tail::tuple is a type constraint and thats
unpythonic / type constraints have been considered and rejected'. If
you dont think it looks like a type constraint: fine. The simpler
argument is that whatever it is, its just a more verbose and flexible
variant of a construct that python already has.

*(I call that a 'type constraint', because that is what it literally
is; if you can make a case that this term has acquired a different
meaning in practice, and that there is another term in common use for
this kind of construct; please enlighten me. Until that time, im going
to ask you to take 'type constraint' by its literal meaning; a
coercion of the type of a symbol, rather than whatever particular
meaning it has acquired for you (it might help if you explained that).
Im not sure if it was you that brought that up, but let me reiterate
that I dont mean a 'type cast', which is a runtime concept. A 'type
constraint' is purely a linguistic construct that will be 'compiled
out')
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Pythonification of the asterisk-based collection packing/unpacking syntax

2011-12-25 Thread Eelco
On Dec 25, 1:50 pm, Steven D'Aprano  wrote:
> On Sat, 24 Dec 2011 06:45:01 -0800, Eelco wrote:
> > Can you give an example of a construct in python where two whitespace
> > delimited identifiers are legal?
>
> Not apart from the trivial case of two identifiers separated by newlines.
>
> What's your point?

My point is as I originally stated it: that this construct, of two
identifiers seperated by non-newline whitespace, as in 'list tail'
does not occur anywhere else in python, so introducing that syntax,
while i suppose technically possible, would be a break with existing
expectations. Normally speaking, if two identifiers interact, they are
explicitly 'joined' by an infixed operator of some sort, as in 3*4,
rather than * 3 4. That seems a sensible rule to me, and I see no
compelling reason to depart from it.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Pythonification of the asterisk-based collection packing/unpacking syntax

2011-12-25 Thread Eelco
On Dec 25, 2:13 pm, Steven D'Aprano  wrote:
> On Sat, 24 Dec 2011 06:47:21 -0800, Eelco wrote:
> > I would like to be able to write something like:
>
> > a, middle::tuple, b = ::sequence
>
> > Where I would like the extra :: before the sequence to explicitly signal
> > collection unpacking on the rhs, to maintain the symmetry with
> > collection unpacking within a function call.
>
> The :: on the right-hand side is redundant, because the left-hand side
> already explicitly signals collection unpacking of the RHS. Requiring ::
> on the RHS above is as unnecessary as it would be here:

Yes, it is redundant; hence the word 'extra' in my post.

Explicit and implicit are not well-defined terms, but I would say that
at the moment the signal is implicit, in the sense that one cannot see
what is going on by considering the rhs in isolation. Normally in
python, an assignment just binds the rhs to the identifiers on the
lhs, but in case of collection (un)packing, this rule that holds
almost all of the time is broken, and the assignment statement implies
a far more complicated construct, with a far more subtle meaning, and
non-constant time complexity.

Thats not a terrible thing, but a little extra explicitness there
would not hurt, and like I argued many times before, it is a nice
unification with the situation where the unpacking can not be
implicit, like inside a function call rather than assignment.


>     n = len(::sequence)

Now you are just discrediting yourself in terms of having any idea
what you are talking about.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Pythonification of the asterisk-based collection packing/unpacking syntax

2011-12-26 Thread Eelco
On Dec 25, 5:15 pm, Steven D'Aprano  wrote:
> On Sun, 25 Dec 2011 06:55:28 -0800, Eelco wrote:
> > Anyway,  braces are used at
> > least an order of magnitude more than collection packing/ unpacking in
> > typical code.
>
> That's a wild and unjustified claim. Here's a quick and dirty test, using
> the standard library as an example of typical idiomatic code:
>
> [steve@orac ~]$ cd /usr/lib/python2.6
> [steve@orac python2.6]$ grep "[*]args" *.py | wc -l
> 270
> [steve@orac python2.6]$ grep "{" *.py | wc -l
> 550
>
> Doesn't look like a factor of 10 difference to me.

Now try it without changing the subject from round braces to
everything but round braces.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Pythonification of the asterisk-based collection packing/unpacking syntax

2011-12-26 Thread Eelco
On Dec 25, 5:23 pm, Chris Angelico  wrote:
> On Mon, Dec 26, 2011 at 2:38 AM, Eelco  wrote:
> > Until that time, im going
> > to ask you to take 'type constraint' by its literal meaning; a
> > coercion of the type of a symbol, rather than whatever particular
> > meaning it has acquired for you (it might help if you explained that).
> > Im not sure if it was you that brought that up, but let me reiterate
> > that I dont mean a 'type cast', which is a runtime concept. A 'type
> > constraint' is purely a linguistic construct that will be 'compiled
> > out')
>
> The dictionary definition of constraint is "a limitation or
> restriction", and you're right that it can be "compiled out". In fact,
> that is probably the best definition. Assuming everything is written
> correctly, you should be able to eliminate all constraints and the
> code will still function correctly*; but having the constrains means
> that certain illegal operations will throw errors.
>
> Here's two examples of tuple unpacking, one with a type constraint,
> the other without:
>
> a, b = ('hello', [1,2,3] )
> a, b::list = ('hello', [1,2,3] )
>
> The constraint on the second line means that, if the second element is
> not a list, the interpreter should throw an error. It does NOT mean to
> completely change the meaning of the statement to _make_ the last
> argument into a list. That is not the job of a constraint.

Thank you for providing clarification on what a 'type constraint'
means to you. That clears things up a bit.

What you are talking about goes by the name of a 'dynamic type CHECK';
some kind of syntactic sugar for something like
'assert(type(obj)==sometype)'. Like a 'type cast', this is also a
runtime concept. How you manage to confuse that with what I am talking
about, given that ive stated many times I am not talking about a
runtime construct but a compile-time construct, is quite beyond me.
(not to mention that ive quite explicitly stated what I mean by 'type
constraint' many times now).

By contrast, here is the first google hit for 'type constraint'.

http://msdn.microsoft.com/en-us/library/d5x73970.aspx

Note that this is a different application of the concept of a type
constraint, but nonetheless,  the concept is as I stated it: a
constraint to the type of a symbol to modify its compile-time
semantics. To cite from its first paragraph:

"...you can apply restrictions to the kinds of types ... by using a
type that is not allowed by a constraint, the result is a COMPILE-TIME
ERROR" (emphasis mine)
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Pythonification of the asterisk-based collection packing/unpacking syntax

2011-12-26 Thread Eelco
On Dec 25, 6:05 pm, Steven D'Aprano  wrote:
> On Sun, 25 Dec 2011 07:38:17 -0800, Eelco wrote:
> > On Dec 25, 2:12 pm, Steven D'Aprano  > +comp.lang.pyt...@pearwood.info> wrote:
> >> On Sat, 24 Dec 2011 06:39:39 -0800, Eelco wrote:
> >> > On Dec 20, 4:30 am, alex23  wrote:
> >> >> On Dec 19, 8:15 pm, Eelco  wrote:
>
> >> >> > What does that have to do with collection packing/unpacking?
>
> >> >> It's mocking your insistance that collection unpacking is a type
> >> >> constraint.
>
> >> > This is really going to be the last time I waste any words on this:
>
> >> If only that were true, but after sending this post, you immediately
> >> followed up with FIVE more posts on this subject in less than half an
> >> hour.
>
> > Did I waste any more words on collection packing and type constraints?
> > No, I did not. (though I am about to, and am willing to do so for every
> > question that seems genuinely aimed at engaging me on the matter)
>
> > Did I intend to say that I was going to let a single troll shut down my
> > entire topic? No, I did not.
>
> Ah, well whatever you *intended* wasn't clear from your comment. At least
> not clear to *me*.

Always glad to help.

> > Yes, indeed it would be abuse of language to call this a type
> > constraint, since the fact that y is a list is indeed an outcome of
> > whatever happens to pop out at the right hand side. One could redefine
> > the identifier list to return any kind of object.
>
> So far, we agree on this.

Good.

> > How is 'head, *tail = sequence' or semantically entirely equivalently,
> > 'head, tail::list = sequence' any different then? Of course after
> > interpretation/compilation, what it boils down to is that we are
> > constructing a list and binding it to the identifier tail, but that is
> > not how it is formulated in python as a language
>
> I'm afraid it is.
>
> Here's the definition of assignment in Python 
> 3:http://docs.python.org/py3k/reference/simple_stmts.html#assignment-
> statements

Que?

'head, *tail = sequence'

Is how one currently unpacks a head and tail in idiomatic python

This is semantically equivalent to

'head = sequence[0]'
'tail = list(sequence[1:])'

But these forms are linguistically different, in too many different
ways to mention.

> > We dont have
> > something of the form 'tail = list_tail(sequence)'.
>
> I'm afraid we do. See the definition of assignment again.

Que?

My claim is that the two semantically identical formulations above do
not have isomorphic linguistic form. As far as I can make sense of
your words, you seem to be disputing this claim, but its a claim as
much worth debating as that the sun rises in the east.

> > Rather, we annotate
> > the identifier 'tail' with an attribute that unquestionably destinates
> > it to become a list*. It is no longer that 'tail' will just take
> > anything that pops out of the expression on the right hand side;
>
> Of course it will. Python is a dynamically typed language. It doesn't
> suddenly develop static types to ensure that 'tail' becomes a list;
> 'tail' is bound to a list because that's what the assignment statement
> provides.

How python accomplishes any of this under the hood is entirely
immaterial. The form is that of a compile-time type constraint,
regardless of whether the BDFL ever thought about it in these terms.

> > rather,
> > the semantics of what will go on at right hand side is coerced by the
> > constraint placed on 'tail'.
>
> But it isn't a constraint placed on 'tail'. It is a consequence of the
> definition of assignment in Python 3. 'tail' becomes bound to a list
> because that is what the assignment statement is defined to do in that
> circumstance, not because the identifier (symbol) 'tail' is constrained
> to only accept lists. 'tail' may not even exist before hand, so talking
> about constraints on 'tail' is an abuse of language, AS YOU AGREED ABOVE.

'tail' is (re)declared on the spot as a brand-new identifier (type
constraint included); whether it exists before has no significance
whatsoever, since python allows rebinding of identifiers.

> > *(I call that a 'type constraint', because that is what it literally is;
>
> No. It is literally a name binding of a dynamically typed, unconstrained
> name to an object which happens to be a list.

Let me take a step back and reflect on the form of the argument we are
having. I claim the object in f

Re: Pythonification of the asterisk-based collection packing/unpacking syntax

2011-12-26 Thread Eelco
On Dec 26, 10:01 pm, Chris Angelico  wrote:
> On Tue, Dec 27, 2011 at 7:39 AM, Eelco  wrote:
> > Now try it without changing the subject from round braces to
> > everything but round braces.
>
> Around here, the term "braces" means the curly ones - { and } - that
> delimit blocks of code in C, and dictionaries/sets in Python.
> "Brackets" may be what you're looking for, if you mean all of ()[]{}.
> Or if you just mean (), they're called "parentheses".
>
> If your point is that parens are used more often than
> packing/unpacking, that's almost certainly true, since function calls
> (including method invocations) are so prevalent in pretty much any
> code. But what does that prove?

That proves the original point of contention: that the below* is
suboptimal language design, not because terseness always trumps
verbosity, but because commonly-used constructs (such as parenthesis
or round brackets or whatever you wish to call them) are more
deserving of the limited space in both the ascii table and your
reflexive memory, than uncommonly used ones.


*original mock code by steve:

class MyClass superclasslist A, B C:
def method argumentlist self, x, y:
t = tuple 1, 2 tuple 3, 4 endtuple endtuple
return group x + y endgroup * group x - y endgroup
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Pythonification of the asterisk-based collection packing/unpacking syntax

2011-12-26 Thread Eelco
On Dec 26, 10:05 pm, Chris Angelico  wrote:
> On Tue, Dec 27, 2011 at 7:58 AM, Eelco  wrote:
> > What you are talking about goes by the name of a 'dynamic type CHECK';
> > some kind of syntactic sugar for something like
> > 'assert(type(obj)==sometype)'. Like a 'type cast', this is also a
> > runtime concept...
>
> > By contrast, here is the first google hit for 'type constraint'.
>
> >http://msdn.microsoft.com/en-us/library/d5x73970.aspx
>
> > "...you can apply restrictions to the kinds of types ... by using a
> > type that is not allowed by a constraint, the result is a COMPILE-TIME
> > ERROR" (emphasis mine)
>
> A constraint can be applied at compile time or at run time. It'd be
> valid to apply them at edit time, if you so chose - your editor could
> refuse to save your file until you fix the problem. Doesn't mean a
> thing.

A constraint in the sense that I have explained many times now, can in
no way, shape or form be applied at run time. Youd have better luck
applying a consternation to a squirrel. Perhaps you meant 'type check'
again? But then again, that makes no sense whatsoever at compile-
time... Im starting to doubt if there is any sense to be found here at
all.

Anyway, ill take your further silence on the matter as a 'sorry I
derailed your thread with my confusion of terminology'

> Python, by its nature, cannot do compile-time type checking.

Python can do whatever its designers have put into it. In this case,
that includes the emission of different code based on a (type)
annotation at the point of declaration of an identifier (only in the
particular circumstance of collection unpacking though, as far as I am
aware).

> Under no circumstances, however, does this justify the use of the term
> "constraint" to mean "utterly different semantics of the same code".

Thank you for your theory on justice. Im sure its fascinating, but
until you get around to actually explaining it, im going to have to be
conservative and stick with the jargon in common use though, sorry.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Pythonification of the asterisk-based collection packing/unpacking syntax

2011-12-26 Thread Eelco
On Dec 26, 11:27 pm, Chris Angelico  wrote:
> On Tue, Dec 27, 2011 at 8:51 AM, Eelco  wrote:
> > That proves the original point of contention: that [Steve's demo code] is
> > suboptimal language design, not because terseness always trumps
> > verbosity, but because commonly-used constructs (such as parenthesis
> > or round brackets or whatever you wish to call them) are more
> > deserving of the limited space in both the ascii table and your
> > reflexive memory, than uncommonly used ones.
>
> In Magic: The Gathering R&D, they have a term (the article reporting
> which I can't actually find at the moment) called "spread complexity"
> or "fan complexity" - the idea being that as you fan out a booster
> pack, you see a certain amount of complexity in front of you. The
> designers can afford to put more complex cards in as rares than they
> can as commons, because you see ten commons for every rare - so a
> common factors ten times as much as a rare in spread complexity. (Mark
> Rosewater, my apologies if I'm misremembering here!)
>
> The same applies here. When you cast your eye over a program, you're
> going to see certain syntactic elements a lot. Assignment, arithmetic,
> blocks of code (ie indent/dedent), and function calls are all
> extremely common; lambdas, the use of decorators, and exception
> handling are somewhat uncommon; and metaclasses, the writing of
> decorators, and reloading of modules are all quite rare.
>
> The elements that occur frequently should be:
> a) Readable and grokkable;
> b) Easily typed on a regular keyboard - no using ASCII character 126
> to mean negation, tyvm!
> c) Make sense.
>
> Rarer elements (and I'm not talking about xenon and plutonium here)
> are allowed to have long names, obscure syntax, or even be shoved away
> in odd modules (the way module reloading is in Python 3). If 0.1% of
> your code is suddenly twice as large as it used to be, will you
> notice? But if a new syntax adds even 5% to the mindspace requirement
> of basic assignment, your code will majorly suffer.
>
> In summary: Terseness trumps verbosity primarily for common
> operations, and only when doing so does not violate rules a and c
> above.
>
> ChrisA

Good to see there is something we agree upon completely.

Not that I mean to say the question as to how verbose a syntax is
appropriate for collection (un)packing is settled; one could
reasonably argue they find tail::tuple too verbose. But parenthesis
are not a terribly good example to compare to, since they are infact
so much more used they are clearly in another category.

*args and **kwargs are debateable in the appropriateness of their
terseness (but I personally like to err on the side of verbosity), but
extended collection unpacking, as in 'head,*tail=sequence', is quite a
rare construct indeed, and here I very strongly feel a more explicit
syntax is preferrable. That is, as a seasoned python 2 user, I wouldnt
have been willing to gamble on what this does when id come across it
for the first time in python 3. Could as well be a completely new use
of the asterisk. But if collection packing/unpacking would be
presented as a more general construct from the start,
'head,tail::tuple=sequence' would be hard to miss.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Python education survey

2011-12-27 Thread Eelco
On Dec 27, 6:59 am, Carl Smith  wrote:
> On Dec 20, 10:58 am, Andrea Crotti  wrote:
>
>
>
>
>
>
>
>
>
> > On 12/20/2011 03:51 AM, Raymond Hettinger wrote:
>
> > > Do you use IDLE when teaching Python?
> > > If not, what is the tool of choice?
>
> > > Students may not be experienced with the command-line and may be
> > > running Windows, Linux, or Macs.  Ideally, the tool or IDE will be
> > > easy to install and configure (startup directory, path, associated
> > > with a particular version of Python etc).
>
> > > Though an Emacs user myself, I've been teaching with IDLE because it's
> > > free; it runs on multiple OSes, it has tooltips and code colorization
> > > and easy indent/dedent/comment/uncomment commands, it has tab
> > > completion; it allows easy editing at the interactive prompt; it has
> > > an easy run-script command (F5); it has direct access to source code
> > > (File OpenModule) and a class browser (Cntl+B).
>
> > > On the downside, some python distros aren't built with the requisite
> > > Tcl/Tk support; some distros like the Mac OS ship with a broken Tcl/Tk
> > > so users have to install a fix to that as well; and IDLE sometimes
> > > just freezes for no reason.  It also doesn't have an easy way to
> > > specify the startup directory.
>
> > > If your goal is to quickly get new users up and running in Python,
> > > what IDE or editor do you recommend?
>
> > > Raymond
>
> > I think ipython and a good editor gives a much nicer experience
> > than IDLE, which I actually almost never used, and
> > for everything else there is python and python-mode.
>
> > New users however can be pointed to something like PyCharm
> > or Eclipse+PyDev if they are more familiar to IDEs..
>
> I agree; IPython is a excellent choice. You have a much more powerful
> interactive Python experience, with all the features you need from an
> IDE. You can use any editor (VIM) and you can also readily hack
> IPython to death.
>
> I think the fact that anyone with basic programming skills can
> substantially enhance their console is a big winner in CS education.
> It gives students something they personally value to work on, it's a
> place to store all their little bits of code and actually benefit from
> them in real life.
>
> I've never met a programmer that got familiar with IPython and then
> went on to stop using it. It should be included in the standard
> library and used as the default Python interactive environment.
>
> The last line of my .bashrc file:
>
> ipython3

Youve got one here. I like IPython a lot, but it quite rarely enters
into my workflow.

While I agree that a good interactive python console is a good way to
get your feet wet with programming, I also strongly feel that a more
comprehensive programming environment should be introduced to
students. That includes opening and editing files, syntax
highlighting, and code completion. And painless installation. There
are no lightweight editors that provide all this functionality in
conjuction with Ipython*. So I prefer to work the other way around;
use something like pycharm, and open an IPython interactive session
within it.

*Your suggestion of VIM is especially objectionable. Though I am sure
it is a great tool to you, the subject here is beginner education.
Just because it is a good tool for you, does not make it a good tool
for a beginner.

IPython bundled with a lightweight but function-rich and non-hacker-
but-WYSIWYG editor would be a great choice. But until that comes
around, pycharm it is for me.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Pythonification of the asterisk-based collection packing/unpacking syntax

2011-12-27 Thread Eelco
On Dec 27, 1:52 am, Chris Angelico  wrote:
> On Tue, Dec 27, 2011 at 10:44 AM, Eelco  wrote:
> > extended collection unpacking, as in 'head,*tail=sequence', is quite a
> > rare construct indeed, and here I very strongly feel a more explicit
> > syntax is preferrable.
>
> You may be right, but...
>
> > ... if collection packing/unpacking would be
> > presented as a more general construct from the start,
> > 'head,tail::tuple=sequence' would be hard to miss.
>
> ... it doesn't really justify a _change_. When a language is in its
> infancy and the only code written in it is on the designers' own
> computers, these sorts of debates can be tipped by relatively small
> differences - is it more readable, is it quick enough to type, etc.
> But once a language reaches a level of maturity, changes need to
> overwhelm the "but it's a change" hurdle - breaking existing code is
> majorly dangerous, and keeping two distinct ways of doing something
> means you get the worst of both worlds.
>
> We can argue till the cows come home as to which way would be better,
> _had Python started with it_. I don't think there's anything like
> enough difference to justify the breakage/duplication.

That I agree with; I think it is a questionable idea to introduce this
in a new python 3 version. But I consider it a reasonable change for a
'python 4', or whatever the next major version change will be called.
Writing a code-conversion tool to convert from *args to args::tuple
would be quite easy indeed.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Python education survey

2011-12-27 Thread Eelco
On Dec 27, 6:53 pm, Lie Ryan  wrote:
> On 12/27/2011 10:41 PM, Eelco wrote:
>
>
>
> > *Your suggestion of VIM is especially objectionable. Though I am sure
> > it is a great tool to you, the subject here is beginner education.
> > Just because it is a good tool for you, does not make it a good tool
> > for a beginner.
>
> Before using VIM, I used to use gedit (and still do, though not as often
> now); I don't think I've ever had any problem with not using a full
> blown IDE with Python. I generally don't miss not using an IDE since
> Python doesn't have the tradition of using overly verbose names like in
> Java.

As for my personal use, I very much prefer an IDE. I hate having only
crappy code completion, for starters, and I like a good integrated
debugger. But then again, im spoiled I suppose coming from C#. On the
other hand, ive worked for many years using a very minimal notepad
+command line compilation setup as well.

But I can very well imagine that people are perfectly happy with more
hackerish tools. That is, once they have gotten past the learning
curve.

> I'm personally of the opinion that beginners generally should start with
> a simple programmer text editors (gedit is a good example). Firstly, you
> don't want to confuse beginners with IDE vs language features; secondly,
> at the size of the problem beginners typically had, they don't **need**
> 95% of those features; and if you teach beginners powerful IDE features
> too early, by the time their problem gets big enough that the IDE
> features would actually help, they'd already forgotten about them.

A good IDE should get out of your way if you want it to. I like
pycharm in this regard; click an x or two, and you are facing just
your text editor and console/output window.

Generally, I think a non-cluttered IDE is ideal for a beginner. You
dont have to explain to them how to open a file, and if you tell them
to hit the 'play' button to start running their code (not a hard
concept to grasp or remember either) they are good to start hacking.
Also, I think code completion is a blessing to beginning programmers.
IPython is good in that regard; until you switch to editing files,
where your choice is between notepad, or configuring an other editor
you dont want your class to spend any time on, and youll end up with
something that still doesnt do much more than syntax highlighting.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Python education survey

2011-12-27 Thread Eelco
On Dec 27, 9:04 pm, Rick Johnson  wrote:
> On Dec 27, 1:45 pm, Eelco  wrote:
>
> > On Dec 27, 6:53 pm, Lie Ryan  wrote:
> > > On 12/27/2011 10:41 PM, Eelco wrote:
> > > Before using VIM, I used to use gedit
>
> Eelco, please don't get offended, but can you (and everyone else) stop
> using silly verbage like "used to", "use to", "suppose to", "hard"
> when you "difficult", and "pretty" when you mean "very". I find this
> verbiage to be quite ridiculous. In this case you could have simply
> said...
>
> """Before using VIM, I USED gedit."""
>
> or if you want to stress that you don't use gedit anymore you could
> say...
>
> """ Previously i used gedit, but have since moved on to VIM."""
>
> Thanks

Despite the fact that you mis-attributed that quote to me, im going to
be a little bit offended in the name of its actual author anyway.
Thats a lot of words to waste on your linguistic preferences.
Personally, I reserve the right to botch my non-native languages as
much as I please.

> > You
> > dont have to explain to them how to open a file, and if you tell them
> > to hit the 'play' button to start running their code (not a hard
> > concept to grasp or remember either) they are good to start hacking.
>
> I always though "run" was a perfect verb for "running" code... but who
> knows :)

Im assuming the audience is familiar with an ipod, but not an IDE, or
programming in general. To their eyes, it looks like a 'play' button;
but yes, 'running' is what its called in my mind.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Pythonification of the asterisk-based collection packing/unpacking syntax

2011-12-28 Thread Eelco
On Dec 27, 11:57 pm, Steven D'Aprano  wrote:
> On Mon, 26 Dec 2011 13:41:34 -0800, Eelco wrote:
> > On Dec 25, 6:05 pm, Steven D'Aprano  > +comp.lang.pyt...@pearwood.info> wrote:
> >> On Sun, 25 Dec 2011 07:38:17 -0800, Eelco wrote:
>
> [...]
>
> >> > How is 'head, *tail = sequence' or semantically entirely
> >> > equivalently, 'head, tail::list = sequence' any different then? Of
> >> > course after interpretation/compilation, what it boils down to is
> >> > that we are constructing a list and binding it to the identifier
> >> > tail, but that is not how it is formulated in python as a language
>
> >> I'm afraid it is.
>
> >> Here's the definition of assignment in Python 3:
> >>http://docs.python.org/py3k/reference/simple_stmts.html#assignment-
> >> statements
>
> > Que?
>
> You have claimed that "constructing a list and binding it to the
> identifier" is not how iterator unpacking is formulated in Python the
> language. But that is wrong. That *is* how iterator unpacking is
> formulated in Python the language. The reference manual goes into detail
> on how assignment is defined in Python. You should read it.
>
> > 'head, *tail = sequence'
>
> > Is how one currently unpacks a head and tail in idiomatic python
>
> > This is semantically equivalent to
>
> > 'head = sequence[0]'
> > 'tail = list(sequence[1:])'
>
> There's a reason this feature is called *iterable* unpacking: it operates
> on any iterable object, not just indexable sequences.
>
> 'head, *tail = sequence' is not just semantically equivalent to, but
> *actually is* implemented as something very close to:
>
> temp = iter(sequence)
> head = next(temp)
> tail = list(temp)
> del temp
>
> Extended iterable unpacking, as in 'head, *middle, tail = sequence' is a
> little more complex, but otherwise the same: it operates using the
> iterator protocol, not indexing. I recommend you read the PEP, if you
> haven't already done so.
>
> http://www.python.org/dev/peps/pep-3132/
>
> > But these forms are linguistically different, in too many different ways
> > to mention.
>
> How about mentioning even one way? Because I have no idea what
> differences you are referring to, or why you think they are important.

The one spans two lines; the other one. Need I go on?

> >> > We dont have
> >> > something of the form 'tail = list_tail(sequence)'.
>
> >> I'm afraid we do. See the definition of assignment again.
>
> > Que?
>
> Again, you make a claim about Python which is contradicted by the
> documented behaviour of the language. You claim that we DON'T have
> something of the form 'tail = list_tail(sequence)', but that is *exactly*
> what we DO have: extracting the tail from an iterator.
>
> Obviously there is no built-in function "list_tail" but we get the same
> effect by just using list() on an iterator after advancing past the first
> item.
>
> > My claim is that the two semantically identical formulations above do
> > not have isomorphic linguistic form. As far as I can make sense of your
> > words, you seem to be disputing this claim, but its a claim as much
> > worth debating as that the sun rises in the east.
>
> "Isomorphic linguistic form"? Are you referring to the idea from
> linguistics that there are analogies between the structure of phonic and
> semantic units? E.g. that the structures (phoneme, syllable, word) and
> (sememe, onomateme, sentence) are analogous.
>
> I don't see why this is relevant, or which units you are referring to --
> the human-language description of what Python does, high-level Python
> language features, Python byte-code, or machine code. Not that it
> matters, but it is unlikely that any of those are isomorphic in the
> linguistic sense, and I am not making any general claim that they are.
>
> If not, I have no idea what you are getting at, except possibly trying to
> hide behind obfuscation.

I wasnt too worried about obfuscation, since I think there is little
left to lose on that front. Let me make a last-ditch effort to explain
though:

When python reads your code, it parses it into a symbolic graph
representation. The two snippets under consideration do not parse into
the same graph, in the same way that insignificant whitespace or
arbitrary identifier names do, for instance. Hence, not linguistically
isomorphic.

The very function of a programming language is to transform this
representation of the code into semantically identical but differe

Re: Pythonification of the asterisk-based collection packing/unpacking syntax

2011-12-28 Thread Eelco
On Dec 28, 2:11 am, Rick Johnson  wrote:
> On Dec 27, 5:10 pm, Steven D'Aprano 
> +comp.lang.pyt...@pearwood.info> wrote:
> > On Sun, 25 Dec 2011 07:47:20 -0800, Eelco wrote:
> > Your original use-case, where you want to change the type of tail from a
> > list to something else, is simply solved by one extra line of code:
>
> > head, *tail = sequence
> > tail = tuple(tail)
>
> i wonder if we could make this proposal a bit more "Pythonic"? Hmm...
>
> head, tuple(tail) = sequence
>
> ...YEP!

That has been considered; it was my first thought too, but this
requires one to break the symmetry between collection packing and
unpacking.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Pythonification of the asterisk-based collection packing/unpacking syntax

2011-12-28 Thread Eelco
On Dec 28, 8:08 am, Chris Angelico  wrote:
> On Wed, Dec 28, 2011 at 5:25 PM, Steven D'Aprano
>
>
>
>
>
>
>
>
>
>  wrote:
> > On Wed, 28 Dec 2011 15:06:37 +1100, Chris Angelico wrote:
>
> >> ... suppose you have a huge
> >> set/frozenset using tuples as the keys, and one of your operations is to
> >> shorten all keys by removing their first elements. Current Python
> >> roughly doubles the cost of this operation, since you can't choose what
> >> type the tail is made into.
>
> > The First Rule of Program Optimization:
> > - Don't do it.
>
> > The Second Rule of Program Optimization (for experts only):
> > - Don't do it yet.
>
> > Building syntax to optimize imagined problems is rarely a good idea. The
> > difference between 2 seconds processing your huge set and 4 seconds
> > processing it is unlikely to be significant unless you have dozens of
> > such huge sets and less than a minute to process them all.
>
> > And your idea of "huge" is probably not that big... it makes me laugh
> > when people ask how to optimize code "because my actual data has HUNDREDS
> > of items!". Whoop-de-doo. Come back when you have a hundred million
> > items, then I'll take your question seriously.
>
> > (All references to "you" and "your" are generic, and not aimed at Chris
> > personally. Stupid English language.)
>
> And what you're seeing there is the _best possible_ situation I could
> think of, the strongest possible justification for new syntax.
> Granted, that may say more about me and my imagination than about the
> problem, but the challenge is open: Come up with something that
> actually needs this.
>
> ChrisA

I personally feel any performance benefits are but a plus; they are
not the motivating factor for this idea. I simply like the added
verbosity and explicitness, thats the bottom line.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Pythonification of the asterisk-based collection packing/unpacking syntax

2011-12-28 Thread Eelco
On Dec 28, 12:07 am, Steven D'Aprano  wrote:
> On Mon, 26 Dec 2011 13:51:50 -0800, Eelco wrote:
>
> [...]
>
> >> If your point is that parens are used more often than
> >> packing/unpacking, that's almost certainly true, since function calls
> >> (including method invocations) are so prevalent in pretty much any
> >> code. But what does that prove?
>
> > That proves the original point of contention: that the below* is
> > suboptimal language design,
>
> Well duh.

This is where the referee should interrupt you for snipping someones
citation right before a 'but'

> I was mocking the idea that the meaning of * is context-dependent is a
> bad thing by pointing out that we accept context-dependent meaning for
> round brackets () without any difficulties. Of course it is "suboptimal
> language design" -- it couldn't fail to be. Context-dependency is not
> necessarily a bad thing.

You know, so you dont end up simply restating my point while trying to
make it seem like you disagree.

> > not because terseness always trumps
> > verbosity, but because commonly-used constructs (such as parenthesis or
> > round brackets or whatever you wish to call them)
>
> Parentheses are not a construct. They are symbols (punctuation marks)
> which are applied to at least three different constructs: grouping,
> function calls, class inheritance lists.

Parenthesis encompass a class of constructs. Happy now?

> > are more deserving of
> > the limited space in both the ascii table and your reflexive memory,
> > than uncommonly used ones.
>
> Right. And since sequence packing and unpacking is a common idiom, it
> deserves to be given punctuation. That's my opinion.

Its a valid opinion. But if we are going to be quantitative about
terms such as 'common', you know that there will be at least an order
of magnitude difference between these constructs in commonality, if
not two. Thats what makes your example a poor one. If you could
verbosify a construct of the same commonality and arrive at equally
absurd code, you would have a point.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Python education survey

2011-12-28 Thread Eelco
On Dec 28, 2:56 am, Rick Johnson  wrote:
> On Dec 27, 3:44 pm, Eelco  wrote:
>
> > Despite the fact that you mis-attributed that quote to me, im going to
> > be a little bit offended in the name of its actual author anyway.
> > Thats a lot of words to waste on your linguistic preferences.
> > Personally, I reserve the right to botch my non-native languages as
> > much as I please.
>
> I hope you're just joking a bit because i have little respect for
> those who refuse to better themselves. If you are learning English as
> a second language then you have a legitimacy excuse, but at some point
> that excuse just becomes a lie. In any case, i apologize for mis-
> quoting you.

Yes, I was joking a bit; I learned my english primarily on programming
boards, and im proud to say it rivals that of a majority of native
speakers (low bar to beat, true). Furthermore, you are free to direct
criticism at my writing or that of anyone else, but I must say I dont
much care to hear it. A language is learned by using it, in reading,
writing or speech; not by grammar nazis, or style nazis for that
matter. Im here to discuss issues related to python, and anyone who
manages to make himself understood is welcome to do so, as far as I am
concerned. Im much more worried whether they have something
interesting to contribute to the actual discussion. Not getting stuck
picking nits, fighting personal feuds or getting dragged into the
swamp by trolls; those are the real challenges, in my opinion.

If you are insistent on bettering yourself; there is half a dozen
other languages we could continue the conversation in. Your marginal
gain per sentence read and written might be much larger there than in
english.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Pythonification of the asterisk-based collection packing/unpacking syntax

2011-12-29 Thread Eelco
On Dec 28, 11:29 pm, Lie Ryan  wrote:
> On 12/28/2011 11:08 PM, Eelco wrote:
>
> > I personally feel any performance benefits are but a plus; they are
> > not the motivating factor for this idea. I simply like the added
> > verbosity and explicitness, thats the bottom line.
>
> Any performance benefits are a plus, I agree, as long as it doesn't make
> my language looks like Perl. Now get off my lawn!

Im no perl expert, but it says on the wikipedia page a common
criticism is its overuse of otherwise meaningless special characters;
and I would agree; I puked a little in my mouth looking at the code
samples.

I would argue that the use of single special characters to signal a
relatively complex and uncommon construct is exactly what I am trying
to avoid with this proposal.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Pythonification of the asterisk-based collection packing/unpacking syntax

2011-12-29 Thread Eelco
On Dec 29, 2:23 pm, Steven D'Aprano  wrote:
> On Thu, 29 Dec 2011 03:55:14 -0800, Eelco wrote:
> > I would argue that the use of single special characters to signal a
> > relatively complex and uncommon construct is exactly what I am trying to
> > avoid with this proposal.
>
> This would be the proposal to change the existing
>
>     head, *tail = sequence
>
> to your proposed:
>
>     head, tail:: = ::sequence
>
> (when happy with the default list for tail), or
>
>     head, tail::tuple = ::sequence
>
> to avoid an explicit call to "tail = tuple(tail)" after the unpacking.
>
> Either way, with or without an explicit type declaration on the left hand
> side, you are increasing the number of punctuation characters from one to
> four. If your aim is to minimize the number of punctuation characters,
> you're doing it wrong.
>
> --
> Steven

The goal is not to minimize the number of (special) characters to
type. To goal is to minimize the number of special characters which
are hard to interpret at a glance. I would prefer : over ::, but both
are a single special character construct. Adding those characters once
more on the rhs is similarly, not an increase in the number of
concepts employed; merely a more explicit form of the same construct.

And besides, I dont much like 'head, tail:: = ::sequence'. I threw
that out there to appease the terseness advocates, but to me it
largely defeats the purpose, because indeed it is hardly any different
from the original. I like the explicit mentioning of the collection
type to be constructed; that is what really brings it more towards
'for line in file' explicit obviousness to my mind.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Pythonification of the asterisk-based collection packing/unpacking syntax

2012-01-03 Thread Eelco
On Jan 3, 3:38 am, alex23  wrote:
> On Dec 27 2011, 8:01 pm, Eelco  wrote:
>
> > But I consider it a reasonable change for a
> > 'python 4', or whatever the next major version change will be called.
>
> You do realise there were 8 years between 2 & 3? You might be waiting
> for quite some time.

Yes, I realize this discussion is quite theoretical in nature. Some of
the more 'emotionally engaged' participants might do well to keep that
in mind as well.

> Conversely, you could pitch in behind Rick Johnson's Python 4000 fork,
> I sure it's progressing nicely given how long Rick has been talking it
> up.

Would you be so kind as to leave your personal feuds at the door?

> > Writing a code-conversion tool to convert from *args to args::tuple
> > would be quite easy indeed.
>
> You might want to ask people maintaining libraries in both 2.x & 3.x
> via 2to3 just how well that's working out for them. If the impact of
> changes was trivially obvious, the programming landscape would look
> very different indeed.

Of course if a conversion tool falters on even a single construct,
automated conversion is not going to be reliable, and thats going to
be a pain. But whatever python 4 will be like, its not going to be
backwards compatible by definition; and at least I dont think this
proposed change will contribute to the trouble of conversion between
the two. It is really quite a superficial syntax tweak.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Python education survey

2012-01-03 Thread Eelco
> Why do people use pretty when we already have words that carry more
> specific meaning? Because they are lazy! And laziness begets
> stupidity.

No, that would be because they are not autistic. Most people like
having a repertoire of words with subtly different meanings in their
natural language, because there is a demand for this semantic richness.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: replacing __dict__ with an OrderedDict

2012-01-08 Thread Eelco
i havnt read every post in great detail, but it doesnt seem like your
actual question has been answered, so ill give it a try.

AFAIK, changing __dict__ to be an ordereddict is fundamentally
impossible in python 2. __dict__ is a builtin language construct
hardcoded into the C API. There is no way to mess with it.

Apparently this is different in python 3, but I dont know much about
that.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: NaN, Null, and Sorting

2012-01-16 Thread Eelco
On 13 jan, 20:04, Ethan Furman  wrote:
> With NaN, it is possible to get a list that will not properly sort:
>
> --> NaN = float('nan')
> --> spam = [1, 2, NaN, 3, NaN, 4, 5, 7, NaN]
> --> sorted(spam)
> [1, 2, nan, 3, nan, 4, 5, 7, nan]
>
> I'm constructing a Null object with the semantics that if the returned
> object is Null, it's actual value is unknown.
>
>  From a purist point of view if it is unknown then comparison results
> are also unknown since the actual value might be greater, lesser, or the
> same as the value being compared against.
>
>  From a practical point of view a list with Nulls scattered throughout
> is a pain in the backside.
>
> So I am strongly leaning towards implementing the comparisons such that
> Null objects are less than other objects so they will always sort together.
>
> Thoughts/advice/criticisms/etc?
>
> ~Ethan~

My suggestion would be thus: nans/nulls are unordered; sorting them is
fundamentally an ill defined notion. What you want, conceptually, is a
sorted list of the sortable entries, and a seperate list of the
unsorted entries. Translated into code, the most pure solution would
be to filter out the nanas/nulls in their own list first, and then
sort the rest. If the interface demands it, you can concatenate the
lists afterwards, but probably it is most convenient to keep them in
seperate lists.

Perhaps arbitrarily defining the ordering of nulls/nans is slightly
more efficient than the above, but it should not make a big
difference, and in terms of purity its no contest.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Splitting a file from specific column content

2012-01-22 Thread Eelco
The grep solution is not cross-platform, and not really an answer to a
question about python.

The by-line iteration examples are inefficient and bad practice from a
numpy/vectorization perspective.

I would advice to do it the numpythonic way (untested code):

breakpoints = [3, 5, 7]
data = np.loadtxt('data.txt')
time = data[:,0]
indices = np.searchsorted(time, breakpoints)
chunks = np.split(data, indices, axis=0)
for i, d in enumerate(chunks):
np.savetxt('data'+str(i)+'.txt', d)

Not sure how it compared to the grep solution in terms of performance,
but that should be quite a non-issue for 20mb of data, and its sure to
blow the by-line iteration out of the water. If you want to be more
efficient, you are going to have to cut the text-to-numeric parsing
out of the loop, which is the vast majority of the computational load
here; but if thats possible at all depends on how structured your
timestamps are; there must be a really compelling performance gain to
justify throwing the elegance of the np.split based solution out of
the window, in my opinion.
-- 
http://mail.python.org/mailman/listinfo/python-list


Verbose and flexible args and kwargs syntax

2011-12-11 Thread Eelco Hoogendoorn

Throwing an idea for a PEP out there:

It strikes me that the def func(*args, **kwargs) syntax is rather 
unpytonic. It certainly did not have that 'for line in file' pythonic 
obviousness for me as a beginner. Plus, asterikses are impossible to 
google for, so finding out what exactly they do more or less forces you 
to write a forum post about it.


A more readable form occurred to me, which also happens to be more 
flexible, and which I think is fully compatible with the syntax of the 
language:


def func(parg, list(args), dict(kwargs))

Perhaps this is considered abuse of notation; dict(kwargs) already has a 
meaning rather different from the one we try to give it here; but then 
again the context (being inside a function definition) is unique and 
easily recognizable.


An added advantage would be the possibility of using subclasses of dict 
and list as well; imagine how much more beautiful a lot of code would be 
if one could say


def func(attrdict(kwargs))

Problems im still wrestling with: the same syntax could not be used when 
calling a function; that lack of symmetry would make things more 
confusing, not less.


Thoughts?
--
http://mail.python.org/mailman/listinfo/python-list


Verbose and flexible args and kwargs syntax

2011-12-11 Thread Eelco Hoogendoorn

 Yes, that's just a strict keywordification of the * and ** symbols.
 The same argument could be made for eliminating the standard algebraic
 + operator and replacing it with a keyword "__add__". I don't think
 that's worthwhile.



Well, its not quite the same in the sense that algebraic operators are 
essentially part of 'natural language', or at least extremely widely 
adopted. They have earned their own special symbols. Argument 
packing/unpacking is a very specific thing; a small corner of a 
particular programming language.


However, as seen in the light of python 3 head-tail syntax, perhaps the 
above is not quite true, and one could argue that packing/unpacking of 
collections is indeed a quite general concept, deserving of its own 
symbols. Breaking uniformity with that use case would also be a bad 
thing; ideally, a verbose alternative to all occurances of collection 
packing/unpacking would be available.


That said, a more verbose and flexible syntax would be desirable there 
too; as of now, the tail is always a list. I havnt read the discussions 
leading up to those design decisions, but that seems like a compromise 
to me; something like head,tuple(tail) = someiterable would be 
preferrable there too, id say

--
http://mail.python.org/mailman/listinfo/python-list


Verbose and flexible args and kwargs syntax

2011-12-11 Thread Eelco Hoogendoorn
As for syntax; what about coopting/integrating with the function 
annotation syntax?


so:

def func(args: list, kwargs: attrdict)
and correspondingly in the function call?

a, b:tuple = someiterable?

I guess a rule that interprets every function argument annotated as a 
subclass of list or dict as a special case would severely restrict its 
intended use though...

--
http://mail.python.org/mailman/listinfo/python-list


Verbose and flexible args and kwargs syntax

2011-12-11 Thread Eelco Hoogendoorn

 No more so than any other form of punctuation. Plus and minus + - may be
 so common that just about everyone knows it, but how about | == @ % and
 even . (dot)? None of these things will be obvious to newbies who have
 never programmed before. Oh well.



 Some things you just have to learn.



Yes, some things you just have to learn. Nonetheless, I strongly prefer 
explicit logical operators over |, would much rather have 'equals' 
instead of ==, which is stylistic in line with 'is' and explicitly 
distinguishes between equality and identity comparisons. As for %; it is 
entirely unclear to me why that obscure operation ever got its own 
one-character symbol. Ill take 'mod', or even better, 'modulus' any day 
of the week.


The dot is clearly quantitatively in another realm here. 90% of typical 
python code is attribute accesses. The dot is entirely unambigious and 
cannot be mistaken for anything else. It reads like a book.



 It's a judgement call as to where a language divides "cryptic punctuation
 line noise" and "useful short operators", and in my opinion * and ** tuple
 and dict unpacking fall strongly on the "useful short operators" side.
 Your opinion may differ, but luckily for me, the BDFL agrees with me :)


I also agree that it is a value judgement as to which constructs get 
their own cryptic symbols and which do not, but the are some reasonable 
guidelines we should be able to agree upon. Obscure operations should 
not reserve any of the few available characters. Furthermore, the 
language should not just be formally consistent, but also easy to grasp 
at a glance, without deciphering subtle semantics of a blurb of weird 
characters. (some programming languages obviously disagree, but python, 
as far as I am allowed to speak for it, does not). And most importantly, 
if you cant come up with a terse syntax that does everything you want to 
do, the terse syntax should at best be an alternative to the verbose one.




 It is also misleading because args are not collected into a list, but
 into a tuple.


In case you wanted a tuple youd write tuple(args), obviously. Exactly that 
added flexibility is half of my case in favor. Why shouldnt it be a list when I 
want it to?




 Worse, it suggests that one should be able to generalise to
 something like this:



 def func(parg, str(args), int(kwargs), my_func(more_args)):



 which is incoherent.


Sorry, but I dont get this point at all. Does ** suggests one should be 
able to generalize to ***? The rules are the rules.




The real questions, in my mind, are:

1) How useful is this added flexibility? Not insanely, but I can see it 
making a lot of code significantly more clean.


And:

2) How fundamental is collection packing/unpacking? One can easily argue 
that it is indeed quite fundamental and therefore deserves its own terse 
symbols, I feel. However, if more flexibility is indeed deemed 
desirable, such terse syntax quickly gives way to a more verbose one. 
Can you come up with some terse symbols that will be able to express all 
of the below and dont make you wish you hadnt rather typed out the names?


head, tuple(tail) = iterable
head, list(tail) = iterable
head, str(tail) = somestring
head, generator(tail) = mygenerator

And so on.

If not, one has to admit that functionality is being sacrificed on the 
alter of terseness, which seems like a raw deal to me.

--
http://mail.python.org/mailman/listinfo/python-list


Verbose and flexible args and kwargs syntax

2011-12-11 Thread Eelco Hoogendoorn

 There are other means of finding information than Google. Really.


This is really only a very minor point in my argument, so I dont want to 
put the focus on this.


But really, no.

Googling 'myprogramminglanguage conceptimtryingtofigureout' is my first, 
second and third line of defence. Yes, I could read the reference manual 
from top to bottom, and if I already knew about the existence of your 
article then im sure that would be a great help too. But the situation 
one finds oneself in is seeing two asterikses and not even being aware 
they are particular to function definitions/invocations. Im fluent in 
many different languages and well versed in CS concepts and jargon, but 
I had no idea what to search for when first trying to figure out the 
meaning of these symbols, and that does not happen often to me.

--
http://mail.python.org/mailman/listinfo/python-list


Verbose and flexible args and kwargs syntax

2011-12-12 Thread Eelco Hoogendoorn

 The above examples are seldom needed in Python because we have one
 general method to repeatedly split a sequence into head and tail.



 it = iter(iterable) # 'it' now represents the sequenced iterable
 head = next(it) # 'it' now represents the tail after removing the head



 In other words, next(it) encompasses all of your examples and many more.
 Because 'it' is mutated to represent the tail, it does not need to be
 rebound and therefore is not.



The question in language design is never 'could we do these things 
before'. The answer is obvious: yes our CPUs are turing complete; we can 
do anything. The question is; how would we like to do them?


So do you think the new head/tail unpacking features in python 3 are 
entirely uncalled for? I personally quite like them, but I would like 
them to be more general.

--
http://mail.python.org/mailman/listinfo/python-list


Verbose and flexible args and kwargs syntax

2011-12-12 Thread Eelco Hoogendoorn

> No more, or less, explicit than the difference between "==" and "is".

== may be taken to mean identity comparison; 'equals' can only mean one 
thing. Of course 'formally' these symbols are well defined, but so is 
brainf*ck



 Modulo is hardly an obscure operation. "What's the remainder...?" is a
 simple question that people learn about in primary school.



So is 'how much wood would a woodchucker chuck if a woodchucker could 
chuck wood?'. But how often does that concept turn up in your code?


> And you can blame C for the use of % instead of mod or modulo.

I didnt know one of Python's design goals was backwards compatibility 
with C.



 I can't imagine what sort of Python code you have seen that you consider
 90% attribute access "typical". I've just run the Python tokenizer over
 my startup.py file, and I get these results:


Yes, that was a hyperbole; but quite an often used construct, is it not?


 If you can supply any function at all, what happens if I write this:



You cannot; only constructors modelling a sequence or a dict, and only 
in that order. Is that rule clear enough?


> I believe that your proposal leads to an over-generalisation "call
> arbitrary functions when handling parameter lists".

I hope the above clears that up. It is as much about calling functions 
as ** is about raising kwargs to the power of.


> I don't believe you
> need this added complication. If you want to your var args as a list,
> call list(args) inside your function.

We dont strictly 'need' any language construct. Real men use assembler, 
right?




 >/  head, tuple(tail) = iterable

/>  In Python 3, that is spelled:

 head, *tail = iterable
 tail = tuple(tail)


Yes, I know. How is that not a lot more verbose and worse than what I 
have proposed in all possible ways?


> head, tail = somestring[0], somestring[1:]

Well yes, splendid; we can do that with lists too since the dawn of 
Python. What you are saying here in effect is that you think the 
head/tail syntax is superfluous; that youd rather see it eliminated than 
generalized.


> head, tail = next(mygenerator), mygenerator

Which again of course works, but is yet again of entirely different form 
than any of the above solutions, while conceptually doing the same 
thing. Certainly, there is room for improved elegance here?
-- 
http://mail.python.org/mailman/listinfo/python-list


Verbose and flexible args and kwargs syntax

2011-12-12 Thread Eelco Hoogendoorn

 On the contrary, it is a major point. You want us to change the language
 so you can program by Google. Sorry, aint't gonna happen.


On the contrary; I believe I get to decide which points I consider 
important. This one, I do not. Sorry for putting it in the first paragraph.

--
http://mail.python.org/mailman/listinfo/python-list


Verbose and flexible args and kwargs syntax

2011-12-12 Thread Eelco Hoogendoorn

> On the contrary, it is a major point.

Sorry, but im affraid it is up to ME to decide which point I feel are 
important. No, this is a minor point to me, and one that has been 
admirably put to rest by pointing out that spelling out the name of the 
symbol in google directly leads you to the information you are looking for.

--
http://mail.python.org/mailman/listinfo/python-list