Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Post
  • Reply
Subjunctive
Sep 12, 2006

✨sparkle and shine✨

vOv posted:

Didn't Python's built-in HTTP library not actually verify HTTPS certificates by default for a long time, or am I thinking of something else?

Yeah, until late 2014 (some 2.7.x maintenance release) or so.

Adbot
ADBOT LOVES YOU

Internet Janitor
May 17, 2008

"That isn't the appropriate trash receptacle."
I've read several of Rob Pike's papers and watched some of his talks about the design of Go, and I think he has a very different definition of "simple" than I do. It seems Guido is in a similar camp to Rob.

For loops are very flexible and can be used to produce solutions to many problems. That's one kind of simplicity. map, reduce, filter, scan and friends each have a very specific purpose, and expose fewer "moving parts"- no loose variable definitions, no opportunities for off-by-one errors. I find that a more satisfying kind of simplicity. By having a more specific use case in mind, they convey more meaning to both a reader and potentially a compiler.

Pavlov
Oct 21, 2012

I've long been fascinated with how the alt-right develops elaborate and obscure dog whistles to try to communicate their meaning without having to say it out loud
Stepan Andreyevich Bandera being the most prominent example of that
The problem with list comprehensions is that they're only reasonable to use in trivial cases, but list comprehensions aren't a trivial feature of python, they're a whole embedded domain specific language, complete with it's own nesting and order of operations. For instance guess what this does:

Python code:
[x for row in matrix for x in row]
The answer is: it flattens a matrix to an array. I remember spending way too much time figuring out exactly why this works before realizing how stupid that was.

Pavlov fucked around with this message at 20:40 on Jan 20, 2016

VikingofRock
Aug 24, 2008




Pavlov posted:

The problem with list comprehensions is that they're only reasonable to use in trivial cases, but list comprehensions aren't a trivial feature of python, they're a whole impeded domain specific language, complete with it's own nesting and order of operations. For instance guess what this does:

Python code:
[x for row in matrix for x in row]
The answer is: it flattens a matrix to an array. I remember spending way too much time figuring out exactly why this works before realizing how stupid that was.

I've always thought it was really confusing how python orders nested for's in a list comprehension. This:

Python code:
[x for x in row for row in matrix]
seems much more natural to me. (I get that it's supposed to be ordered like how you would nest the for loops, but still)

comedyblissoption
Mar 15, 2006

List comprehensions are kind of dumb because they aren't extensible.

List comprehensions are only more readable because the language didn't prioritize good syntax for the superior alternative: composing higher order functions.

here are some examples of different syntaxes for chaining together higher order functions:
code:
//most langs (e.g. python) tend to look like unreadable poo poo:
result = reduce(multiply, filter(predicate, map(square, list)), 1);

//there's probably some list comprehension equivalent for this that looks ok,
//but again, it's not extensible
code:
//some OO langs (e.g. C#) start looking reasonable:
result = list
    .map(square)
    .filter(predicate)
    .reduce(multiply, 1)
code:
//functional langs (e.g. haskell) have idioms supporting composition of functions:
result = reduce multiply 1 . filter predicate . map square $ list

Hammerite
Mar 9, 2007

And you don't remember what I said here, either, but it was pompous and stupid.
Jade Ear Joe

Internet Janitor posted:

Python is a depressingly mediocre language. There are slower languages, more dangerous languages and worse-designed languages, but it is a master of nothing.

Arguably it's intended to fulfil that jack of all trades role. But I don't really like the implication that we should want to program in a "more dangerous" language because it's less "mediocre" by somebody's idiosyncratic idea of what is and isn't mediocre. Yes the rocket veered off course and blew up, but on the other hand, the programmers writing the code were enjoying themselves! (Yes I am aware that you wouldn't write a rocket guidance system in Python)

quote:

From syntax to semantics it is riddled with inconsistencies and "convenient" special cases.

