Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Python > Pythonification of the asterisk-based collection packing/unpacking syntax

Reply
Thread Tools

Pythonification of the asterisk-based collection packing/unpacking syntax

 
 
Steven D'Aprano
Guest
Posts: n/a
 
      12-18-2011
On Sun, 18 Dec 2011 13:45:35 +1100, Chris Angelico wrote:

> On Sun, Dec 18, 2011 at 11:59 AM, Steven D'Aprano
> <steve+> wrote:
>> The usual test of a weakly-typed language is that "1"+1 succeeds (and
>> usually gives 2), as in Perl but not Python. I believe you are
>> confusing weak typing with dynamic typing, a common mistake.

>
> I'd go stronger than "usually" there. If "1"+1 results in "11", then
> that's not weak typing but rather a convenient syntax for
> stringification - if every object can (or must) provide a to-string
> method, and concatenating anything to a string causes it to be
> stringified, then it's still strongly typed.



For what it's worth, Wikipedia's article on type systems gives Javascript
as an example of weak typing because it converts "1"+1 to "11". I agree
with them.

http://en.wikipedia.org/wiki/Type_system

I think that weak and strong typing aren't dichotomies, but extremes in a
continuum. Assembly languages are entirely weak, since everything is
bytes and there are no types to check; some academic languages may be
entire strong; but most real-world languages include elements of both.
Most commonly coercing ints to floats.

Chris Smith's influence article "What To Know Before Debating Type
Systems" goes further, suggesting that weak and strong typing are
meaningless terms. I don't go that far, but you should read his article:

http://cdsmith.wordpress.com/2011/01...ticle-i-wrote/


> Or is a rich set of automated type-conversion functions evidence of weak
> typing? And if so, then where is the line drawn - is upcasting of int to
> float weak?


To my mind, the distinction that should be drawn is that if two types are
in some sense the same *kind* of thing, then automatic conversions or
coercions are weak evidence of weak typing. Since we consider both ints
and floats to be kinds of numbers, mixed int/float arithmetic is not a
good example of weak typing. But since numbers and strings are quite
different kinds of things, mixed str/int operations is a good example of
weak typing.

But not *entirely* different: numbers can be considered strings of
digits; and non-digit strings can have numeric values. I don't know of
any language that allows 1 + "one" to return 2, but such a thing wouldn't
be impossible.


--
Steven
 
Reply With Quote
 
 
 
 
Chris Angelico
Guest
Posts: n/a
 
      12-18-2011
On Sun, Dec 18, 2011 at 2:03 PM, Evan Driscoll <> wrote:
> Sorry, I just subscribed to the list so am stepping in mid-conversation,


Welcome to the list! If you're curious as to what's happened, check
the archives:
http://mail.python.org/pipermail/python-list/

> Something like ML or Haskell, which does not even allow integer to
> double promotions, is very strong typing. Something like Java, which
> allows some arithmetic conversion and also automatic stringification (a
> la "1" + 1) is somewhere in the middle of the spectrum. Personally I'd
> put Python even weaker on account of things such as '[1,2]*2' and '1 <
> True' being allowed, but on the other hand it doesn't allow "1"+1.


But [1,2]*2 is operator overloading. The language doesn't quietly
convert [1,2] into a number and multiply that by 2, it keeps it as a
list and multiplies the list by 2.

Allowing 1 < True is weaker typing. It should be noted, however, that
"1 < True" is False, and "1 > True" is also False. The comparison
doesn't make much sense, but it's not an error.

ChrisA
 
Reply With Quote
 
 
 
 
Roy Smith
Guest
Posts: n/a
 
      12-18-2011
In article <4eed5eef$0$29979$c3e8da3$ om>,
Steven D'Aprano <steve+> wrote:

> some academic languages may be
> entire strong; but most real-world languages include elements of both.
> Most commonly coercing ints to floats.


Early Fortran compilers did not automatically promote ints to floats.

> But not *entirely* different: numbers can be considered strings of
> digits; and non-digit strings can have numeric values. I don't know of
> any language that allows 1 + "one" to return 2, but such a thing wouldn't
> be impossible.


It is possible for 1 + "one" to be equal to 2 in C or C++. All it takes
is for the string literal to be located at memory location 1. Not
likely, but nothing in the language prevents it.
 
Reply With Quote
 
Chris Angelico
Guest
Posts: n/a
 
      12-18-2011
On Sun, Dec 18, 2011 at 2:59 PM, Roy Smith <> wrote:
> It is possible for 1 + "one" to be equal to 2 in C or C++. *All it takes
> is for the string literal to be located at memory location 1. *Not
> likely, but nothing in the language prevents it.


Not quite; 1 + "one" will be "ne", which might happen to be at memory
location 2. The data type is going to be char* (or, in a modern
compiler, const char*), not int. That said, though, I think that (in
this obscure circumstance) it would compare equal with 2. For what
that's worth.

