News for hackers. Stuff that matters.
Re:Key differences between Python 2.7.x and Python 3.x (2014) by Mizza on Sunday May 07, 2017 @01:48PM (#14286540)
I have a whole blog post/rant brewing about that topic, but on the whole, I just think it feels like it was designed by committee rather than a visionary. They've abandoned the common usage case in favor of the corner case. It also makes it much harder to teach.

A few quick examples:

Base64 encoding returns bytes. Why would anybody _ever_ want that? The whole purpose of B64 encoding is to make something string-safe.

It's also now invalid to have this as a project structure: Name/name.py (with a Name class) in it.

Which I would say is literally the most sensible common project structure to have. Now you have to call the file with the name class 'core' or 'main' or anything besides the actual description of what it is. Of course, you'll get no help from the errors if you hit this problem.

"Dictionary view objects" are horribly unsemantic and annoying to teach. How is the language improved by having this no longer work `k = d.keys(); k.sort()`? Just give me a list.

I'm maintaining a fairly large and popular Python 2/3 project and all of the errors are coming from the Python 3 side, and the maintainability of the project has been decimated by needing to support both versions.

They should have just made a 2.8 with asyncio and unicode strings.

My hope is that somebody will make a new language that does to Python what Python did to C/Java. For day-to-day scripting, let's get really serious about programmer ergonomics, semantics and maintainability above all.

Re:Key differences between Python 2.7.x and Python 3.x (2014) by masklinn on Sunday May 07, 2017 @05:32PM (#14287803)
> Base64 encoding returns bytes. Why would anybody _ever_ want that? The whole purpose of B64 encoding is to make something string-safe.

No, it's to make something ascii-safe which is a completely different concern.

> It's also now invalid to have this as a project structure: Name/name.py (with a Name class) in it.

What?

    > mkdir Name
    > echo "class Name: pass" > Name/name.py
    > python3 -c "from Name.name import Name;print(Name)"
    <class 'Name.name.Name'>
> "Dictionary view objects" are horribly unsemantic

Unsemantic? They're just the opposite. keyviews and itemviews are now sets, which is semantically sensible and really useful to get the intersection of two dictionary keysets, the only missing part is being able to subdict based on a keyset.

> Just give me a list.

    list(d.keys())
Why are you even using .sort()

> unicode strings.

That's what broke compatibility FFS, that's the entire reason why the maintainers felt they could change the rest of the language.

Re:Key differences between Python 2.7.x and Python 3.x (2014) by goatlover on Sunday May 07, 2017 @01:51PM (#14286554)
There are other scripting languages that have good support and strong communities. There doesn't need to be yet another programming language. Use Ruby, JS or PHP 7 instead. If it's scientific computing, Julia fills the niche very nicely. Or R.
Re:Key differences between Python 2.7.x and Python 3.x (2014) by Mizza on Sunday May 07, 2017 @01:59PM (#14286594)
My point is that we should go a level "higher" than any current offering.

Ex, why not let me do something like this out of the box:

    get https://api.github.com/users/Miserlou as miserlou
    print "My name is " miserlou.name
Transparent/automatic web requests, content-type checking, serialization parsing, string formatting, network reference parsing, etc. Let the user be more specific if they need to, but design heavily around the most common use case.
Re:Key differences between Python 2.7.x and Python 3.x (2014) by twic on Sunday May 07, 2017 @02:48PM (#14286873)
This is the kind of stuff Rebol wanted to do, although i don't know if it covered this particular case.
Re:Key differences between Python 2.7.x and Python 3.x (2014) by marvy on Sunday May 07, 2017 @03:07PM (#14286990)
Yep, the moment I saw that I though "REBOL"! (Actually, I thought of Red, but same idea.)

Still, it seems that this is not thought through properly. What should the language do if the server does not return JSON? And can't we basically do this in Python already?

Re:Key differences between Python 2.7.x and Python 3.x (2014) by Mizza on Sunday May 07, 2017 @03:30PM (#14287125)
It's a trivial example, but the point would be that the stdlib would have the ability to

a) Speak flutent HTTP b) Understand Content-Type c) Deserialize to a common format

all completely transparently. If the server returned XML or MsgPack, it wouldn't matter, the code would work the same.

Ideally, we could imagine this going a step further, and having the language speak REST entirely.

Python's requests is a nice prototype, ergonomically speaking, but we can go much further.

Re:Key differences between Python 2.7.x and Python 3.x (2014) by draegtun on Monday May 08, 2017 @02:44PM (#14294361)
There is nothing currently built into Rebol stdlib that replicates exactly this. But here's an example of how it could be done...

    import <json>
    import <xml>

    load-*: function [site] [
        p: open site
        content: read p
        http: query p
        close p

        parse http/headers/Content-Type [
              "application/json" return (load-json content)
            | "application/xml"  return (load-xml content)
        ] else [
            fail "Content-Type not recognised"
        ]
    ]

    miserlou: load-* https://api.github.com/users/Miserlou
    print ["My name is" miserlou/name]
Re:Key differences between Python 2.7.x and Python 3.x (2014) by marvy on Monday May 08, 2017 @09:50PM (#14297176)
Is this hypothetical, or does the stdlib actually have load-json and load-xml?
Re:Key differences between Python 2.7.x and Python 3.x (2014) by draegtun on Tuesday May 09, 2017 @09:23AM (#14299755)
Above works, the <json> & <xml> imports are pulled off this remotely hosted common library - https://github.com/r3n/renclib

You'll need the Ren/C branch of Rebol 3 for this:

* repo - https://github.com/metaeducation/ren-c

* pre-built binaries - http://metaeducation.s3.amazonaws.com/index.html

Re:Key differences between Python 2.7.x and Python 3.x (2014) by marvy on Tuesday May 09, 2017 @02:20PM (#14302578)
Okay, as someone who doesn't know REBOL, what is the effect of miserlou/name if the server returns XML? The string value of a top-level <name> tag?
Re:Key differences between Python 2.7.x and Python 3.x (2014) by draegtun on Wednesday May 10, 2017 @03:40AM (#14306517)
Ah this was a different XML module than I was thinking of because this is complete DOM parser!! But even so it does produce (by default) a flat representation of the XML.

So, if for example, Github did return XML and it looked something like this (shown in Rebol console):

    >> x: load-xml {<root><name>Mr Miserlou</name><login>xxx</login></root>}
    == [
        <root> [
            <name> "Mr Miserlou"
            <login> "xxx"
        ]
    ]
So to get top-level tags it's just:

    >> second x                                                              
    == [
        <name> "Mr Miserlou"
        <login> "xxx"
    ]
Now load-json also has a flat option so that a good way to unify things. Here's an updated example showing this:

    import <json>
    import <xml>

    load-*: function [site] [
        p: open site
        content: read p
        http: query p
        close p

        data: parse http/headers/Content-Type [
              "application/json" return (load-json/flat content)
            | "application/xml"  return (second load-xml content)
        ] else [
            fail "Content-Type not recognised"
        ]

        ;; next 2 lines just turns it into a hashmap so can do:  miserlou/name
        ;; without it could have done:  miserlou/<name>
        ;;
        for-skip data 2 [data/1: to-word to-string data/1]
        make map! lock data
    ]

    miserlou: load-* https://api.github.com/users/Miserlou
    print miserlou/name
Re:Key differences between Python 2.7.x and Python 3.x (2014) by marvy on Thursday May 11, 2017 @12:45PM (#14317438)
Okay, that's quite good! I'm going to see how good this can get with the Python std lib later. Probably not quite this nice.
Re:Key differences between Python 2.7.x and Python 3.x (2014) by marvy on Thursday May 11, 2017 @09:35PM (#14320846)
Actually, I think I was wrong. You can get something this nice in Python. It just requires a bit more glue code in the case of JSON, and a lot more glue code in the case of XML. All told, I figure Python might 10x more code than REBOL here. I'm not sure if it's fair to hold this against Python though. It's "just" a question of libraries. And it's only fair to hold libraries against a language if the library itself would be hard to write. Which in this case I think it wouldn't.

Still neat though. Sometimes I wonder if I should learn REBOL (or Red?) or something.

Re:Key differences between Python 2.7.x and Python 3.x (2014) by marvy on Sunday May 07, 2017 @06:36PM (#14288112)
Um, what if the server returned, say, a JPEG? Or a plain old HTML webpage, complete with inline CSS and script tags?
Re:Key differences between Python 2.7.x and Python 3.x (2014) by draegtun on Monday May 08, 2017 @02:07PM (#14294056)
Very close!

Here's an example using latest build of Rebol 3 (Ren/C branch)...

    import <json>
    miserlou: load-json read https://api.github.com/users/Miserlou
    print ["My name is" miserlou/name]
Re:Key differences between Python 2.7.x and Python 3.x (2014) by goatlover on Sunday May 07, 2017 @02:04PM (#14286628)
I like that! Are you sure there isn't some language that does this already?
Re:Key differences between Python 2.7.x and Python 3.x (2014) by narimiran on Sunday May 07, 2017 @03:39PM (#14287178)
> `k = d.keys(); k.sort()`? Just give me a list

Here you go, a sorted list of dict keys:

    k = sorted(d.keys())
Re:Key differences between Python 2.7.x and Python 3.x (2014) by Mizza on Sunday May 07, 2017 @03:48PM (#14287226)
You've completely missed the point. I'm not saying it can't be done, I'm saying that the new way is stupid.

In Python 3, I have to tell my students that

   breakfast = ["bacon", "eggs"]
   sorted_breakfast = breakfast.sort()
works, but

   breakfast = {"bacon": 2, "eggs": 3}
   sorted_breakfast = breakfast.keys().sort()
doesn't. They will ask, "why?", and I have to say "just because."

Instead, you have to use "sorted", even though "sorted" isn't even a verb, it is a property. "Why is sorted() rather than sort()" - "just because."

Similarly, "where is there a b'' in front of my name", why can't it find my module, and on and on and on.

The advantages of Python of a teaching languages are mostly gone now, and I would probably use JavaScript to teach beginners now, whereas I previously would have used Python2.7.

Re:Key differences between Python 2.7.x and Python 3.x (2014) by narimiran on Sunday May 07, 2017 @04:00PM (#14287290)
> In Python 3, I have to tell my students that

> breakfast = ["bacon", "eggs"]

> sorted_breakfast = breakfast.sort()

> works

Well, some of your students might point out to you that your `sorted_breakfast` is `None`, because that is what `sort()` returns, and even this example doesn't work as you have wanted ;)

On the other hand, if you have used `sorted(breakfast)` (and `sorted(breakfast.keys())` in other example), both examples would work as intended, and you couldn't blame Python 3.

> "Why is sorted() rather than sort()" - "just because."

It is not "just because", it is because it returns a sorted list (which is exactly what you wanted), compared to returning None.

Re:Key differences between Python 2.7.x and Python 3.x (2014) by masklinn on Sunday May 07, 2017 @05:33PM (#14287808)
> It is not "just because", it is because it returns a sorted list (which is exactly what you wanted), compared to returning None.

Also because `sorted()` works on any iterable, whereas .sort only works on lists.

Re:Key differences between Python 2.7.x and Python 3.x (2014) by xapata on Monday May 08, 2017 @01:28AM (#14289441)
I know that the best way to learn is "see one, do one, teach one" but I wish you'd put more effort into learning the language before teaching it.

The python.org tutorial and FAQ have answers to these questions.

I think it's unethical to tell a student, "just because" instead of, "I don't know why."

Re:Key differences between Python 2.7.x and Python 3.x (2014) by narimiran on Monday May 08, 2017 @02:07AM (#14289580)
You're replying to the wrong person. I'm not the one who is doing teaching, I'm just the guy who corrects the teacher who hates Python 3 (for wrong reasons) ;)
Re:Key differences between Python 2.7.x and Python 3.x (2014) by xapata on Monday May 08, 2017 @11:02AM (#14292080)
Sorry about that.
Re:Key differences between Python 2.7.x and Python 3.x (2014) by SmirkingRevenge on Sunday May 07, 2017 @04:10PM (#14287338)
FYI... neither of those work. Sort (using the dot sort() notation) operates on a mutable list in place, and returns no value. Never use it on the right side of an assignment. Its like dict's `update` in that regard.
Re:Key differences between Python 2.7.x and Python 3.x (2014) by pythongen on Sunday May 07, 2017 @04:08PM (#14287327)
your example sorted_breakfast doesn't work, in python 3.5 sorted_breakfast == None. Sort is a verb that modifies the receiving object, sorted is for returning a new object that is a sorted copy of the original, so you need to allocate two times the object.

Returning an iterator instead of a list has the advantage of not having to create a new object in case that is not needed, for example if you are going to filter a big dictionary just to obtain a few items then copying the keys of the dictionary and then filtering is not a good way of using memory efficiently.

Re:Key differences between Python 2.7.x and Python 3.x (2014) by int_19h on Sunday May 07, 2017 @11:46PM (#14289103)
> Similarly, "where is there a b'' in front of my name"

How do you even get them there? I mean, input() returns Unicode strings. So do all operations on text streams.

Re:Key differences between Python 2.7.x and Python 3.x (2014) by kortex on Monday May 08, 2017 @12:07AM (#14289177)
In [1]: breakfast = {"bacon": 2, "eggs": 3}

In [2]: sorted(breakfast)

Out[2]: ['bacon', 'eggs']

Done. One and only one obvious way to return a sorted list of keys of a dict.

Re:Key differences between Python 2.7.x and Python 3.x (2014) by macspoofing on Sunday May 07, 2017 @03:01PM (#14286954)
>Base64 encoding returns bytes. Why would anybody _ever_ want that?

What corner case do you think python 3 is solving with the return type being a byte array? Surely you must have looked into it because clearly it isn't arbitrary ... Right?

>The whole purpose of B64 encoding is to make something string-safe

Guess again.

Re:Key differences between Python 2.7.x and Python 3.x (2014) by Mizza on Sunday May 07, 2017 @03:09PM (#14286998)
From Wikipedia:

"Base64 is a group of similar binary-to-text encoding schemes that represent binary data in an ASCII string format by translating it into a radix-64 representation."

Binary. To. Text. As in - bytes in, text out. Come on now.

Re:Key differences between Python 2.7.x and Python 3.x (2014) by SmirkingRevenge on Sunday May 07, 2017 @04:27PM (#14287452)
Its intentional, in part because of all the mayhem caused by Python2's "free-spirited" view on whether a thing is bytes or text. And that "free-spirited" view caused A LOT of mayhem.

Python3 errs on the side of not converting bytes to strings or vice versa unless its an explicit conversion on the bytes/string object itself. And it is fan-fucking-tastic!

Re:Key differences between Python 2.7.x and Python 3.x (2014) by Volt on Sunday May 07, 2017 @05:56PM (#14287921)
How do you feel about this:

https://github.com/naftaliharris/tauthon