No. The point of pseudo-code is that it doesn't have to compile. I can quickly gloss over irrelevant details. In contrast, even languages that look like pseudocode at the first glance can have very non-intuitive details that would just detract from the algorithm. Let's take for example Quicksort in Haskell:
qs :: Ord a => [a] -> [a]
qs [] = []
qs (pivot:xs) = (qs smaller) ++ pivot:(qs larger)
where smaller = [x | x <- xs, x <= pivot]
larger = [x | x <- xs, x > pivot]
or the same in Python:
def qs(array):
if not array:
return []
pivot = array[0]
xs = array[1:]
smaller = [x for x in xs if x <= pivot]
larger = [x for x in xs if x > pivot]
return qs(smaller) + [pivot] + qs(larger)
The advantage in both cases is that this is executable code, and as such can be tested, typechecked, and toyed with by students. However, they both include syntactic details that are distracting. Students would usually be better served by pseudocode that illustrates the intention of the algorithm, not implementation details:
algorithm QUICKSORT(array)
return [] if array is empty
pivot ← array[0]
xs ← array[1, ...] -- the rest of the array without the pivot
smaller ← [x | x ∈ xs, x <= pivot] -- all smaller or equal elements
larger ← [x | x ∈ xs, x > pivot] -- all larger elements
return [QUICKSORT(smaller)..., pivot, QUICKSORT(larger)...]
Notable differences:
I can just make up a list comprehension syntax that looks like maths rather than having to explain why Python has a for
and if
here.
I don't have to explain that language's syntax for list concatenation. Why does Python use +
addition? What is :
in Haskell? I can just choose a syntax that gets the point across more clearly.
the type signature Ord a => [a] -> [a]
is just an implementation detail. While possibly helpful in this case, the type signatures sometimes required by Haskell can get absurd.
I don't have to explain why Python considers empty collections to be false, and what array[1:]
is supposed to mean.
I avoid clever students pointing out that I should really use yield
in the Python example.
Haskell sucks for explaining mutable data structures like Hash Tables, RB trees, ….
Things start getting very language-specific once we need complex records to express our algorithms. E.g. Python's object system has a few surprises that are just distracting.
That said, it can be very valuable to use one of these languages in addition to pseudocode, just carefully label what is what.
In the development server docs, they state there are issues with calling run() and automatically reloading code:
This works well for the common case but it does not work well for development which is why from Flask 0.11 onwards the flask method is recommended. The reason for this is that due to how the reload mechanism works there are some bizarre side-effects (like executing certain code twice, sometimes crashing without message or dying when a syntax or import error happens).
They claim the CLI doesn't suffer from this problem.
The first commit that seems to touch on this issue is this: https://github.com/pallets/flask/commit/3bdb90f06b9d3167320180d4a5055dcd949bf72f
And there Armin Ronacher wrote:
It is not recommended to use this function for development with
automatic reloading as this is badly supported. Instead you should be
using the flask
command line script's runserver
support.
As mentioned by Aaron Hall, it seems like the use of run() could be problematic due to the fact that all objects which are instances of classes defined in the modules being replaced won't be reinstantiated, and whenever a module is reloaded, the modules it imports aren't reloaded as well.
The details about this may be found for Python 3 at:
https://docs.python.org/3/library/importlib.html?highlight=importlib#module-importlib
It states:
As with all other objects in Python the old objects are only reclaimed after their reference counts drop to zero.
Other references to the old objects (such as names external to the module) are not rebound to refer to the new objects and must be updated in each namespace where they occur if that is desired.
When a module is reloaded, its dictionary (containing the module’s global variables) is retained. Redefinitions of names will override the old definitions, so this is generally not a problem. If the new version of a module does not define a name that was defined by the old version, the old definition remains.
So, by creating a new process and killing the old one, you naturally eliminate all obsolete references.
Also, Flask's CLI uses the 'click' module, making it very easy to add custom commands, but most importantly, besides fixing the reloading bug, the CLI offers a standardised way to run applications and add custom commands. This sounds like a very good thing, because it makes familiarity with Flask more transferable between different teams and applications, rather than having multiple ways to do the same thing.
It seems like a genuine way to make Flask more in accordance to the Zen of Python:
There should be one-- and preferably only one --obvious way to do it.
Best Answer
Because the standard writers don't want to actually assert an implementation. They want to define what it does, but not necessarily how it does it. So, for example, if you look at the GNU C++ version of
find_if
, you will see that the implementation is slightly different from what you give, which is based on the C++ standard:This is functionally equivalent to what the standard has, but not exactly the same. This gives compiler writers flexibility. There may be a better way to do it for a particular platform. The implementor may wish to use a different coding style.
This is particularly true for scripting languages like python in that the implementor may decided to implement in a completely different language for performance reasons. Someone implementing python may, for instance, write
itertools.chain(*iterables)
in C++. This is perfectly fine if the standard says "equivalent to" as long as the code does the same as the provided python. If the standard said "is" instead, then implementors would be required to either implement in that language, or not meet the standard.In summary: