Why Are There So Many Pythons?
toptal.com
toptal.com
It's a great example of how Python isn't that different from LLVM and JVM!
I highly suggest people have a play with Hy, Pharen, and similar, as they really make you look at your language differently :)
> It’s fast because it compiles source code to native code
Actually, that's why it's slow. pypy is significantly slower than cpython in fact, primarily for short-life scripts.The initial start time can easily double or triple the run time in some cases.
To be fair, it's only a couple of seconds extra, but for many tiny scripts this amounts to a lot of wasted time. It's not a magical cure all in all situations.
...that said, its so fantastically easy to drop in, in most cases its worth trying to see how it performs just for fun~
pypy setup.py install
pypy app.py
[INFO ] Kivy v1.8.0-dev
[INFO ] [Logger ] Record log in /Users/d/.kivy/logs/kivy_14-01-15_2.txt
[INFO ] [Factory ] 156 symbols loaded
...
(drop in replacement for fun times? without having to change all your print and import statements? yes please~)So for a continuously running flask app, I think you could make a good case for it.
Pypy does have tooling to convert a limited subset of python ( they call it RPython) into an exe.
http://en.wikipedia.org/wiki/Partial_evaluation#Futamura_pro...
I'm a little rusty on the details, but IIUC the core of PyPy is an "abstract interpreter" for a restricted subset of Python known as RPython. Abstract interpretation is essentially a fold (in the functional programming sense) of the IR for a language, where you can parameterize the particular operation applied to each node. When the operation specified is "evaluate", you get partial evaluation, as described in the Wikipedia article.
The interesting part of PyPy happens when the RPython program to be evaluated is itself a Python interpreter, which it is. In this case, 'prog' is the Python interpreter written in RPython, and Istatic is your Python program. The first Futamura projection will give you a JIT; you specialize the RPython interpreter with your particular program, and it evaluates everything statically known at compile time (namely, your program) and produces an executable.
The second Futamura projection will give you a JIT compiler. Remember, since RPython is a subset of Python, an interpreter for Python written in RPython could be interpreted by itself. Moreover, it could be compiled by itself by the process described in the paragraph above. When you compile your JIT through the same process, you get a program that means the same thing (i.e. it will translate a Python program into an executable) but runs faster. The PyPy JIT that everybody's excited about for running Python scripts faster is this executable.
The third Futamura projection involves running PyPy on the toolchain that generated PyPy. Remember, this whole specializer machinery is all written in RPython, which can be interpreted by itself. So when your run the specializer machinery through itself, you get - an optimized toolset for building JIT compilers. That's what made programming language theorists excited about PyPy long before the Python community was. It's not just "faster Python", but it's a toolset for building a JIT out of anything you can build an interpreter for. Write an interpreter in RPython - for anything, Ruby, PHP, Arc, whatever - and run it through the PyPy toolchain, and it will give you a JIT compiler.
There are quite a few interpreters available for C.
Although Sun/Oracle's implementation is JIT based only, there are other Java vendors with toolchains that support ahead of time compilation to native code.
> Is Python interpreted or compiled? The question isn't really well-formed.
which is then repeated:
> C compiles to machine code, which is then run directly on your processor. Each instruction instructs your CPU to move stuff around.
No, "C" does not "compile" to machine code. The C compiler compiles C, and sometimes does so to machine code, and there are a C compilers that compile first to a form of bytecode or other symbolic representation, then to native. <language> is compiled/interpreted is a sad leftover from the heavily-diluted introductory computer books in the 1980s.
Hell, I would call Python's own 2to3 tool a compiler: it generates a full parse tree using a grammar, it runs some translation rules, and it generates Python 3 code.
All a compiler is is a combination of a translator and (possibly - but not necessarily) an optimiser.
I get that these are the reward for upgrading, but it seems unreasonable to hold back.
I don't like 3.x because A) I can't unpack tuples in lambda or function arguments and B) the new "encode"/"decode" scheme sucks. They have the right idea, but it's implemented poorly. I miss being able to do .encode('hex') or .decode('hex'), and I think the reasoning against this is weak. There are a lot of other little issues like this that remove a lot of the expressivity I'm used to from 2.7. Those are just the two that bother me the most.
The Python community will not like it, but if there is enough demand/contributors to make it so, surely they will not refuse patches?
Because 2.7 was born for this exact reason.
People use good enough 2.6 and need a bridge version between 2.6 and py3k. Many py3k features were backported to 2.7 as well.
Now you want bridge over bridge?
> future is the missing compatibility layer between Python 2 > and Python 3. It allows you to use a single, clean > Python 3.x-compatible codebase to support both Python 2 > and Python 3 with minimal overhead.
So in effect, you can run with some Python3 isms on Python2. All your Python is now 3 like and you can start migrating without losing the underlying infrastructure.
Does anyone else have trouble with that statement?
Maybe it should read "bytecode is more portable and is easier to secure." ?
Java is what, 20 years old and based on bytecode and despite Sun/Oracle's efforts still has security problems.
But yeah, your main point stands.
Sun/Oracle's implementation has security problems.
There are lots of Java VMs and compilers to choose from.
Although bytecode does simplify validation if you look at all the research work has been done in Assembly validation.
more (portable and secure)
rather than (more portable) and secureBut yes, bytecode isn't magic pixi dust that makes things secure; it can be a tool to make things more secure though, with effort.
x = random.choice([1, "foo"])
this is given as an example of why Python could never be strongly typed.Honest question: isn't this solved using Either in Haskell?
You can achieve something like this with type classes, though. This is somewhat similar to requiring all the elements to fullfill an interface, kind of like List<Comparable> in Java-like languages. With existential quantification (there are other options) you can make a list where every element in a list can be of a different type as long as they derive from the same type class (like Eq, Ord, etc). The type class is still a constraint that Python doesn't have but it makes static typing possible.
See the heterogenous collection link above.
#lang typed/racket
(: choose : (All (A) (Listof A) -> A))
(define (choose e)
(list-ref e (random (length e))))
(define x (choose (list 1 "foo")))
Unfortunately, people tend to assume that "type systems" and "the type system in Java/ML/Haskell" have the same level of expressiveness.The inferred languages just have this dude that watches your code and says, "yeah, I understand what is going on, your stuff is internally consistent"
For more on whether all programs have types, I wrote this: https://medium.com/p/8a3b4bedf68c
I agree with some of what you said in the medium link. Python does have a type system, structural and dynamic strong. The way the plus operator works was a mistake, Lua is superior in this regard.
Take a look at the type inferencing that Shedskin and RPython in PyPy can do. If there wasn't a type system, how are those 'static strong' programs created?
The programer and the program has a type system where the language may not.
As I say pretty explicitly in linked post, Python doesn't have a type system. Also, the term "strong" type system doesn't mean anything. Also^2, "structural" type systems are about how types are compared, and to whatever degree Python compares types, it isn't structurally.
RPython is a different programming language, which is statically type. Shedskin is similar.
RPython and Shedskin as not different languages, they are subsets. All programs in RPython and Shedskin are proper python programs with the same semantics.
Second, having a type system makes a language very different! Language subsets are different languages.
What you're saying is that Shedskin and Python have a non-empty intersection. But would the language of numbers with `+` be the "same language" as Python? It has the same relationship as Shedskin.
I made a mistake when I said quickcheck, I was thinking of the combination of Dialyzer and Typer in Erlang ( http://www.slideshare.net/konstantinvsorokin/kostis-sagonas-... )
I think I get what you are saying, that you have to take the totality of language in the current context.
And I would have to say yes, the language of numbers with "+" is in fact Python. I think it is also Haskell and lots of other languages. If I look at a corpus of language through a slit, I will always see a subset of that language. But it doesn't stop being that language by looking at with a microscope. What happens we see a code snippet like
a = 5 + b - 10
We don't know what language it is, but it doesn't matter. It is valid Ruby,Python,Lua,JavaScript, etc.Are we,me splitting hairs? I am just a layperson, I would like to fix any discrepancies in my knowledge.
Say what? What C interpreter might that be? In the end it is executed by machine code compiled from C programs designed so as to implement a Python virtual machine. Much, much different and much harder to make the intended connection.
Now why, really, is it easy to write C extensions for your Python code?
blog posts that helps me understand my tools/ecosystem better (rather than just harp on some recent happening in SV, for example) is awesome.
It's basically a script language.
Which is unfortunate, because now we dance through phrases like "things like Python and Ruby". There is a hard-to-precisely-define category here, and it's useful to have a name for it--even if the name is flawed.
And, in my opinion, it's usually better to hang on to an old name as it becomes less and less literally true than to continually fish about for a new name. ("Dynamic language" is popular now, but what happens when someone popularizes such a language with static typing?) As an analogy, consider "touchdown" in American football. You haven't had to touch the ball down to score in my lifetime, or even in my parents lifetimes, but we still call it a "touchdown" and not a "planebreaker".
If I can throw a thing over the wall to you that's runnable and doesn't contain textual source code then that's a compiled program.
I never know what exactly the speaker is referring to:
- the language definition, or some feature of it such as the type system?
- one or more (popular) language implementations?
- the intended use (e.g. short throwaway programs, desktop apps, kernel code) and target audience (e.g. experienced programmers, casual programmers, non-programmers)?
- the actual use and target audience?
- some opinion of the speaker about the language/implementation/etc. in question?
(Of course, this is just in my experience. YMMV)
----
tl,dr; in the body of my discussions, "scripting language" is a free variable and I can't find its definition! I wish people would pass it as a parameter!
discuss_scripting_language(listener="matt", opinion="they suck/rock!!!1one", definition="...")No, it means the language is interpreted instead of being compiled to native code AOT.
> ‘interpreted’ and ‘compiled’ are properties of an implementationSay we have a language X whose definition says nothing about interpretation or compilation. We also have two implementations of language X, one which is an interpreter, and one which is a compiler.
Is X an interpreted language, a compiled language, or something else?
Sorry for the misunderstanding, and thanks for the clarification.
Both. You can take in consideration a real example: Scheme is interpreted in all its implementations and compiled in a relevant number of them.
Languages and implementations are different things, but being interpreted, compiled, JIT-ed, translated, etc. is a property of the language implemented in the... implementation.
I don't think anyone who's ever programmed in Java would actually consider it a scripting language.
For me, when most people say "scripting language" they really mean a dynamic language.
Perl, Ruby, Python, JavaScript, Lisp... These are all considered "scripting" languages and the main thing they have in common is the dynamic linking and type systems.
Statically typed languages like Java are generally not used for scripting purposes.
That answers your question, really.
@a = (1, 2, 3); print "@a\n";
$a = [1, 2, 3]; print "@$a\n";
which have no expressive value (if lists and hashes had been first-class values there'd be no reason for references to exist as a type) but only cause subtle mistakes.You're ignoring context, which is a fundamental design decision in Perl. That's like criticizing C for having pointers while ignoring the design decision to expose memory as a flat space.
#!/usr/bin/perl
use strict;
++$a{$x};
and when run, produces, Global symbol "%a" requires explicit package name at ./test3.pl line 4.
Global symbol "$x" requires explicit package name at ./test3.pl line 4.
So, I'm not sure if I see that point. Are you not a fan of autovivification? Because it: rules. I think the only thing one has to understand is the use of exists(), to see if there is, say, a key in a hash, rather than defined(): #!/usr/bin/perl
use strict;
my %foo = (batz => undef);
for (qw(bar batz)){
if(exists($foo{$_})){
print "$_ exists!\n";
if(defined($foo{$_})){
print "and $_ is defined.\n";
}
else {
print "and $_ is undefined.\n";
}
}
else {
print "$_ doesn't actually exist\n";
}
}
prints, bar doesn't actually exist
batz exists!
and batz is undefined. use 5.016;
use warnings;
use Hash::Util 'lock_keys';
my %a = (B => 100); # B but no A defined
lock_keys %a;
my $x = 'A';
++$a{$x};
Above now throws an error on the last line - Attempt to access disallowed key 'A' in a restricted hash...Alternatively autovivification can be switched off - https://metacpan.org/pod/autovivification
OTOH Perl people tend to like the way we can, for example, create histograms (and nested structures like graphs) a bit more fluently with autovivifying hashes, e.g.:
my %a;
for my $x (@x) { $a{$x}++ }
than if we always had to be saying if (exists $a{$x}) {
$a{$x}++
}
else {
$a{$x} = 0
}
Or as Perlistas would be more prone to write (if forced to use a non-vivifying hash): exists $a{$x} ? $a{$x}++ : { $a{$x} = 0 }
Or gosh, who knows: $a{$x} = exists $a{$x} ? $a{$x}+1 : 0
Or to have sat around and waited for 10 years or so until Hash::Util was invented (after Perl 4's initial release), provided then you knew to look for it, and how), at which point you'd finally be able to say: use Hash::Util 'unlock_keys';
But as it happens, when Perl 4 first came out, autovivification (and its cohort, promiscuous ducktyping) were chosen as the default behavior for many of the language's core constructs (not just hashes and arrays). It's just the way Perl rolls. Whether it's the "right" tradeoff to make or not, from a socio-engineering perspective, is an interesting question (and partially a matter of taste). But in general Perl has been pretty consistent in its approach to tradeoffs like these.The solution to this is to use the autodie pragma (https://metacpan.org/pod/autodie) which has been part of the Perl core since 5.10.1 (released in Aug 2009):
use 5.016;
use warnings;
use autodie;
open my $fh, '<', "somefile"; # this file doesn't exist
So above will now produce a runtime error - Can't open 'somefile' for reading: 'No such file or directory' at...And autodie is lexically scoped so it won't break any library code.