ChrisA
 
Reply With Quote
 
Evan Driscoll
Guest
Posts: n/a
 
      12-18-2011
On 12/17/2011 21:42, Chris Angelico wrote:
> Welcome to the list! If you're curious as to what's happened, check
> the archives:
> http://mail.python.org/pipermail/python-list/

Thanks! Incidentally, is there a good way to respond to the original
post in this thread, considering it wasn't delivered to me?

> But [1,2]*2 is operator overloading. The language doesn't quietly
> convert [1,2] into a number and multiply that by 2, it keeps it as a
> list and multiplies the list by 2.
>
> Allowing 1 < True is weaker typing. It should be noted, however, that
> "1 < True" is False, and "1 > True" is also False. The comparison
> doesn't make much sense, but it's not an error.

I see where you're coming from, especially as I wouldn't consider
overloading a function on types (in a language where that phrase makes
sense) moving towards weak typing either. Or at least I wouldn't have
before this discussion... At the same time, it seems a bit
implementationy. I mean, suppose '1' were an object and implemented
__lt__. Does it suddenly become not weak typing because of that?

(The other thing is that I think strong vs weak is more subjective than
many of the other measures. Is '1 < True' or '"1"+1' weaker? I think it
has a lot to do with how the operations provided by the language play to
your expectations.)

On 12/17/2011 22:05, Chris Angelico wrote:
> Not quite; 1 + "one" will be "ne", which might happen to be at memory
> location 2. The data type is going to be char* (or, in a modern
> compiler, const char*), not int.

I'm not quite sure I'd say that it could be 2, exactly, but I definitely
disagree with this... after running 'int x = 5, *p = &x' would you say
that "p is 5"? (Assume &x != 5.) 1+"one" *points to* "ne", but it's
still a pointer.

Evan




-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.10 (MingW32)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/

iQEcBAEBAgAGBQJO7W9kAAoJEAOzoR8eZTzgj6wH/0NGvt3ENA62bRVoA0hIeMm6
HQNcx8F5IvPIscLpD5pbUdLk3QHHNdZWk4RDTemDW16SIJfmxx yQG64Kt9uc8LHw
kORW7AnUZl9x+zBsB8XBU8nfAJrKvGEoum1RBaq8MxAkBEkLqZ oWK8+y67iAR4eI
fg3iFwZ6UPJFt/8dUjC7rIKAVWtXuzI2WU4ojXNn7s4KIbktL5dJij5wdKAe0id2
ZKmh49WzocnY7saZTSrodW4mtfDppc+tyyd1BLnjXM5fIHaIYR TywdO/Rj7OfpN1
QdM56MdJgFMSO6SRfZHAToXhCmJKTJ80STz1yAqm80Y87klITe 9K/gDNTPE3Fbc=
=Ee7m
-----END PGP SIGNATURE-----

 
Reply With Quote
 
buck
Guest
Posts: n/a
 
      12-18-2011
I like the spirit of this. Let's look at your examples.

> 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 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).

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.

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.

-buck
 
Reply With Quote
 
Chris Angelico
Guest
Posts: n/a
 
      12-18-2011
On Sun, Dec 18, 2011 at 3:43 PM, Evan Driscoll <> wrote:
> On 12/17/2011 21:42, Chris Angelico wrote:
>> Welcome to the list! If you're curious as to what's happened, check
>> the archives:
>> http://mail.python.org/pipermail/python-list/

> Thanks! Incidentally, is there a good way to respond to the original
> post in this thread, considering it wasn't delivered to me?


I don't know of a way, but this works. It's all part of the same thread.

> I mean, suppose '1' were an object and implemented
> __lt__. Does it suddenly become not weak typing because of that?


Is it weak typing to overload a function?

//C++ likes this a lot.
int foo(int x,int y) {return x*3+y;}
double foo(double x,double y) {return x*3+y;}

This is definitely making the term "strongly typed language" fairly useless.

> (The other thing is that I think strong vs weak is more subjective than
> many of the other measures. Is '1 < True' or '"1"+1' weaker? I think it
> has a lot to do with how the operations provided by the language play to
> your expectations.)


+1. My expectations are:
1) The Boolean value "True" might be the same as a nonzero integer, or
might not; it would make sense to use inequality comparisons with
zero, MAYBE, but not with 1. So I don't particularly care what the
language does with "1 < True", because it's not something that I would
normally do.
2) "1"+1, in any high level language with an actual string type, I
would expect to produce "11". It makes the most sense this way; having
it return 2 means there's a special case where the string happens to
look like a number - meaning that " 1"+1 is different from "1"+1. That
just feels wrong to me... but I'm fully aware that many other people
will disagree.

Yep, it's pretty subjective.

> On 12/17/2011 22:05, Chris Angelico wrote:
>> Not quite; 1 + "one" will be "ne", which might happen to be at memory
>> location 2. The data type is going to be char* (or, in a modern
>> compiler, const char*), not int.