What inconsistencies and special cases are you thinking of (give me some worst offenders in your view)? I'm curious because Python has always seemed to me a quite carefully designed language that's had a lot of thought put into it. And they're not afraid to make breaking changes to eliminate bad choices from the past (see Python 2/3).

VikingofRock posted:

I've always thought it was really confusing how python orders nested for's in a list comprehension. This:

Python code:
[x for x in row for row in matrix]
seems much more natural to me. (I get that it's supposed to be ordered like how you would nest the for loops, but still)

I agree, but I've learned to accept the fact that those of us for which this makes more sense are in a minority (sadly).

Linear Zoetrope
Nov 28, 2011

A hero must cook
I remember that I looked at one of the popular online Intro to Programming* courses (Coursera's maybe), and chuckled when one of their first examples was riddled with completely unexplained implicit type coercions. "2. + x / 3." where x was set to an integer or something like that. It was something that I understood instantly, but if you're new to the language and don't notice those little periods you're going to get some weird, frustrating outputs. Admittedly, this is probably the fault of the course more than Python's, but I'm not a huge fan of implicit type coercions in general. If you're going to do that, I think Julia's method where you have to explicitly request integer division is better so all numeric types are treated equally. So 3/2 = 3.0 / 2.0 = 1.5.

I like it because if you're an experienced programmer it's perhaps a bit unusual, but easy to pick up, and if you're just a person who wants to run some calculations and doesn't have a big understanding of why computers have strange idiosyncratic numeric types it's completely intuitive.

* It's possible it was actually the machine learning course, since I think that one didn't require background in Python and was going to teach it to you as you went. Either way, it was "beginner to Python" in some way.

Linear Zoetrope fucked around with this message at 11:59 on Jan 20, 2016

Hammerite
Mar 9, 2007

And you don't remember what I said here, either, but it was pompous and stupid.
Jade Ear Joe

Jsor posted:

I remember that I looked at one of the popular online Intro to Programming* courses (Coursera's maybe), and chuckled when one of their first examples was riddled with completely unexplained implicit type coercions. "2. + x / 3." where x was set to an integer or something like that. It was something that I understood instantly, but if you're new to the language and don't notice those little periods you're going to get some weird, frustrating outputs. Admittedly, this is probably the fault of the course more than Python's, but I'm not a huge fan of implicit type coercions in general. If you're going to do that, I think Julia's method where you have to explicitly request integer division is better so all numeric types are treated equally. So 3/2 = 3.0 / 2.0 = 1.5.

Fixed in Python 3, which is what I am generally referring to when I speak of "Python" without further specifying (and so should everyone else be, it was released in 2008 for crying out loud). I will defend the Internet honour of Python 3, I will not defend Python 2

Hammerite
Mar 9, 2007

And you don't remember what I said here, either, but it was pompous and stupid.
Jade Ear Joe
To contribute properly to the thread, our company is working on a project that involves units to be deployed remotely that have a GPS receiver in them. The purpose of this is to keep track of where they are. The units have to be programmed in Lua (because that's what's installed on them or something, I don't know). It turns out that Lua supports only one numeric type: you can have single or double-precision floating point, but not both. The people deploying these units configured the Lua to have single-precision floating point numbers. This is not precise enough to keep track of where something is in the world to the nearest metre. Someone at our company ended up having to write Lua code to make ersatz double-precision numbers from the single-precision ones available.

feedmegin
Jul 30, 2008

Hammerite posted:

Fixed in Python 3, which is what I am generally referring to when I speak of "Python" without further specifying (and so should everyone else be, it was released in 2008 for crying out loud). I will defend the Internet honour of Python 3, I will not defend Python 2

Should, maybe, but isn't. There's still an absolute ton of Python 2 out there, so yeah you do kind of need to specify.

LOOK I AM A TURTLE
May 22, 2003

"I'm actually a tortoise."
Grimey Drawer

comedyblissoption posted:

code:
//functional langs (e.g. haskell) have idioms supporting composition of functions:
result = reduce multiply 1 . filter predicate . map square $ list

In Haskell in this particular case you could also use do-notation:
code:
result = reduce multiply 1 $ do
    x <- list
    guard (predicate x)
    return (square x)
Aesthetically that's not necessarily an improvement over the compositional approach, but I tend to think of do-notation as a more general and less limited list comprehension syntax.

Of course, Haskell also has list comprehensions, but they're not used much from what I've seen.

Subjunctive posted:

I'm not sure what my favourite part of that is. The wafting Go aroma of interface {}, or that he decided to name the map operation "apply".

It blows my mind how many different names people can come up with for these extremely basic list operations. Off the top of my head I can name: map/apply/transform/collect/select, filter/where, fold/reduce/aggregate/accumulate, car/head/first and cdr/tail, and that's from just a handful of languages.

FlapYoJacks
Feb 12, 2009
Strewn about the project I inherited are C files, in these C files are bullshit like this:

C code:
/*
 * Enables and starts the Blue Alert daemon.
 */

#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>

int main(int argc, char *argv[]) {
	/* Release cwd */
	chdir("/");

	/* Close fds and sockets */
	int fd;
	for(fd=0; fd<sysconf(_SC_OPEN_MAX); fd++) close(fd);

	/* Become process group leader */
	setsid();

	setuid(0);

	system("/sbin/chkconfig PROGRAM on >/dev/null 2>&1");
	system("/etc/init.d/PROGRAM start >/dev/null 2>&1");
}				
what in the gently caress? WHAT IN THE GOD drat gently caress?

Edit* I copy and pasted the whole c file.

FlapYoJacks fucked around with this message at 14:44 on Jan 20, 2016

Malcolm XML
Aug 8, 2009

I always knew it would end like this.

LOOK I AM A TURTLE posted:

In Haskell in this particular case you could also use do-notation:
code:

result = reduce multiply 1 $ do
    x <- list
    guard (predicate x)
    return (square x)

Aesthetically that's not necessarily an improvement over the compositional approach, but I tend to think of do-notation as a more general and less limited list comprehension syntax.

Of course, Haskell also has list comprehensions, but they're not used much from what I've seen.


It blows my mind how many different names people can come up with for these extremely basic list operations. Off the top of my head I can name: map/apply/transform/collect/select, filter/where, fold/reduce/aggregate/accumulate, car/head/first and cdr/tail, and that's from just a handful of languages.

Haskell also has monad comprehensions


They are equivalent

csammis
Aug 26, 2003

Mental Institution

ratbert90 posted:

Strewn about the project I inherited are C files, in these C files are bullshit like this:

what in the gently caress? WHAT IN THE GOD drat gently caress?

Edit* I copy and pasted the whole c file.

Are they meant to be exec()'d from another process? That would explain closing all the file descriptors since the new image inherits open file descriptors from the exec()ing process.

FlapYoJacks
Feb 12, 2009

csammis posted:

Are they meant to be exec()'d from another process? That would explain closing all the file descriptors since the new image inherits open file descriptors from the exec()ing process.

I'm not worried about the closing of the fd's. Why does this program exist? Why didn't they just call the two whole things from the main program? Why are they not checking return codes? Why does this thing EXIST?

Plorkyeran
Mar 22, 2007

To Escape The Shackles Of The Old Forums, We Must Reject The Tribal Negativity He Endorsed

Subjunctive posted:

Do you think they run Lua in their CDN asset serving code path? They might, CDN systems usually have CPU to spare.
A few years ago their load balancer/cdn/firewall/etc. was basically just nginx+luajit, but that may have changed by now.

Athas
Aug 6, 2007

fuck that joker

While I agree with you that people spend too much time coming up with stupid new "friendlier" names, folds and reduces are not the same thing. A (left-)fold is of type (a -> b -> a) -> a -> [b] -> a, where a reduction is of type (a -> a -> a) -> a -> [a] -> a. This is pretty important if you actually want them to be parallel (folds aren't).

csammis
Aug 26, 2003

Mental Institution

ratbert90 posted:

I'm not worried about the closing of the fd's. Why does this program exist? Why didn't they just call the two whole things from the main program? Why are they not checking return codes? Why does this thing EXIST?

Yeah, my guess is that there was a need to launch a couple of things from a program but they had to run as root so a little fork()/exec() setup was created with a bunch of tiny programs that do nothing but clean up from having been exec'd and then run their commands. As for why they're not checking return codes, lovely developers do lovely things, who knows?

HappyHippo
Nov 19, 2003
Do you have an Air Miles Card?

Subjunctive posted:

It is both of those things, but that doesn't make it clearer. In fact, "more powerful" usually means "more opaque" when it comes to syntax.

Internet Janitor posted:

I've read several of Rob Pike's papers and watched some of his talks about the design of Go, and I think he has a very different definition of "simple" than I do. It seems Guido is in a similar camp to Rob.

For loops are very flexible and can be used to produce solutions to many problems. That's one kind of simplicity. map, reduce, filter, scan and friends each have a very specific purpose, and expose fewer "moving parts"- no loose variable definitions, no opportunities for off-by-one errors. I find that a more satisfying kind of simplicity. By having a more specific use case in mind, they convey more meaning to both a reader and potentially a compiler.

A good general rule I've found to make my code clearer is to always use the least powerful construct that will do the job. In many places people will do this by convention but it's good to have the general principle. Never use a while loop when you could use a for loop; never use a case statement where a simple if would suffice; never use goto when there's anything else available. In this case for example the list comprehension is more powerful than the filter, so I would use a filter. By choosing the less powerful construct you limit the mental burden on the person reading you code because you've limited what the code itself could do. One of the things I like about functional languages (or those that have borrowed their ideas) is that they tend to have finer grained constructs in this regard. map, reduce, filter, scan, fold etc all do things you could do with a for loop in an imperative language yet they communicate so much more.

Also I couldn't agree more about Rob Pike. Every time I read something by that guy I find myself disagreeing with it, his philosophy is like the exact opposite of mine.

Steve French
Sep 8, 2003

In what way is for less powerful than while?

fritz
Jul 26, 2003

Steve French posted:

In what way is for less powerful than while?

You can't always modify the loop counter in a for.

Munkeymon
Aug 14, 2003

Motherfucker's got an
armor-piercing crowbar! Rigoddamndicu𝜆ous.




The comprehension is clearer to me because I don't immediately remember which argument to filter is supposed to be the sequence (and like someone else said, have internalized sequence syntax) and meaningless and/or single-character variable names are depressingly common in the wild :shrug:

vOv posted:

Didn't Python's built-in HTTP library not actually verify HTTPS certificates by default for a long time, or am I thinking of something else?

IIRC the manual also said it's only meant for local testing.

Lonely Wolf
Jan 20, 2003

Will hawk false idols for heaps and heaps of dough.
If you try to write a program in a language like it's Java, you're an idiot.

If you try to write a program in a language like it's Haskell, everyone responsible for that language is an idiot.

(I like functional programming. (Not everything has to be functional programming.))

Internet Janitor
May 17, 2008

"That isn't the appropriate trash receptacle."

Hammerite posted:

Arguably it's intended to fulfil that jack of all trades role. But I don't really like the implication that we should want to program in a "more dangerous" language because it's less "mediocre" by somebody's idiosyncratic idea of what is and isn't mediocre.

I think you misunderstood what I was saying. I'm not at all suggesting that people use more dangerous languages because it is exciting. My point is that Python is not as bad as some really terrible options out there (from the perspective of general runtime safety it is better in some ways than C, for example), but you could do much better along that axis- even Java permits catching more issues at compile time and allows programmers to express and enforce better contracts throughout large applications.

quote:

What inconsistencies and special cases are you thinking of (give me some worst offenders in your view)? I'm curious because Python has always seemed to me a quite carefully designed language that's had a lot of thought put into it. And they're not afraid to make breaking changes to eliminate bad choices from the past (see Python 2/3).

If I list specific cases they're going to get picked to death and some will seem rather petty, but here are a few which come to mind:

- Double inequalities. Python special-cases expressions of a form like x < y <= z as described here. This has some unintuitive consequences for operator precedence, and while it is a syntax which is often valid in a math class it doesn't generalize and in my experience it gives students a totally wrong initial understanding of how logical expressions work.

- I'm not fond of Python's scoping rules, and I think they interact poorly with the decision to make variable declaration implicit. A classic example:
code:
a = [1, 2, 3]

def foo():
    print a 

def bar():
    a.append(5)
    print a

def quux():
    a += 9
    print a

foo()
bar()
quux()
code:
[1, 2, 3]
[1, 2, 3, 5]
Traceback (most recent call last):
  Line 17, in <module>
    quux()
  Line 12, in quux
    a += 9
UnboundLocalError: local variable 'a' referenced before assignment
- As has been discussed already, list comprehensions. For simple cases it is a terse way to express a wide variety of list operations, but they generalize poorly to more complex cases. In effect they overload keywords with a new set of syntax rules and semantics. Again, this can lead to a great deal of confusion. Given the degree to which Python is publicized as being a language which is "intuitive to a layman/beginner" (a dubious statement about any language, granted), list comprehensions are one of the places the language strays furthest from that ideal.

- Mutable default values. Not strictly inconsistent, but surprising and unhelpful for common use cases.

Thermopyle
Jul 1, 2003

...the stupid are cocksure while the intelligent are full of doubt. —Bertrand Russell

Every time anyone posts stuff like that about any language I find myself going "oh yeah that's terrible, what a dumb language".

Then later I find myself using said language without it ever bothering me.

For example, I avoided JS for years because every discussion about it ever highlights all kinds of bullshit. Then I started using it and...it just doesn't bother me.

I'm not claiming that odd/wrong/stupid stuff in a language can't be bad for programmer sanity, because I don't believe that. However, I wonder if talking about an issue just makes it seem worse than it actually is.

Also there's the issue where different things wax and wane in importance depending upon the environment you're working in...

xzzy
Mar 5, 2009

Pretty much. List comprehensions look like line noise to me, so I just never use them. :iiam:

Thermopyle
Jul 1, 2003

...the stupid are cocksure while the intelligent are full of doubt. —Bertrand Russell

xzzy posted:

Pretty much. List comprehensions look like line noise to me, so I just never use them. :iiam:

Oh yeah, I meant to say that I find most list comprehensions in the wild to express intent better than most usages of filter in the wild.

HappyHippo
Nov 19, 2003
Do you have an Air Miles Card?

Steve French posted:

In what way is for less powerful than while?

In addition to what fritz said, I was referring to a "typical for loop" where you just loop from one value to another. Doing weird poo poo is normally obvious, although not always. I'm not a fan of the c style for loop party for this reason. For example you could modify the iteration variable in the loop, which is why you should use foreach in place of for where possible (in languages that have it), again because it's less powerful.

HappyHippo fucked around with this message at 17:47 on Jan 20, 2016

Internet Janitor
May 17, 2008

"That isn't the appropriate trash receptacle."
If you're mostly writing new programs you can use a sane subset of a language and avoid its warts. If you want to read or modify existing programs, though, there's a good chance you'll have to deal with warts. In practical projects it comes down to the amount of discipline in your team and how well you agree with one another over how the language should be used.

Space Kablooey
May 6, 2009


HappyHippo posted:

In addition to what fritz said, I was referring to a "typical for loop" where you just loop from one value to another. Doing weird poo poo is normally obvious.
Of course you could modify the for loop variable in the loop, which is why you should use foreach in place of for where possible (in languages that have it), again because it's less powerful.

What's your criteria for a language construct to be more or less powerful than another? I'm asking because I personally consider foreach loop to be more powerful than a simple for loop. And to be more confusing, I agree with you that foreach should be used where possible instead of a simple for loop.

Plorkyeran
Mar 22, 2007

To Escape The Shackles Of The Old Forums, We Must Reject The Tribal Negativity He Endorsed
For can be used for everything foreach can, but not vice versa. Therefore for is more powerful.

brap
Aug 23, 2004

Grimey Drawer
List comprehensions are at best equivalent to a map(filter(li, f), g) and it's hilarious that guido thinks a language level construct is needed. Guido is a very arbitrary person who much like Pike should not be in charge of a language. See also "x if cond else y".

Python is a stillborn language. There's enough of the community that will literally never stop using Python 2. All the courses I've been taking at university that use Python don't even mention what version to use but will depend on Python 2-only packages and what have you.

Breaking packages was very stupid. It put the community in the position of "I won't migrate until the libraries I depend on are migrated to Python 3" and the library devs in the position of "I won't migrate until people are actually using Python 3."

I have never heard of a new language version making it impossible to use libraries built with the previous version of the language except Python.

That said, the best teaching language is still Beginning Student Language from How to Design Programs.

edit: I guess some of the illegible list flattening stuff won't work with map. You need flatMap or SelectMany or something.

brap fucked around with this message at 18:13 on Jan 20, 2016

xzzy
Mar 5, 2009

At least people are using Python 3. Or starting to. Unlike Perl 6. :v:

Subjunctive
Sep 12, 2006

✨sparkle and shine✨

Plorkyeran posted:

For can be used for everything foreach can, but not vice versa. Therefore for is more powerful.

Yeah, often people say "powerful" to mean "does more stuff for me", but in the context of languages I think a better definition is "can be used to do more things".

I also like filter/map over comprehensions because you can extend the set of operations consistently with your own functions, whereas with list comprehensions you end up mixing comprehensions with functions, giving you the worst (IMO) of both worlds.

fleshweasel posted:

I have never heard of a new language version making it impossible to use libraries built with the previous version of the language except Python.

I think Perl5/Perl4 had that problem, and it's certainly common enough with frameworks which have other libraries around them (angular, react, etc.). Also, Swift breaks poo poo all the time.

Space Kablooey
May 6, 2009


Plorkyeran posted:

For can be used for everything foreach can, but not vice versa. Therefore for is more powerful.


Subjunctive posted:

Yeah, often people say "powerful" to mean "does more stuff for me", but in the context of languages I think a better definition is "can be used to do more things".

Thanks, that makes sense. :)

Thermopyle
Jul 1, 2003

...the stupid are cocksure while the intelligent are full of doubt. —Bertrand Russell

fleshweasel posted:

Breaking packages was very stupid. It put the community in the position of "I won't migrate until the libraries I depend on are migrated to Python 3" and the library devs in the position of "I won't migrate until people are actually using Python 3."

Ehh, I avoided Python 3 for several years because I always ran into packages that didn't work on it yet. Now I almost always use it because I very rarely run into that problem. Of course, that's going to be dependent upon what kind of work you do.

I mean, yes, its a big clusterfuck, but the situation is way better now and you can tell its getting better.

Subjunctive
Sep 12, 2006

✨sparkle and shine✨

Thermopyle posted:

Ehh, I avoided Python 3 for several years because I always ran into packages that didn't work on it yet. Now I almost always use it because I very rarely run into that problem. Of course, that's going to be dependent upon what kind of work you do.

OS X still ships with 2.7, alas.

qntm
Jun 17, 2009

Plorkyeran posted:

For can be used for everything foreach can, but not vice versa. Therefore for is more powerful.

Here we also see that just because something is more powerful doesn't mean it's better. forEach should almost always be used over for(;;).

xzzy
Mar 5, 2009

Python: at least it's not perl.

Adbot
ADBOT LOVES YOU

Subjunctive
Sep 12, 2006

✨sparkle and shine✨

qntm posted:

Here we also see that just because something is more powerful doesn't mean it's better. forEach should almost always be used over for(;;).

Yes, indeed I think you should always use the least powerful construct out of your choices. (Similarly, give your programs the least privilege you can.)

  • 1
  • 2
  • 3
  • 4
  • 5
  • Post
  • Reply