> I'm not quite sure I'd say that it could be 2, exactly, but I definitely
> disagree with this... after running 'int x = 5, *p = &x' would you say
> that "p is 5"? (Assume &x != 5.) 1+"one" *points to* "ne", but it's
> still a pointer.


Point. I stand corrected. I tend to think of a char* as "being" the
string, even though technically it only points to the beginning of it;
it's the nearest thing C has to a string type. (To be honest, it's
still a lot better than many high level languages' string types for
certain common operations - eg trimming leading whitespace is pretty
efficient on a PSZ.) In your example, p would be some integer value
that is the pointer, but *p is 5. However, there's really no syntax in
C to say what the "string value" is.

ChrisA
 
Reply With Quote
 
Chris Angelico
Guest
Posts: n/a
 
      12-18-2011
On Sun, Dec 18, 2011 at 3:52 PM, buck <> wrote:
> 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.
>
> Try these on for size.
>
> * * head, @tuple tail = sequence
> * * def foo(@list args, @dict kwargs): pass
> * * foo(@args, @kwargs)


That's reasonably clean as a concept, but it's not really quite the
same. None of these examples is the way a decorator works; each of
them requires a fundamental change to the way Python handles the rest
of the statement.

head, @tuple tail = sequence
-- Does this mean "take the second element of a two-element sequence,
pass it through tuple(), and store the result in tail"? Because, while
that might be useful, and would make perfect sense as a decorator,
it's insufficient as a replacement for current "*tail" syntax.

ChrisA
 
Reply With Quote
 
Evan Driscoll
Guest
Posts: n/a
 
      12-18-2011
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.)

buck's syntax still has some of the feel of "I wonder if this is type
checking" to a newbie, but much much less IMO.


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?

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.)


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)

Evan








-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.10 (MingW32)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/

iQEcBAEBAgAGBQJO7XsnAAoJEAOzoR8eZTzgYsAH/2Q/po+5w9/FA7vOgx1cii6X
WBHx772m/C24XKt8U2SM4a3rT3QUs69L9LE3Sk8uzq6OuQHycqjxdvhwFUJ WqX+m
5jQw15VK554/bSI8b+AX3oLsam8xbSsZ9J2Ru49KoWMcj7R0ns1vJES4MFwu9L +M
y9E0/miUcSpGQe18N1VlYmEdF5wJcg4vitJrimLC5CLttWZiUq94Coa QY2ju3cZk
bg14ISsOlmy3uW8D84WUd7YxI4dPVyTg2PAhnwdZgpTnCvSe12 Mu6R8WUxBvbzwj
xvle/VOXhgC8msocMBA756A2KvJEtLwCofBrjeEnVHKn0S7QyUMjpXD sZoBUS7E=
=2y+K
-----END PGP SIGNATURE-----

 
Reply With Quote
 
Evan Driscoll
Guest
Posts: n/a
 
      12-18-2011
On 12/17/2011 23:33, Evan Driscoll wrote:
> 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.

Though in the interest of full disclosure, and I should have said this
before, the first hit for all of those searches except "python star"
*is* relevant and reasonably helpful; just from someone's blog post
instead of "from the horse's mouth", so to speak.

Evan


-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.10 (MingW32)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/

iQEcBAEBAgAGBQJO7YAbAAoJEAOzoR8eZTzg1q8IAINyMZUpbM eEKHO8DkCTEfWE
kdsazCuM3Iv9najPtbRmYs8GnNjsWG2rTqHlxrjhtjKc9dkbOd mskRshP/pcPzSv
Uorvf7XDLGbJ/GwTERIDW7PqPVeXlTtdW6jW7xPrztWWU6/hIEiETFEmQwK/CHDG
82wb3rdxOAS+RxnVUfbYJq3RXI0IiH+ATVWnUpXlnq2IuosKeJ lqNZ6Rk8ADB0R4
ZVmfHvSNb7TpSG4HNJZODVC3O8t1+T1jsYjwgMp/oN5d8x/2cTrrwaqLqYAR+dVS
UVYLEt85I9FJqb0ddubKAZH+vmnwbzgwgcY0fL2WcloW9/CpCgrS+BNhyMqlOi0=
=XYhS
-----END PGP SIGNATURE-----

 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
create collection of collection Hemant ASP .Net 1 10-22-2009 03:04 PM
Collection problems (create Collection object, add data to collection, bind collection to datagrid) Øyvind Isaksen ASP .Net 1 05-18-2007 09:24 AM
Sorting the Collection(java.util.Collection) of Elements Pradeep Java 2 01-24-2007 02:33 PM
Adding to collection from controlDesigner only produces end tag for the collection. Don ASP .Net Building Controls 0 07-22-2005 09:31 PM
STL - an algorithm for finding a collection within a collection? Dylan C++ 5 03-22-2005 01:31 AM



Advertisments
 



1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57